标签: avqueueplayer

使用AVQueuePlayer/AVPlayer进行无缝播放 - 是否可能?

我一直在玩AVPlayer它的子类AVQueuePlayer(以及一个MPMediaItems 数组)并发现后者在无间隙专辑中表现更好,但似乎都没有完全完成任务.

使用时,有当前和下一磁道之间的一个非常明显的暂停AVPlayerreplaceCurrentItemWithPlayerItem方法.但随着AVQueuePlayeradvanceToNextItem方法的间隙狭窄得多.

唯一的选择是这两个类,因为我正在处理AVPlayerItem包含iTunes音乐库中项目的资产URL的.这就引出了一个问题,是否可以通过iOS SDK实现无间隙播放?

ios avplayer avqueueplayer

7
推荐指数
1
解决办法
2138
查看次数

当AVQueuePlayer完成最后一个播放项目时如何做某事

我有一个AVQueuePlayer,我是从4个AVPlayerItems的数组创建的,它都可以正常播放.

我希望在队列中的最后一项完成播放时做一些事情,我在这里看了很多答案,这看起来最符合我想要的: 在声音结束后执行代码的最佳方法播放

在我的按钮处理程序中,我有这个代码:

static const NSString *ItemStatusContext;

    [thePlayerItemA addObserver:self forKeyPath:@"status" options:0 context:&ItemStatusContext];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(playerItemDidReachEnd)
                                                 name:AVPlayerItemDidPlayToEndTimeNotification
                                               object:thePlayerItemA];

     theQueuePlayer = [AVQueuePlayer playerWithPlayerItem:thePlayerItemA]; 

    [theQueuePlayer play];
Run Code Online (Sandbox Code Playgroud)

然后我有一个处理playerItemDidReachEnd的函数:

- (void)playerItemDidReachEnd:(NSNotification *)notification {
// Do stuff here
NSLog(@"IT REACHED THE END");
}
Run Code Online (Sandbox Code Playgroud)

但是当我运行它时,我得到一个内部不一致的例外:

    An -observeValueForKeyPath:ofObject:change:context: message was received but not handled.
Key path: status
Observed object: <AVPlayerItem: 0x735a130, asset = <AVURLAsset: 0x73559c0, URL = file://localhost/Users/mike/Library/Application%20Support/iPhone%20Simulator/5.0/Applications/A0DBEC13-2DA6-4887-B29D-B43A78E173B8/Phonics%2001.app/yes.mp3>>
Change: {
    kind = 1;
Run Code Online (Sandbox Code Playgroud)

}

我究竟做错了什么?

objective-c ios avqueueplayer

6
推荐指数
2
解决办法
6759
查看次数

带有Soundcloud流项的AVQueuePlayer(或AVPlayer)阻止UI(主线程)

感谢这两篇文章,我在创建AVPLayerItem AVQueuePlayer播放 期间解决了这个问题, 没有间隙,并且冻结AVPlayer在缓冲音频流的过程中"冻结"应用程序

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL URLWithString:urlString] options:@{AVURLAssetPreferPreciseDurationAndTimingKey : @(YES)}];
    NSArray *keys = @[@"playable", @"tracks",@"duration" ];

    [asset loadValuesAsynchronouslyForKeys:keys completionHandler:^()
     {

         for (NSString *thisKey in keys) {
             NSError *error = nil;
             AVKeyValueStatus keyStatus = [asset statusOfValueForKey:thisKey error:&error];
             if (keyStatus == AVKeyValueStatusFailed) {
                 return ;
             }
         }

         AVPlayerItem *item = [[AVPlayerItem alloc] initWithAsset:asset];

         dispatch_async(dispatch_get_main_queue(), ^ {

             [item addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];

             [player insertItem:item afterItem:nil];

         });

     }];
});
Run Code Online (Sandbox Code Playgroud)

