Is it possible to make AVURLAsset work without a file extension?

此生再无相见时 提交于 2019-12-03 09:06:18

问题


I’m trying to create thumbnails for video files:

- (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;
    }
}

The catch is that the video files are stored in a content-addressable store and have no extensions. This appears to throw AVURLAsset off, as the asset gets created, but upon reading the frame image I get the following error:

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}

Is this documented or mentioned somewhere? I can’t believe I’m really forced to pass the file format information through the file name. The options argument to the AVURLAsset initializer looks like a good place to supply the filetype, but according to the documentation there does not seem to be any support for that.

PS. I have tested the code, the same file with the correct extension produces the thumbnails just fine.


回答1:


In the end I temporarily create a hardlink to the file and give the correct extension to the hardlink. It’s a hack though, I’d like to see a better solution. I’ve submitted a bug report against AVURLAsset, hopefully Apple could add the feature to read the file format information from the options dictionary.




回答2:


I believe I have found a workaround in iOS7. The trick is to use a AVAssetResourceLoader. Pass into the AVURLAsset a dummy URL which contains a scheme created by you, which will cause the AVAssetResourceLoaderDelegate to be called e.g. 'myscheme://random.com/file.mp4' As you can see with the URL I created it has a .mp4 extension, this will allow the AVPlayer to properly open the file, as long as you follow the next step correctly.

Now implement the AVAssetResourceLoaderDelegate to use the actual URL ie 'http://actual.com/file' The data will now be correctly passed through to the AVPlayer without it complaining about not being able to open that type of file format.




回答3:


Swift answer:

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)

Complete answer 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];

And now AVURLAsset will work with tmpPath.




回答4:


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()
        }
}


来源:https://stackoverflow.com/questions/9290972/is-it-possible-to-make-avurlasset-work-without-a-file-extension

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!