2012-02-15 134 views
11

我試圖爲視頻文件創建縮略圖:是否可以使AVURLAsset在沒有文件擴展名的情況下工作?

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

美中不足的是,視頻文件存儲在一個content-addressable store,沒有擴展。這似乎拋出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參數看起來是提供文件類型的好地方,但根據文檔,似乎沒有任何支持。

PS。我測試了代碼,具有正確擴展名的相同文件產生縮略圖就好了。

回答

10

最後,我臨時創建一個硬鏈接到文件並給硬鏈接提供正確的擴展名。這是一個黑客,但我希望看到更好的解決方案。我有submitted a bug report針對AVURLAsset,希望Apple可以添加該功能來從options字典中讀取文件格式信息。

+0

你能告訴我PLZ。你如何創建硬鏈接到文件,實際上我有一個你管視頻的網址,我必須使用它的網址創建該視頻的縮略圖 – 2012-03-01 12:20:23

+0

你的意思是一個本地文件的URL,或一個普通的HTTP YouTube網址?使用'[NSFileManager linkItemAtURL:toURL:error:]''可以很容易地鏈接本地文件的URL。從HTTP YouTube視頻URL創建縮略圖值得[單獨的問題](http://stackoverflow.com/questions/ask),恕我直言。 – zoul 2012-03-01 13:04:11

+1

在iOS7和[[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil]中仍然沒有修復;'沒有擴展名的文件沒有問題 – 2013-10-19 19:51:28

3

斯威夫特答案:

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工作。

+0

嘿..相同的方法在PHAsset的情況下工作..我無法通過從PHAsset獲取的路徑讀取本地文件。所以鏈接工程 – ProblemSlover 2015-11-03 10:20:37

4

我相信我已經在iOS7中找到了解決方法。 訣竅是使用AVAssetResourceLoader。 傳入AVURLAsset一個虛擬URL,其中包含您創建的方案,這會導致AVAssetResourceLoaderDelegate被調用,例如'myscheme://random.com/file.mp4' 正如你可以看到我創建的URL有一個.mp4擴展名,這將允許AVPlayer正確地打開該文件,只要你正確地執行下一步。

現在實現AVAssetResourceLoaderDelegate以使用實際URL即'http://actual.com/file' 現在數據將正確傳遞給AVPlayer,而不會抱怨它無法打開該類型的文件格式。

+1

我正在努力實現您推薦的解決方法,並且我正在實現AVAssetResourceLoaderDelegate,但我仍然無法讓AVPlayer播放音頻源。你能詳細說明你的意思嗎?「現在實現AVAssetResourceLoaderDelegate以使用實際的URL,即'http://actual.com/file'」?您是否以某種方式換出網址? – Shackleford 2017-07-13 21:29:25

+1

前段時間我做了這個,但基本上我使用了一個帶.mp4擴展名的資源方案,這樣委託將被調用並且不會被跳過。一旦進入該委託,我使用實際的資源地址來加載它,我使用靜態方法來獲取實際資源地址,而不是使用虛擬委託所需的代碼來正確調用。 – Pellet 2017-07-14 05:37:06

相關問題