iOS 6.1のAVPlayerItemのAVMutuableCompositionがトラックリストを正しくロードしない理由をデバッグするのを助けるために、誰かが私を正しい方向に向けることができますか?
私がやっていることは、AVMutableCompositionTrack を作成し、再生のために同じ mp4 から時間範囲を追加することです。これは他のファイルでは正しく機能しますが、720p、毎秒 30 フレームでエンコードされたファイルがいくつかあり、トラック リストが正しく作成されません。シームレスに順番に表示したい。
これが私のコードの一部です:
- (AVPlayerItem *) loadVideoByAVComposition
{
AVComposition *composition = [ self loadCompositionTracks];
AVComposition *immutableSnapshotComposition = [composition copy];
AVPlayerItem *playerItemForComposition = [[AVPlayerItem alloc]initWithAsset:immutableSnapshotComposition];
return playerItemForComposition;
}
トラックをロード:
-(AVMutableComposition *) loadCompositionTracks
{
AVMutableComposition *composition = [[AVMutableComposition alloc]init];
NSDictionary *optionsDictionary = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:AVURLAssetPreferPreciseDurationAndTimingKey];
AVMutableCompositionTrack *compositionVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
// hard coded test mp4
NSString *videoFileName = @"avi.mp4";
AVAsset *asset = [self getAVAssetByFileName:videoFileName optsDict:optionsDictionary];
if (asset == nil) { return nil; }
// add some track items
[self addTrackList:compositionVideoTrack asset:asset];
return composition;
}
これらのファイルを作成するデスクトップ アプリは、ビデオ ファイルのフレーム番号と長さによって情報をエクスポートします。だから私はこれらから始めて、トラックリストに追加するために秒に変換します.
-(void)addTrackList:(AVMutableCompositionTrack *)track asset:(AVAsset *)asset
{
if (track == nil) { return; }
CMTime insertionPointTime = kCMTimeZero;
// add some test track insert points
insertionPointTime = [self addTrackItems:track asset:asset start:100 duration:800 insertTime:insertionPointTime];
insertionPointTime = [self addTrackItems:track asset:asset start:1500 duration:600 insertTime:insertionPointTime];
insertionPointTime = [self addTrackItems:track asset:asset start:2500 duration:500 insertTime:insertionPointTime];
}
そして、実際に時間範囲を AVMutuableComposition に追加する方法は次のとおりです。
-(CMTime)addTrackItems:(AVMutableCompositionTrack *)track asset:(AVAsset *)asset start:(NSUInteger)start duration:(NSUInteger)duration insertTime:(CMTime)insertTime
{
if (track == nil) { return insertTime; }
NSError *videoError = nil;
Float64 secondsCalc = (start / 30);
CMTime startTime = CMTimeMakeWithSeconds(secondsCalc, 600);
secondsCalc = duration / 30;
CMTime cmDuration = CMTimeMakeWithSeconds(secondsCalc, 600);
CMTimeRange timeRange = CMTimeRangeMake(startTime, cmDuration);
// add video track
AVAssetTrack *clipVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
[track insertTimeRange:timeRange ofTrack:clipVideoTrack atTime:insertTime error:&videoError];
if (videoError != nil)
{
NSLog(@"");
NSLog(@"Error while adding track to composition");
}
// calculate for next insert point
CMTime resultInsertionPointTime = CMTimeAdd(insertTime, timeRange.duration);
return resultInsertionPointTime;
}
したがって、このコードはいくつかのビデオ ファイルで機能しますが、一部のビデオ ファイルでは最初のトラックだけが読み込まれ、他のトラックは読み込まれません。黒いフレームまたはビデオが停止するだけです。基本的に、トラック リストを正しく構築していません。では、ロードから戻ってくる警告コードやエラー コードをデバッグして、TimeRanges が有効かどうかなどを教えてもらうにはどうすればよいでしょうか。
読み込みプロセスを説明できるアップルのドキュメント以外に、他に良いリソースはありますか。アップルのドキュメントはまばらです。私はすでにいくつかの wwdc セッションも見てきました。どんな助けでも大歓迎です。ありがとう!