How to show buffered data on UISlider using MpMoviePlayerController in iOS?

后端 未结 3 1362
小蘑菇
小蘑菇 2021-01-31 06:24

I am using MPMoviePlayerController to play audio and I want to show the buffered data on slider like this ...

相关标签:
3条回答
  • 2021-01-31 06:53

    You cannot do this with MPMoviePlayerController.

    However if you switch to AVPlayer then you can use AVPlayerItem.loadedTimeRanges. It contains all information you need for visualization in your custom control.

    There are number of questions that have been asked on that topic, for example:

    AVPlayer streaming progress

    0 讨论(0)
  • 2021-01-31 06:59

    Yes We can Show stream data using MPMoviePlayerController by its playableDuration. I am explaining all these steps involved me to make this custom_slider for my customize player...

    (You Can direct read step 4 if you only interested in programming part) These are the steps:

    Step 1: (First Design part) i done it using standard Controls...

    In Interface Builder place your UISlider immediately on top of your UIProgressView and make them the same size.

    On a UISlider the background horizontal line is called the track, the trick is to make it invisible. We do this with a transparent PNG and the UISlider methods setMinimumTrackImage:forState: and setMaximumTrackImage:forState:.

    In the viewDidLoad method of your view controller add:

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

    where ProgressSlider refers to your UISlider and progressBar to your UIProgressView.

    and you can make transparent image programmatically like this.

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

    you can change the size of it according to your progress view track image height width... I use {512,5} you can use {1,1} for default slider and progress view.

    Reference taken form this answer https://stackoverflow.com/a/4570100/3933302

    Step 2:

    Now I tried to set the track and progress image of UIProgressView. But it was not showing the track and progress image. then i found this solution...to use this library available in github. https://gist.github.com/JohnEstropia/9482567

    Now I changed occurrences of UIProgressView to JEProgressView, including those in NIBs and storyboards.

    Basically, you'd need to force assigning the images directly to the UIProgressView's children UIImageViews.

    The subclass is needed to override layoutSubviews, where you adjust the heights of the imageViews according to the image sizes.

    Reference taken from this Answer https://stackoverflow.com/a/22322367/3933302

    Step 3:

    But now the question is from which will you make the image for slider and progressView. This is explained in this tutorial and You can download the psd also.

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

    Step 4:

    Now come to programming part.. by using the playable duration it is possible to show stream data..(which was my biggest problem)

    Using MPMovieLoadStatePlayable we can get when The buffer has enough data that playback can begin, but it may run out of data before playback finishes.

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

    Now in your PlayAudio method...place this code..

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

    and here is the definition of 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;
    }
    

    and here is the definition of updateProgressUI

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

    I hope this fully customize slider will help you lot in making custom player...I explained all my work in steps.....Thanks ....

    0 讨论(0)
  • 2021-01-31 07:02

    According the documentation of MPMoviePlayerController (available here) you can use the playableDuration property to retrieve the duration that has been loaded by the player.

    You would then have to subclass UISlider to draw the red part of your control in the drawRect: method.

    As for AVPlayer you would call loadedTimeRanges (documentation here) on the AVPlayerItem representing your content. That would give you an array of (as of iOS 8) a single CMTimeRange representing the part of your media that has been buffered. I would advise using [NSArray firstObject] when retrieving the time range to protect your code against a possibly empty array.

    0 讨论(0)
提交回复
热议问题