Как воспроизводить файлы фильмов без расширения на iOS с помощью MPMoviePlayerController или AVPlayer?

Я хочу посмотреть фильм в iOS 4.3 на iPad. Я успешно использовал MPMoviePlayerController и AVPlayer для загрузки файлов с удаленного URL-адреса, когда имя файла имеет расширение файла. Однако, когда я использую CDN, который не возвращает имя файла (просто непредсказуемое случайное имя), ни MPMoviePlayerController, ни AVPlayer, похоже, не справляются.

Есть ли способ сказать любому игроку, что это действительно фильм типа x, и он должен просто продолжить его воспроизведение?

MPMoviePlayerController вернет следующую ошибку из уведомления об изменении состояния:

{
    MPMoviePlayerPlaybackDidFinishReasonUserInfoKey = 1;
    error = "Error Domain=MediaPlayerErrorDomain Code=-12847 \"This movie format is not supported.\" UserInfo=0x5b60030 {NSLocalizedDescription=This movie format is not supported.}";
}

Я знаю, что этот файл является допустимым файлом m4v, так как когда я его переименовываю, все в порядке.


person Michael    schedule 31.03.2011    source источник
comment
+1 за хороший вопрос - надеюсь, кто-то найдет способ добиться этого ....   -  person Till    schedule 03.04.2011
comment
Нет идеального решения, но я нашел кое-что, что может помочь некоторым людям - если вы убедитесь, что заголовок типа контента правильный, видео будет воспроизводиться, если нет расширения файла. Итак, чтобы воспроизвести видео в MPMoviePlayerController, вам необходимо либо правильное расширение файла , либо правильный тип mime. Я протестировал его с допустимым расширением файла и неправильным типом содержимого, и он все равно будет воспроизводиться.   -  person Michael    schedule 19.04.2011
comment
Привет @Michael, Вы работали с этим вопросом? Я пытаюсь сделать то же самое сейчас, могу я узнать, как это сработало?   -  person Santo    schedule 24.08.2015
comment
@Santo Если вам нравится Private API, посмотрите мой ответ ниже   -  person naituw    schedule 02.02.2018


Ответы (8)


Если проигрыватель не может угадать формат файла, вам необходимо проверить, что CDN отправляет обратно правильный тип mime. Я предполагаю, что ваш CDN не может правильно угадать mimetype, как и проигрыватель.

В большинстве случаев это связано с тем, как CDN представляет заголовок HTTP. Убедитесь, что в заголовке Content-Type установлен формат видео, соответствующий вашему содержанию.

person Magnus    schedule 31.03.2012
comment
Мой сервер возвращает тип контента видео / mp4, мой файл также является допустимым файлом mp4 с кодировкой H.264, но AVPlayer не воспроизводит его без расширения файла. И это пять лет спустя с Swift 3. Есть идеи, что еще может быть неправильным? - person shelll; 03.05.2017

Файл в tmp

NSString* _filePath

Создать символическую ссылку

NSFileManager *filemgr = [NSFileManager defaultManager];
NSString *slink = [_filePath stringByAppendingPathExtension:@"m4v"];
if (![filemgr fileExistsAtPath:slink]) {
    NSError *error = nil;
    [filemgr createSymbolicLinkAtPath:[_filePath stringByAppendingPathExtension:@"m4v"] withDestinationPath: _filePath error: &error];
    if (error) {
        ...
    }
}
...

воспроизвести видео с помощью Slink