但是,使用来自Soundcloud的流(https://api.soundcloud.com/tracks/146924238/stream?client_id=76395c48f97de903ff44861e230116bd),在项目状态准备好播放(AVPlayerStatusReadyToPlay)之后,AVQueueplayer继续在主线程中执行某些操作"冻结"UI(跟踪继续在后台线程中播放).

我注意到这个问题在网络较低时更为重要,然后我得出结论,当项目缓冲流时,此冻结存在.

有人有解决方案或诀窍吗?

objective-c freeze soundcloud avplayer avqueueplayer

6
推荐指数
0
解决办法
848
查看次数

当AVQueuePlayer从资产跳到另一个时,烦人的延迟

我有一个AVQueuePlayer应该按顺序播放一个AVURLAsset表示一个连续视频的连续片段的数组.

每当一个片段结束而另一个片段开始时,就会有一个很小的小故障(帧保持约0.2秒,声音被静音)

我试着研究如何解决这个问题,但没有找到任何东西.我尝试用2来解决它,AVQueuePlayer并在每个片段结束前0.2秒左右切换.问题没有解决.

关于如何解决这个问题的任何想法?

注意:使用mp4 joiner软件将mp4片段连接在一起时,输出是一个平滑的视频,没有任何故障.

mpmovieplayercontroller avfoundation ios avqueueplayer swift

6
推荐指数
1
解决办法
370
查看次数

MPNowPlayingInfoCenter停止更新进度条

我正在制作一个有音乐播放器的应用程序.我有一段时间没有参与其中,但是我最后一次工作时它nowPlayingInfo 正在工作.现在,当我将其更新为Swift 3时,除进度条外,一切正常.

我在这里看到了几个类似的问题,谈到了竞争条件,它被某些东西所覆盖,但我似乎无法弄清楚是什么.我正在使用AVQueuePlayerif如果有帮助.

跳过和上一个按钮工作,专辑封面,标题和艺术家完美更新,但经过的时间只是没有更新.当我调试时,MPNowPlayingInfoPropertyElapsedPlaybackTimefrom MPNowPlayingInfoCenter.default().nowPlayingInfo显示正确的数字,但控制中心的实际屏幕不是.通常,进度停留在0:01并且不会移动.但是,如果我在我的应用程序中寻求使用滑块并返回控制中心,它会显示我寻找的时间但仍然保持不变.

这是我的setNowPlaying代码:

func setNowPlaying(_ dura: Float, timePlayed: Float) {
    let s = songs[playbackInstance.currentSongIndex]
    let albumArt = MPMediaItemArtwork.init(boundsSize: CGSize(width: 480, height: 360), requestHandler: { (size) -> UIImage in
        return self.songImageView.image ?? #imageLiteral(resourceName: "WhiteMusic")
    })
    let songInfo: [String: Any]? = [
        MPMediaItemPropertyTitle: s.name,
        MPMediaItemPropertyArtist: s.artist,
        MPMediaItemPropertyArtwork: albumArt,
        MPMediaItemPropertyPlaybackDuration: dura,
        MPNowPlayingInfoPropertyElapsedPlaybackTime: CMTimeGetSeconds(player.currentTime())
    ]

    MPNowPlayingInfoCenter.default().nowPlayingInfo = songInfo
}
Run Code Online (Sandbox Code Playgroud)

我曾经设置过传递给方法MPNowPlayingInfoPropertyElapsedPlaybackTimetimePlayed变量,但由于它不起作用我player.currentTime()按照其他问题的建议尝试,这可能是比我正在使用的更好的衡量标准.

以下是寻求帮助的代码:

@IBAction func sliderChanged(_ sender: UISlider) …
Run Code Online (Sandbox Code Playgroud)

avqueueplayer mpnowplayinginfocenter swift swift3

6
推荐指数
1
解决办法
1198
查看次数

AVQueuePlayer过早开始下一个项目

我有一个AVQueuePlayer,在特定的情况下,它会在上一首曲目结束之前开始播放下一曲目.它不会同时播放它们,只是提前删除第一首曲目并开始下一首曲目.当两个轨道都是http流时,这肯定会发生,我在本地播放文件时没有尝试过.而且,每次跟踪都不会发生这种情况.只有特定的两个曲目放在一起时才会导致问题.大多数曲目都没有这个问题,但是很多都有.其他媒体播放器在送入这些曲目时不会出现这些症状.显示症状的曲目必须是AAC编码的,我在播放MP3版本时没有这样的问题.AAC文件使用libfaacVBR 90%进行编码.用于编码轨道的确切命令行:

ffmpeg -loglevel error -probesize 10000000 -i "$input" -strict -2 -acodec libfaac -q:a 90 -vn "$output.m4a"
Run Code Online (Sandbox Code Playgroud)

我相信这个问题是涉及AVQueuePlayer积极努力无间隙播放曲目,因为我知道有包含在AAC,让两条轨道在顺序播放无间隙(电子混音特别有用)一些元数据-这些文件不应该有这样的元数据但是,AVQueuePlayer当播放两首不相关的曲目时,它肯定不会引起恐慌吗?编辑:确定不是原因,见下文.

如果你想自己重现这个问题,只需要极少量的代码,只需要创建一个基本的项目,包含AVFoundation,然后执行如下操作:

self.queuePlayer = [AVQueuePlayer queuePlayerWithItems: @[[AVPlayerItem playerItemWithURL: [NSURL URLWithString: @"https://eqbeats.org/track/4875/aac"]], [AVPlayerItem playerItemWithURL: [NSURL URLWithString: @"https://eqbeats.org/track/4499/aac"]]]];
[self.queuePlayer play];
Run Code Online (Sandbox Code Playgroud)

让第一首曲目几乎完成(它将持续约100秒左右),你会听到它突然结束,第二首曲目将会出现.

我认为有一些解决方法,例如在下一首曲目开始时截取消息并检查上一首曲目的播放状态,或者只在前一次启动后将下一个项目添加到队列中...但我担心这些方法的可靠性,特别是当应用程序背景时.如果没有针对此客户端的修复,我可以调查是否有一种方法来剥离此元数据服务器端(假设这问题)或者只是让自己使用更大,更糟糕的MP3版本.

AVFoundation只是骚乱-我敢肯定,任何人谁是有恐怖与它的工作会同意的.我正在讨论是否将此作为Apple的一个错误提出来,但由于它在两个主要的iOS更新中幸存下来,我觉得这个东西只是照常生活AVQueuePlayer.从我对这个问题的研究来看,我显然不是唯一一个在这个框架上挣扎的人:

完全披露:我的应用程序实际上是用RubyMotion编写的,但是我已经能够用更少的代码重现Objective-C中的问题(所以很少有可能的失败点),所以我很确定RubyMotion或者我的使用AVFoundation不是罪魁祸首.

编辑:刚刚使用file://链接测试了本地文件,问题仍然存在,所以它绝对不是流媒体引擎或网络服务器的问题.

编辑2:我已经研究了MP4规范以及iTunes和AVFoundation如何确定MP4中的无间隙.在原来 …

iphone objective-c avfoundation ios avqueueplayer

5
推荐指数
1
解决办法
1179
查看次数

iOS:AVQueuePlayer/AVPlayerItem“AVPlayerItem 一次只能占据播放器队列中的一个位置。”

我不断收到此错误:

“AVPlayerItem 一次只能占据玩家队列中的一个位置。”

我对玩家的物品进行了 NSLog 记录,但似乎没有一个是相同的。此外,我添加这一点只是为了确定:

if([player canInsertItem:itemToAdd afterItem:nil])
 [player insertItem:itemToAdd afterItem:nil];
Run Code Online (Sandbox Code Playgroud)

当我不确定这是否可行(可以在不同的内存位置有两个相同的项目)时,我编写了一个类别方法来测试玩家是否包含一个项目或与其相同的东西。然而,我仍然收到错误。

我见过很多帖子,有人在使用 MPMoviePlayerController 时遇到此错误,但我没有使用该自定义类,只是使用开箱即用的 AVQueuePlayer。

有想法该怎么解决这个吗?

cocoa-touch objective-c ios avplayer avqueueplayer

5
推荐指数
1
解决办法
2365
查看次数

AVURLAsset loadValues异步永不失败

我正在阅读并尝试苹果关于加载视频资源的示例代码。

但我注意到,即使我打开设备上的飞行模式或关闭 Mac 上的 WiFi,该loadValuesAsynchronously功能也不会失败。AVURLAsset有谁知道什么情况下loadValuesAsynchronously会无法加载密钥?

这是相关示例代码

asset.loadValuesAsynchronously(forKeys: PlayerViewController.assetKeysRequiredToPlay) {

    /*
        The asset invokes its completion handler on an arbitrary queue.
        To avoid multiple threads using our internal state at the same time
        we'll elect to use the main thread at all times, let's dispatch
        our handler to the main queue.
    */
    DispatchQueue.main.async() {
        /*
            This method is called when the `AVAsset` for our URL has 
            completed the loading of the values of …
Run Code Online (Sandbox Code Playgroud)

ios avplayer avqueueplayer

5
推荐指数
1
解决办法
6192
查看次数

AVPlayerLooper打ic /视频循环错误

问题

我正在使用AVPlayerLooper无限期重播HTTP Live Streaming视频。该视频可在前三个循环中完美回放。但是在第四个循环以及此后的所有循环中,视频“打“”。换句话说,当视频接近其结束时间时,视频会闪烁,播放最后几帧大约一秒钟,然后再次闪烁并重新启动。这也导致通知AVPlayerItemDidPlayToEndTime被调用两次,并且playerLooper.loopCount每次调用都递增。

如何阻止我的视频打ic?

附加信息:

  • 我只有一些视频有此问题。其他人无缝地工作。
  • AVPlayerLooper旨在允许HTTP Live Streaming视频的无缝循环。它通过制作所提供模板的三个副本AVPlayerItemAVQueuePlayer按照称为“跑步机模式” 的方式(也提供)连续播放它们来工作。似乎在播放完每个项目副本之后,我们就遇到了上面的问题。

avfoundation video-streaming ios avqueueplayer

5
推荐指数
0
解决办法
386
查看次数

音频持续时间在AVQueuePlayer中返回nan

当我尝试.wav使用AVQueuePlayer从服务器播放文件时,它返回的持续时间为nan.

我用这段代码来获取持续时间

audioPlayer.currentItem?.duration.seconds 
audioPlayer.currentItem?.asset.duration.seconds
Run Code Online (Sandbox Code Playgroud)

我确信.wav我使用的文件没有被破坏,因为它被Android应用程序使用,他们能够获得持续时间.

下面我使用的代码非常适合.mp3.但不是.wav

if let url = URL(string: urlString) {
            audioAsset = AVURLAsset.init(url: url)

            if let audioAsset = audioAsset {

                let keys = ["playable"]

                   audioAsset.loadValuesAsynchronously(forKeys: keys, completionHandler: {

                    let playableStatus = audioAsset.statusOfValue(forKey: keys[0], error: nil)
                    switch playableStatus {

                    case .unknown,  .loading,  .failed,  .cancelled:
                        return

                    case .loaded:

                        DispatchQueue.main.async {

                            let playerItem = AVPlayerItem.init(asset: audioAsset)
                            self.audioPlayer.insert(playerItem, after: nil)
                            self.audioPlayer.play()

                            })
                        }
                        break
                    }
                })
            }
        }
Run Code Online (Sandbox Code Playgroud)

wav ios avqueueplayer swift

5
推荐指数
0
解决办法
96
查看次数