简体   繁体   English

使用 AVPlayer 进行流式传输很慢

[英]Using AVPlayer for streaming is slow

I use AVPlayer for streaming mp3 file from the internet and it works really slow.我使用 AVPlayer 从互联网流式传输 mp3 文件,它的工作速度非常慢。 Using profiler I found out, that it downloads entire file at first, and then starts playing.使用分析器我发现,它首先下载整个文件,然后开始播放。 Is there any workaround for this?有什么解决方法吗?

Right now, I'm using this code现在,我正在使用此代码

if let player = player {
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem)

    let item = AVPlayerItem(url: url)

    player.replaceCurrentItem(with: item)
} else {
    player = AVPlayer(url: url)
}
player?.play()

Things I've tried:我尝试过的事情:

  • move player?.play() to an observer, attached to status property of the item将 player?.play() 移动到观察者,附加到项目的状态属性
  • play around with properties preferredForwardBufferDuration and preferredPeakBitRate使用属性preferredForwardBufferDurationpreferredPeakBitRate

All the time the result is downloading a whole audio file and only then start of playing.结果一直是下载整个音频文件,然后才开始播放。

Please note, the issue is - player starts to play ONLY after the whole file was downloaded, while I want it to stream mp3.请注意,问题是 - 播放器仅在整个文件下载后才开始播放,而我希望它流式传输 mp3。

要立即播放,您可以尝试设置

player.automaticallyWaitsToMinimizeStalling = false

You can add an observer to when the AVPlayer gets empty buffer:当 AVPlayer 获得空缓冲区时,您可以添加一个观察者:

[[self.tracksPlayer currentItem] addObserver:self 
                              forKeyPath:@"playbackBufferEmpty" 
                                 options:NSKeyValueObservingOptionNew
                                 context:nil];

And an observer so you can know when the AVPlayer buffered enough to keep up:还有一个观察者,这样你就可以知道 AVPlayer 何时缓冲到足以跟上:

[[self.tracksPlayer currentItem] addObserver:self 
                              forKeyPath:@"playbackLikelyToKeepUp" 
                                 options:NSKeyValueObservingOptionNew 
                                 context:nil];

Then just check for that in your KVO callback:然后只需在您的 KVO 回调中检查:

- (void)observeValueForKeyPath:(NSString *)keyPath 
                  ofObject:(id)object 
                    change:(NSDictionary *)change 
                   context:(void *)context {

if (object == [self.tracksPlayer currentItem] && 
  [keyPath isEqualToString:@"playbackBufferEmpty"]) {

  if ([self.tracksPlayer currentItem].playbackBufferEmpty) {

      NSLog(@"Buffer Empty"); 
  }
} else if (object == [self.tracksPlayer currentItem] && 
         [keyPath isEqualToString:@"playbackLikelyToKeepUp"]) {


  if ([self.tracksPlayer currentItem].playbackLikelyToKeepUp) {

      NSLog(@"LikelyToKeepUp");
  }
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM