我想在iPhone设备上使用AVPlayer播放直播流。同时,我还希望从这个流中获取CVPixelBufferRef以供下一步使用。
我使用Apple指南创建播放器。目前,当我尝试播放本地存储的视频文件时,这个播放器工作得很好,当我尝试播放这个AppleSampleStremURL -
问题出现在我想播放rtsp://这样的流时:
准备资产进行播放
准备播放器。
这里出现了问题 -
我使用Apple指南创建播放器。目前,当我尝试播放本地存储的视频文件时,这个播放器工作得很好,当我尝试播放这个AppleSampleStremURL -
http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8
- 它也能正常工作。问题出现在我想播放rtsp://这样的流时:
rtsp://192.192.168.1:8227/TTLS/Streaming/channels/2?videoCodecType=H.264
代码 - 几乎所有的代码都是使用Apple提供的指南完成的,但无论如何:准备资产进行播放
- (void)initialSetupWithURL:(NSURL *)url
{
NSDictionary *assetOptions = @{ AVURLAssetPreferPreciseDurationAndTimingKey : @YES,
AVURLAssetReferenceRestrictionsKey : @(AVAssetReferenceRestrictionForbidNone)};
self.urlAsset = [AVURLAsset URLAssetWithURL:url options:assetOptions];
}
准备播放器。
- (void)prepareToPlay
{
NSArray *keys = @[@"tracks"];
__weak SPHVideoPlayer *weakSelf = self;
[weakSelf.urlAsset loadValuesAsynchronouslyForKeys:keys completionHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf startLoading];
});
}];
}
- (void)startLoading
{
NSError *error;
AVKeyValueStatus status = [self.urlAsset statusOfValueForKey:@"tracks" error:&error];
if (status == AVKeyValueStatusLoaded) {
self.assetDuration = CMTimeGetSeconds(self.urlAsset.duration);
NSDictionary* videoOutputOptions = @{ (id)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange)};
self.videoOutput = [[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:videoOutputOptions];
self.playerItem = [AVPlayerItem playerItemWithAsset: self.urlAsset];
[self.playerItem addObserver:self
forKeyPath:@"status"
options:NSKeyValueObservingOptionInitial
context:&ItemStatusContext];
[self.playerItem addObserver:self
forKeyPath:@"loadedTimeRanges"
options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld
context:&ItemStatusContext];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:self.playerItem];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didFailedToPlayToEnd)
name:AVPlayerItemFailedToPlayToEndTimeNotification
object:nil];
[self.playerItem addOutput:self.videoOutput];
self.assetPlayer = [AVPlayer playerWithPlayerItem:self.playerItem];
[self addPeriodicalObserver];
NSLog(@"Player created");
} else {
NSLog(@"The asset's tracks were not loaded:\n%@", error.localizedDescription);
}
}
这里出现了问题 -
AVKeyValueStatus status = [self.urlAsset statusOfValueForKey:@"tracks" error:&error];
- 这行代码中使用rtsp:// URL会返回AVKeyValueStatusFailed
出错信息:Printing description of error:
Error Domain=AVFoundationErrorDomain Code=-11800
"The operation could not be completed"
UserInfo=0x7fd1ea5a8a10 {NSLocalizedFailureReason=An unknown error occurred (-12936),
NSLocalizedDescription=The operation could not be completed,
NSURL=rtsp://192.168.1.168:8556/PSIA/Streaming/channels/2?videoCodecType=H.264,
NSUnderlyingError=0x7fd1ea53f830 "The operation couldn’t be completed.
(OSStatus error -12936.)"}
我也寻找了问题:
- 第一个 - 尝试使用苹果提供的样例应用程序StitchedStreamPlayer,但在播放想要播放的流时会出现几个不同的错误。
- 第二个 - 尝试同时使用两个建议,
fileURLWithPath
返回的URL不正确,例如:rtsp://192.168.1.168:8556/PSIA/Streaming/channels/2?videoCodecType=H.264 --file:///
,所以我猜这是不正确的。 - 根据AppleDev的建议,尝试使用不同的方法创建AvPlayer,例如
[AVPlayer playerWithPlayerItem:playerItem]
和[AVPlayer playerWithURL:url]
,但没有改变。还尝试设置AVAsset的不同设置-在initialSetupWithURL
中(请参见上面的方法实现)。
所以,问题是AVPlayer支持播放rtsp://流吗? 如果是,是否有人可以提供正确使用的示例?我在代码中做错了什么吗? 如果AvPlayer不支持rtsp://,也许存在一些替代方案?