rtsp:// liveStream 与 AVPlayer
rtsp:// liveStream with AVPlayer
我想用 AVPlayer 在 iPhone 设备上播放 liveStream。我还想从此流中获取 CVPixelBufferRef
以供下次使用。
我使用 Apple guide 创建播放器。目前使用本地存储的 videoFiles 这个播放器工作得很好,当我尝试播放这个 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 提供的 guid 完成的,但无论如何:
准备播放资产
- (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://URLreturnAVKeyValueStatusFailed
错误:
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.)"}
我也找问题:
- FirstOne - try to use for this stream sample app from Apple - StitchedStreamPlayer - 但我想在那里播放的流会出现一些不同的错误
- SecondOne - 尝试同时使用这两个建议 -
fileURLWithPath
return 不正确 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://流吗?
如果是,有人可以提供正确用法的示例吗? Nad我在代码中做错了什么?
如果 AvPlayer 不支持 rtsp:// 可能存在一些替代解决方案?
我找不到通过 AVURLAsset
进行 rtsp 流式传输的方法,但可以找到很好的起点 here。也许对某些人有用
您尝试过 MobileVLCKit
吗?
这真的很容易,而且效果很好!我写了一个small example here
如果您想尝试,只需在您的终端中输入 pod try ONVIFCamera
。
操作方法如下:
var mediaPlayer = VLCMediaPlayer()
// Associate the movieView to the VLC media player
mediaPlayer.drawable = self.movieView
let url = URL(string: "rtsp://IP_ADDRESS:PORT/params")
let media = VLCMedia(url: url)
mediaPlayer.media = media
mediaPlayer.play()
基本上可以将 rtsp 流分割成小的 mp4 容器,并使用自定义的 URLAsset 将容器推送到 AVPlayer 中。这是一个实验,它仍然需要在块之间平滑过渡的工作,但喜欢这里的想法 https://github.com/MaximKomlev/RTSPAVPlayer
无法使用AVPlayer 播放RTSP 流。您 http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8
共享的 link 是一个 HLS 流。所以它工作正常。
您应该在服务器中将 RTSP 流转换为 HLS,否则您需要寻找其他方法。最高效的一种是在客户端播放HLS流。但是,如果您没有机会获得 HLS 流,则可以使用 VLC。这种方式效率不高,但会奏效。
我有一个旧博客 post 在 iOS 上解释 VLC。可以参考。
https://medium.com/mobil-dev/lets-make-a-video-player-app-e759c165fd58
我想用 AVPlayer 在 iPhone 设备上播放 liveStream。我还想从此流中获取 CVPixelBufferRef
以供下次使用。
我使用 Apple guide 创建播放器。目前使用本地存储的 videoFiles 这个播放器工作得很好,当我尝试播放这个 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 提供的 guid 完成的,但无论如何:
准备播放资产
- (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://URLreturnAVKeyValueStatusFailed
错误:
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.)"}
我也找问题:
- FirstOne - try to use for this stream sample app from Apple - StitchedStreamPlayer - 但我想在那里播放的流会出现一些不同的错误
- SecondOne - 尝试同时使用这两个建议 -
fileURLWithPath
return 不正确 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://流吗? 如果是,有人可以提供正确用法的示例吗? Nad我在代码中做错了什么? 如果 AvPlayer 不支持 rtsp:// 可能存在一些替代解决方案?
我找不到通过 AVURLAsset
进行 rtsp 流式传输的方法,但可以找到很好的起点 here。也许对某些人有用
您尝试过 MobileVLCKit
吗?
这真的很容易,而且效果很好!我写了一个small example here
如果您想尝试,只需在您的终端中输入 pod try ONVIFCamera
。
操作方法如下:
var mediaPlayer = VLCMediaPlayer()
// Associate the movieView to the VLC media player
mediaPlayer.drawable = self.movieView
let url = URL(string: "rtsp://IP_ADDRESS:PORT/params")
let media = VLCMedia(url: url)
mediaPlayer.media = media
mediaPlayer.play()
基本上可以将 rtsp 流分割成小的 mp4 容器,并使用自定义的 URLAsset 将容器推送到 AVPlayer 中。这是一个实验,它仍然需要在块之间平滑过渡的工作,但喜欢这里的想法 https://github.com/MaximKomlev/RTSPAVPlayer
无法使用AVPlayer 播放RTSP 流。您 http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8
共享的 link 是一个 HLS 流。所以它工作正常。
您应该在服务器中将 RTSP 流转换为 HLS,否则您需要寻找其他方法。最高效的一种是在客户端播放HLS流。但是,如果您没有机会获得 HLS 流,则可以使用 VLC。这种方式效率不高,但会奏效。
我有一个旧博客 post 在 iOS 上解释 VLC。可以参考。
https://medium.com/mobil-dev/lets-make-a-video-player-app-e759c165fd58