AVPlayer audio and video playback

What is AVPlayer

  • AVPlayer exists in the AVFoundation framework. It is a video player used to play video, but it can also be used to play music. There is no need to implement the interface when playing music. In other words, as long as you master video playback, audio playback will be mastered naturally.
  • AVPlayerItem: corresponds to media resources and manages the information and status of media resources. Its initialization requires a URL or AVAsset.
  • AVPlayer: player, which controls the playback and pause of resources. AVPlayerItem is its attribute. Its initialization requires URL or AVPlayerItem.
+ (instancetype)playerWithURL:(NSURL *)URL;
+ (instancetype)playerWithPlayerItem:(nullable AVPlayerItem *)item;
  • AVPlayerLayer: player layer, used to display video content. AVPlayer is its attribute, and its initialization requires AVPlayer. If you are playing audio, you do not need to create AVPlayerLayer.
+ (AVPlayerLayer *)playerLayerWithPlayer:(nullable AVPlayer *)player
  • Let's make an analogy between AVPlayerItem, AVPlayer and AVPlayerLayer:
    AVPlayerItem is a disc, AVPlayer is a dvd player, and AVPlayerLayer is a TV screen.

Realization of video playback function

1. Play video resources through network links

//URL encoding is required when the URL is in Chinese
NSURL *url = [NSURL URLWithString:[self.str stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:url];
AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
    
playerLayer.frame = CGRectMake(0, 50, self.view.frame.size.width, 200);
[self.view.layer addSublayer:playerLayer];

2. Common operations

  • Play and pause
[player play];
[player pause];
  • Replace playback resource
[player replaceCurrentItemWithPlayerItem:videoItem];

3. Monitor playback progress

  • Use addPeriodicTimeObserverForInterval:queue:usingBlock: to monitor the player's progress. It is often used to indicate the playback progress and obtain information such as playback duration.
    1) The Interval parameter indicates the callback Interval. block is executed every Interval.
    For example, Interval passes CMTimeMake(1,10). 1 indicates that there is currently 1 frame, 10 indicates that there are 10 frames per second, 1 / 10 = 0.1, that is, when the player is playing, it executes block every 0.1 seconds, including starting and pausing playback.
    2) Method returns an observer object to be removed when it is no longer played.
    Add observer
    self.timeObserve = [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 10) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
        float current = CMTimeGetSeconds(time);
        float total = CMTimeGetSeconds(weakSelf.player.currentItem.duration);
        weakSelf.playTime = [NSString stringWithFormat:@"%.f",current];
        weakSelf.playDuration = [NSString stringWithFormat:@"%.2f",total];
        if (weakSelf.slider.isTracking == NO) {
            weakSelf.slider.value = current / total;
        }
    }];

Remove observer

    if (self.timeObserve) {
        [self.player removeTimeObserver:self.timeObserve];
    }

4. Move the slider to play the video frame at the specified time

  • Use seekToTime: or seekToTime:completionHandler: or seekToTime:toleranceBefore:toleranceAfter:completionHandler: to play video content at a specified time.
    Accurate search for video frames at a certain time may lead to additional decoding delay. seekToTime: the default is not accurate search, but there is a small range of error.
    The search scope of seekToTime:toleranceBefore:toleranceAfter:completionHandler: is [time toleranceBefore, time + toleranceAfter]. When toleranceBefore and toleranceAfter are set to kCMTimePositiveInfinity, the execution effect is equivalent to seekToTime:completionHandler:
    [self.player seekToTime:goalTime toleranceBefore:kCMTimePositiveInfinity toleranceAfter:kCMTimePositiveInfinity completionHandler:^(BOOL finished) {
    }];

Problems encountered

  • When playing, there is no sound from the speaker. Only when the headset is plugged in can there be sound.
    The reason is that the app speaker follows the system sound mode by default, while the mobile phone has set the mute mode, so the speaker follows the mute mode and there is no sound.
    Solution: set Category so that the speaker does not follow the system sound mode.
    //Must be set, otherwise the speaker follows the system sound mode by default
    //The AVAudioSessionCategoryPlayAndRecord mode can play and record. In this mode, the default outlet of sound is the earpiece (there is sound only when wearing headphones). Switch to the speaker through the following methods
    AVAudioSession *session = [AVAudioSession sharedInstance];
    [session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
  • When the slider is moved repeatedly and quickly, the slider will jump.
    This is because seekToTime: will be called when moving the slider. This method is used to search and play the specified video frame. It takes a little time to execute. It will not search and play the specified video frame immediately. At this time, addPeriodicTimeObserverForInterval:queue:usingBlock: the callback will set the position of the slider. The finger has moved the slider to a certain position, Suddenly, for a moment, the slider returns to the previous position, and then immediately returns to the position where the finger stays.
    Solution: use seekToTime:toleranceBefore:toleranceAfter:completionHandler: instead of seekToTime:, there will be a callback of completionHandler when searching and playing the specified video frame. After obtaining the callback, set the position of the slider. See the project for details.

project

  • The following items are based on the actual application of AVPlayer, which can achieve the full play effect of audio playing, vertical and vertical screen video switching, and tiktok vertical screen.
    Project address: AVPlayerAudioVideo

1. Audio player effect:

2. Switching effect of vertical screen and horizontal screen:

3. the effect of full screen like tiktok vertical screen:

The full vertical screen is implemented with UICollectionView, and only three UICollectionViewCell view instances are created. No matter how many videos need to be played, the three UICollectionViewCell view instances are reused to effectively control the memory size and avoid excessive memory loading and full memory.
There is a difficulty in reusing UICollectionViewCell, which is to record the current played position of the video. At first, CMTime was used to save the video, but it was found that it was not possible, and then CMTimeValue and CMTimeScale were used to record the video respectively. Later, AVPlayerItem was used to save the played position.

Conclusion: if the articles and projects are helpful to you, please give a Star ⭐ Hello, your Star ⭐ It is the driving force that I continue to output, thank you 😁😘❤️

Tags: iOS

Posted on Mon, 20 Sep 2021 23:21:18 -0400 by kpowning