2012-02-15 5 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 для инициализатора AVURLAsset выглядит как хорошее место для подачи файла, но, согласно документации, похоже, для этого нет никакой поддержки.

PS. Я протестировал код, тот же файл с правильным расширением делает миниатюры просто прекрасными.

ответ

10

В заключение я временно создаю жесткую ссылку на файл и даю правильное расширение для жесткой ссылки. Хотя это взломать, я бы хотел увидеть лучшее решение. У меня есть submitted a bug report против AVURLAsset, надеюсь, Apple может добавить эту функцию, чтобы прочитать информацию о формате файла из словаря options.

+0

Можете ли вы сказать мне плз. что как u создал жесткую ссылку на файл, на самом деле у меня есть url для видеороликов, и мне нужно создать миниатюру этого видео, используя его url –

+0

Вы имеете в виду локальный URL-адрес файла или обычный URL-адрес HTTP YouTube? Локальный URL-адрес файла можно легко связать с помощью '[NSFileManager linkItemAtURL: toURL: error:]'. Создание миниатюры с URL-адреса видеоролика HTTP заслуживает внимания [отдельный вопрос] (http://stackoverflow.com/questions/ask), IMHO. – zoul

+1

Все еще не исправлено в iOS7 и '[[AVAudioPlayer alloc] initWithContentsOfURL: ошибка URL: nil];' не имеет проблем с файлами, не имеющими расширений –

3

Swift Ответ:

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.поэтому Linking works – ProblemSlover

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 »? Вы каким-то образом меняете URL-адреса? – Shackleford

+1

Я сделал это некоторое время назад, но в основном я использовал схему ресурсов с расширением .mp4, чтобы делегат вызывался и не пропускался. Когда-то внутри этого делегата я использовал фактический адрес ресурса для его загрузки, я использовал статический метод, чтобы получить реальный адрес ресурса, вместо того, чтобы использовать фиктивный, необходимый для правильного вызова делегата. – Pellet