如何在 iOS 中使用 MpMoviePlayerController 在 UISlider 上显示缓冲数据?

Posted

技术标签:

【中文标题】如何在 iOS 中使用 MpMoviePlayerController 在 UISlider 上显示缓冲数据?【英文标题】:How to show buffered data on UISlider using MpMoviePlayerController in iOS? 【发布时间】:2014-12-17 09:53:34 【问题描述】:

我正在使用MPMoviePlayerController 播放音频,我想像这样在滑块上显示缓冲数据...

我想在滑块中显示缓冲区数据,如红色部分。我试过用谷歌搜索它。但我没有得到任何解决方案。 以及如何使滑块自定义? 提前谢谢...

【问题讨论】:

你确定吗?....没有办法获取缓冲区数据。 @安迪 AVPlayer 有一种方法,但我怀疑 MPMoviePlayerController 是否支持 是的,对我来说没问题。如果你会使用 AVPlayer @Andy 给出答案 【参考方案1】:

是的,我们可以通过 playableDuration 使用 MPMoviePlayerController 显示流数据。我正在解释为我的 customize player 制作这个 custom_slider 所涉及的所有这些步骤...

(如果只对编程部分感兴趣,可以直接阅读第四步) 这些是步骤:

第 1 步(第一个设计部分)我使用标准控件完成...

在 Interface Builder 中,将 UISlider 立即放在 UIProgressView 的顶部,并使它们的大小相同。

在 UISlider 上,背景水平线称为轨道,诀窍是使其不可见。我们使用透明 PNG 和 UISlider 方法 setMinimumTrackImage:forState: 和 setMaximumTrackImage:forState: 来做到这一点。

在视图控制器的 viewDidLoad 方法中添加:

[ProgressSlider setMinimumTrackImage:minImage forState:UIControlStateNormal];

[ProgressSlider setMaximumTrackImage:transparentImage forState:UIControlStateNormal];
[progressBar setTrackImage:maxImage];
[progressBar setProgressImage:streamImage];

ProgressSlider 指的是您的 UISlider,progressBar 指的是您的 UIProgressView。

您可以像这样以编程方式制作透明图像。

 UIGraphicsBeginImageContextWithOptions((CGSize)512,5, NO, 0.0f);
    UIImage *transparentImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();

您可以根据进度视图轨道图像高度宽度更改它的大小...我使用 512,5 您可以使用 1,1 作为默认滑块和进度视图。

参考来自这个答案https://***.com/a/4570100/3933302

第 2 步:

现在我尝试设置 UIProgressView 的轨迹和进度图像。但它没有显示轨迹和进度图像。然后我找到了这个解决方案......使用github中提供的这个库。 https://gist.github.com/JohnEstropia/9482567

现在我将 UIProgressView 的出现更改为 JEProgressView,包括 NIB 和情节提要中的出现。

基本上,您需要强制将图像直接分配给 UIProgressView 的子 UIImageView。

需要子类覆盖layoutSubviews,根据图片大小调整imageViews的高度。

参考来自这个答案https://***.com/a/22322367/3933302

第 3 步

但现在的问题是,您将从哪个制作滑块和进度视图的图像。本教程对此进行了说明,您也可以下载 psd。

http://www.raywenderlich.com/32167/photoshop-tutorial-for-developers-creating-a-custom-uislider

第 4 步:

现在进入编程部分.. 通过使用可播放持续时间,可以显示流数据..(这是我最大的问题)

使用MPMovieLoadStatePlayable我们可以得到当缓冲区有足够的数据可以开始播放,但是在播放结束之前它可能会用完数据。

https://developer.apple.com/library/ios/documentation/MediaPlayer/Reference/MPMoviePlayerController_Class/index.html#//apple_ref/c/tdef/MPMovieLoadState

现在在您的 PlayAudio 方法中...放置此代码..

-(void) playAudio:(NSURL *) url 
.............
streamTimer= [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(loadStateChange) userInfo:nil repeats:YES];
..........

这里是loadStateChange的定义

-(void)loadStateChange

if(self.moviePlayer.loadState == MPMovieLoadStatePlayable)

    [self.moviePlayer play];

    slideTimer = [NSTimer scheduledTimerWithTimeInterval:0.5
                                                  target:self
                                                selector:@selector(updateProgressUI)
                                                userInfo:nil
                                                 repeats:YES];
    [streamTimer invalidate];

else if(self.downloadList)
//if you are playing local file then it will show track with full red color
    progressBar.progress= appDel.moviePlayerController.moviePlayer.duration;

这里是updateProgressUI的定义

- (void)updateProgressUI
    if(self.moviePlayer.duration == self.moviePlayer.playableDuration)
        // all done
        [slideTimer invalidate];
    
    progressBar.progress = self.moviePlayer.playableDuration/self.moviePlayer.duration ;


我希望这个完全自定义的滑块能帮助您制作自定义播放器...我逐步解释了我的所有工作......谢谢......

【讨论】:

【参考方案2】:

MPMoviePlayerController 无法做到这一点。

但是,如果您切换到AVPlayer,那么您可以使用AVPlayerItem.loadedTimeRanges。它包含您在自定义控件中进行可视化所需的所有信息。

关于该主题的问题有很多,例如:

AVPlayer streaming progress

【讨论】:

谢谢,但是我们也可以用 MPMoviePlayerController 来做到这一点......使用 playableDuration 属性......【参考方案3】:

根据MPMoviePlayerController(可用here)的文档,您可以使用playableDuration 属性来检索播放器已加载的持续时间。

然后您必须继承 UISlider 以在 drawRect: 方法中绘制控件的红色部分。

至于AVPlayer,您可以在代表您的内容的AVPlayerItem 上调用loadedTimeRanges(文档here)。这将为您提供一个数组(从 iOS 8 开始),一个 CMTimeRange 代表已缓冲的媒体部分。我建议在检索时间范围时使用[NSArray firstObject],以保护您的代码免受可能为空的数组的影响。

【讨论】:

以上是关于如何在 iOS 中使用 MpMoviePlayerController 在 UISlider 上显示缓冲数据?的主要内容,如果未能解决你的问题,请参考以下文章

IOS 6 - 自动旋转 MPMovieplayer

如何替换 MPMoviePlayer 通知?

如何使用 UISlider 在特定时间从 mpmovieplayer 听到声音?

MPMoviePlayer setCurrentPlaybackTime iOS

MPMoviePlayer默认控件按钮未对齐

向 MPMoviePlayer 添加 Airplay 支持