私が抱えている問題は、アプリが関数CVPixelBufferRef
から取得しようとしたときに、iOS9 sdk でアプリをコンパイルすると、ビデオが読み込まれ、すべてのインスタンスが作成されるときに、時々 null 値を取得することです。AVPlayerItemVideoOutput
- copyPixelBufferForItemTime:itemTimeForDisplay:
iOS 8 では私のアプリは正常に動作していましたが、iOS9 では問題が発生しています。iOS 8 SDK でコンパイルされた、ダウンロード可能なアプリ ストアにある私のアプリのバージョンでも、インストール時に同じ問題が発生します。 IOS9。
問題が発生して null が発生したgetCVPixelBufferRef
場合、ホームボタンを押してアプリを再度開いたときにアプリがバックグラウンドになりAVPlayerItemVideoOutput
、null を与えていたインスタンスがアクティブにCVPixelBufferRef
なり、問題が解決されます。
これは、問題を再現するYouTubeビデオです。
https://www.youtube.com/watch?v=997zG08_DMM&feature=youtu.be
すべてのアイテムのインスタンスを作成するためのサンプル コードは次のとおりです。
NSURL *url ;
url = [[NSURL alloc] initFileURLWithPath:[_mainVideo objectForKey:@"file"]];
NSDictionary *pixBuffAttributes = @{(id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange)};
_videoOutput = [[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:pixBuffAttributes];
_myVideoOutputQueue = dispatch_queue_create("myVideoOutputQueue", DISPATCH_QUEUE_SERIAL);
[_videoOutput setDelegate:self queue:_myVideoOutputQueue];
_player = [[AVPlayer alloc] init];
// Do not take mute button into account
NSError *error = nil;
BOOL success = [[AVAudioSession sharedInstance]
setCategory:AVAudioSessionCategoryPlayback
error:&error];
if (!success) {
// NSLog(@"Could not use AVAudioSessionCategoryPlayback", nil);
}
asset = [AVURLAsset URLAssetWithURL:url options:nil];
if(![[NSFileManager defaultManager] fileExistsAtPath:[[asset URL] path]]) {
// NSLog(@"file does not exist");
}
NSArray *requestedKeys = [NSArray arrayWithObjects:kTracksKey, kPlayableKey, nil];
[asset loadValuesAsynchronouslyForKeys:requestedKeys completionHandler:^{
dispatch_async( dispatch_get_main_queue(),
^{
/* Make sure that the value of each key has loaded successfully. */
for (NSString *thisKey in requestedKeys)
{
NSError *error = nil;
AVKeyValueStatus keyStatus = [asset statusOfValueForKey:thisKey error:&error];
if (keyStatus == AVKeyValueStatusFailed)
{
[self assetFailedToPrepareForPlayback:error];
return;
}
}
NSError* error = nil;
AVKeyValueStatus status = [asset statusOfValueForKey:kTracksKey error:&error];
if (status == AVKeyValueStatusLoaded)
{
//_playerItem = [AVPlayerItem playerItemWithAsset:asset];
[_playerItem addOutput:_videoOutput];
[_player replaceCurrentItemWithPlayerItem:_playerItem];
[_videoOutput requestNotificationOfMediaDataChangeWithAdvanceInterval:ONE_FRAME_DURATION];
/* When the player item has played to its end time we'll toggle
the movie controller Pause button to be the Play button */
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:_playerItem];
seekToZeroBeforePlay = NO;
[_playerItem addObserver:self
forKeyPath:kStatusKey
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
context:AVPlayerDemoPlaybackViewControllerStatusObservationContext];
[_player addObserver:self
forKeyPath:kCurrentItemKey
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
context:AVPlayerDemoPlaybackViewControllerCurrentItemObservationContext];
[_player addObserver:self
forKeyPath:kRateKey
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
context:AVPlayerDemoPlaybackViewControllerRateObservationContext];
[self initScrubberTimer];
[self syncScrubber];
}
else
{
// NSLog(@"%@ Failed to load the tracks.", self);
}
});
}];
nullピクセルバッファを提供するサンプルコードを次に示します
CVPixelBufferRef pixelBuffer =
[_videoOutput
copyPixelBufferForItemTime:[_playerItem currentTime]
itemTimeForDisplay:nil];
NSLog(@"the pixel buffer is %@", pixelBuffer);
NSLog (@"the _videoOutput is %@", _videoOutput.description);
CMTime dataTime = [_playerItem currentTime];
//NSLog(@"the current time is %f", dataTime);
return pixelBuffer;