person Andrii Tishchenko    schedule 08.05.2013
comment
Будь осторожен. SymbolicLink будет удален, когда приложение войдет в фоновый режим :( - person Tony; 14.07.2014
comment
Это работает только для локальных файлов. Вопрос касается удаленного URL без расширения файла. - person Sterling Christensen; 25.12.2014

WebKit обрабатывает это с помощью параметра Private AVURLAsset: AVURLAssetOutOfBandMIMETypeKey, этот параметр используется, когда вы указываете тип MIME в HTML-теге video,

Вы можете использовать эту опцию как:

NSString * mimeType = @"video/mp4";

// or even with codecs
mimeType = @"video/mp4; codecs=\"avc1.42E01E, mp4a.40.2\"";

// create asset
AVURLAsset * asset = [[AVURLAsset alloc] initWithURL:url options:@{@"AVURLAssetOutOfBandMIMETypeKey": mimeType}];

// create AVPlayer with AVURLAsset
AVPlayer * player = [AVPlayer playerWithPlayerItem:[AVPlayerItem playerItemWithAsset:asset]];

Поскольку это закрытый ключ, вы можете скрыть его, если планируете отправить его в AppStore.

Исходный код WebKit можно найти здесь: https://opensource.apple.com/source/WebCore/WebCore-7604.1.38.1.6/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm.auto.html

person naituw    schedule 02.02.2018

iPhone поддерживает видео H.264, MPEG-4 в форматах .mp4, .m4v, .mov и аудиофайлы в форматах AAC, MP3, M4a, Apple lossless и Audible. Вы можете использовать метод NSFileManager -contentsOfDirectoryAtPath: error: для получения массива с содержимым каталога (в виде строк). Затем вы просто выполняете операции со строками.

person imdhresh    schedule 22.09.2011
comment
Вопрос касается удаленных URL-адресов. - person Sterling Christensen; 25.12.2014

Дилан прав.

И MPMoviePlayer, и AVPlayer нуждаются в расширении файла для воспроизведения файла с URL-адреса, в противном случае будет показано сообщение об ошибке. Лучше использовать какие-нибудь уловки.

person Tarun    schedule 09.03.2012
comment
Как я сказал выше, это не совсем так - если у вас есть правильный тип mime для файла, он будет работать. - person Michael; 12.03.2012
comment
это неправда - я часто проигрываю видео без имен файлов. - person Magnus; 31.03.2012

Если у вас есть проблемы с получением ContentType вашего соединения, вы можете циклически переключаться между воспроизводимыми типами MIME и создавать символические ссылки на фактический файл с расширением и проверять, доступны ли они для воспроизведения. Вот так:

NSLog(@"linked path: %@",[videoURL absoluteString]);
NSString* linkedPath;
AVURLAsset* asset;
NSFileManager *filemgr = [NSFileManager defaultManager];

for (NSString* string in [AVURLAsset audiovisualMIMETypes]) {

    if ([string containsString:@"video/"]) {

        NSLog(@"Trying: %@",string);

        linkedPath = [[videoURL absoluteString] stringByAppendingPathExtension:[string stringByReplacingOccurrencesOfString:@"video/" withString:@""]];
        NSLog(@"linked path: %@",linkedPath);

        if (![filemgr fileExistsAtPath:linkedPath]) {
            NSError *error = nil;
            [filemgr createSymbolicLinkAtURL:[NSURL URLWithString:linkedPath] withDestinationURL:videoURL error:&error];
            if (error) {
               NSLog(@"error %@",error.localizedDescription);
            }
        }

       asset = [AVURLAsset assetWithURL:[NSURL URLWithString:linkedPath]];
        if ([asset isPlayable]) {
            NSLog(@"Playable");
            break;
        }else{
            NSLog(@"Not Playable");
            asset = nil;
        }
    }

}
person ben    schedule 26.08.2016
comment
Я включил эту строку кода вместе с приведенным выше кодом, решает мою проблему NSString *slink = [_filePath stringByAppendingPathExtension:@"mp4"]; - person Nasir; 13.03.2017
comment
По сути, приведенный выше код преобразует myfilename без расширения во что-то вроде этого, myfilename.mp4 и myfilename.m4v, myfilename.3gpp и myfilename.3gpp2 и так далее. Все эти созданные символические ссылки могут находиться в том же каталоге или в другом каталоге. - person Nasir; 13.03.2017

Это своего рода взлом, но вы могли бы пропустить каждое имя с помощью метода, который проверяет наличие точки с тремя символами после нее. Если нет, просто добавьте .m4v автоматически. Или получите тип MIME и автоматически добавьте расширение на основе возвращаемого типа. Если доступно. Посмотрите документацию с NSString для получения дополнительной информации. Удачи! Сообщите мне, помогло ли это.

person Dylan Gattey    schedule 13.08.2011

Наконец я нашел ответ.

Вы должны использовать AVURLAsset (подкласс AVAsset) и установить MIMEType во входных параметрах:

let mimeType = "video/mp4; codecs=\"avc1.42E01E, mp4a.40.2\""
let urlAsset = AVURLAsset(url: url, options["AVURLAssetOutOfBandMIMETypeKey": mimeType])

Источник - ›https://stackoverflow.com/a/54087143/6736184

person Mohsen Khosravinia    schedule 01.07.2020
comment
В таких сценариях этот вопрос квалифицируется как возможный дубликат. Вы можете пометить вопрос OP, если считаете, что это решение уже существует на веб-сайте. - person mishsx; 01.07.2020