ビデオファイルをAVURLAsset
としてiPadアプリにロードしようとしています。非同期ロード機能を使用して、準備が整うのを待ちます。問題は、実行すると、何をどうすればいいのかまったくわからない、完全に一般的な「失敗」エラーメッセージが表示されることです。ビデオをMPMoviePlayerController
に渡しても機能しますが、AVURLAsset
はそれとの関係を拒否しているようです。
コード:
asset = [[AVURLAsset alloc] initWithURL:[NSURL URLWithString:[docPath stringByAppendingPathComponent:@"video.mov"]] options:nil];
[asset loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:@"tracks"] completionHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
[self composeIfReady];
});
}];
...
- (void)composeIfReady
{
NSError *error = nil;
if([asset statusOfValueForKey:@"tracks" error:&error] == AVKeyValueStatusFailed)
NSLog(@"error loading: %@", [error description]);
if(error == nil)
NSLog(@"okay awesome");
}
出力:
error loading: Error Domain=AVFoundationErrorDomain Code=-11800 "The operation couldn’t be completed. (AVFoundationErrorDomain error -11800.)" UserInfo=0x1696f0 {NSUnderlyingError=0x169a40 "The operation couldn’t be completed. (OSStatus error -12936.)"}
ちなみに、-11800は「不明なエラー」のエラーコードです。一種の行き止まり。何か案は?アセットをロードする前に設定する必要があるものはありますか?
解決しました。トリック:fileURLWithPath:
ではなくURLWithString:
。どうやら違いは本当に、本当に重要です。
_-[NSURL fileURLWithPath:]
_を使用してURLを作成しても、同じエラーが発生する場合。
AVURLAssetReferenceRestrictionsKey
を確認してください。リモートリソースが含まれている場合、ローカルのm3u8は再生に失敗する可能性があります。
値を@(AVAssetReferenceRestrictionForbidNone)
に設定すると、問題が解決します。
FileURLWithPathを使用しても問題が解決しない場合は、int(s)を使用している場合は、時間配列でNSTimeIntervalsをリクエストしてみてください。
これは動作しません:
NSMutableArray *playbackTimes = [NSMutableArray array];
for (int i = 0; i <= 10; i ++) {
[playbackTimes addObject:@(i)];
}
[self.videoPlayer requestThumbnailImagesAtTimes:playbackTimes timeOption:MPMovieTimeOptionNearestKeyFrame];
これは機能します:
NSMutableArray *playbackTimes = [NSMutableArray array];
for (int i = 0; i <= 10; i ++) {
[playbackTimes addObject:@((NSTimeInterval)i)];
}
[self.videoPlayer requestThumbnailImagesAtTimes:playbackTimes timeOption:MPMovieTimeOptionNearestKeyFrame];