19

ビデオファイルのサムネイルを作成しようとしています。

- (UIImage*) thumbnailForVideoAtURL: (NSURL*) videoURL
{
    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
    AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
    CGImageRef imageHandle = [generator copyCGImageAtTime:kCMTimeZero actualTime:NULL error:NULL];
    if (imageHandle) {
        UIImage *frameImage = [UIImage imageWithCGImage:imageHandle];
        CFRelease(imageHandle);
        return frameImage;
    } else {
        return nil;
    }
}

問題は、ビデオファイルがコンテンツアドレス可能なストアに保存されており、拡張子がないことです。AVURLAssetアセットが作成されると、これはうまくいかないように見えますが、フレームイメージを読み取ると、次のエラーが発生します。

Error Domain=AVFoundationErrorDomain Code=-11828 "Cannot Open" UserInfo=0x167170 {NSLocalizedFailureReason=This media format is not supported., NSUnderlyingError=0x163a00 "The operation couldn’t be completed. (OSStatus error -12847.)", NSLocalizedDescription=Cannot Open}

これはどこかに文書化または言及されていますか?ファイル名を介してファイル形式情報を渡すことを本当に強制されているとは信じられません。イニシャライザへのoptions引数AVURLAssetはファイルタイプを提供するのに適した場所のように見えますが、ドキュメントによると、それをサポートしていないようです。

PS。コードをテストしましたが、正しい拡張子の同じファイルでサムネイルが正常に生成されます。

4

4 に答える 4

13

最後に、ファイルへのハードリンクを一時的に作成し、ハードリンクに正しい拡張子を付けます。それはハックですが、もっと良い解決策を見たいです。私はバグレポートを提出しました。Appleが辞書AVURLAssetからファイル形式情報を読み取る機能を追加できることを願っています。options

于 2012-02-19T16:15:34.647 に答える
6

迅速な回答:

let filePath = ###YOU SET THIS###
let fileManager = NSFileManager.defaultManager()
let documentsURL = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .AllDomainsMask).last!
let tmpURL = documentsURL.URLByAppendingPathComponent("tmp.caf")
_ = try? fileManager.removeItemAtURL(tmpURL)
_ = try? fileManager.linkItemAtURL(fileURL, toURL: tmpURL)

完全な答えObj-C:

NSString *filePath = ###YOU SET THIS###
NSFileManager *dfm = [NSFileManager defaultManager];
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *tmpPath = [[documentPaths lastObject] stringByAppendingPathComponent:@"tmp.caf"];
[dfm removeItemAtPath:tmpPath error:nil];
[dfm linkItemAtPath:filePath toPath:tmpPath error:nil];

そして今AVURLAssetはで動作しtmpPathます。

于 2013-10-19T23:51:22.643 に答える
5
let mimeType = "video/mp4; codecs=\"avc1.42E01E, mp4a.40.2\""
let asset = AVURLAsset(url: videoURL!, options:["AVURLAssetOutOfBandMIMETypeKey": mimeType])
let playerItem = AVPlayerItem(asset: asset)
avPlayer = AVPlayer(playerItem: playerItem)
self.avPlayerViewConroller?.player = avPlayer
playerItem.addObserver(self, forKeyPath: "status", options: NSKeyValueObservingOptions(), context: nil)
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)
{
        if(avPlayer?.currentItem?.status == AVPlayerItemStatus.readyToPlay)
        {
            avPlayer?.play()
        }
}
于 2019-01-08T07:35:00.730 に答える
4

iOS7で回避策を見つけたと思います。秘訣は、AVAssetResourceLoaderを使用することです。AVURLAssetに、自分で作成したスキームを含むダミーのURLを渡します。これにより、AVAssetResourceLoaderDelegateが呼び出されます。例:'myscheme://random.com/file.mp4'作成したURLでわかるように、。があります。 mp4拡張子。これにより、次の手順を正しく実行している限り、AVPlayerがファイルを正しく開くことができます。

次に、AVAssetResourceLoaderDelegateを実装して、実際のURLを使用します。つまり' http://actual.com/file 'データは、そのタイプのファイル形式を開くことができないという文句を言わずに、AVPlayerに正しく渡されます。

于 2013-11-01T08:58:41.257 に答える