2011-03-31 14 views
24

Quiero reproducir una película en iOS 4.3 en el iPad. Utilicé con éxito MPMoviePlayerController y AVPlayer para cargar archivos desde una URL remota cuando el nombre de archivo tiene una extensión de archivo. Sin embargo, cuando uso un CDN que no devuelve el nombre de archivo (solo un nombre aleatorio imposible de adivinar), ni MPMoviePlayerController ni AVPlayer parecen ser capaces de hacer frente.¿Cómo reproducir archivos de película sin extensión de archivo en iOS con MPMoviePlayerController o AVPlayer?

¿Hay alguna manera de decirle a un jugador que realmente es una película de tipo x y debería seguir jugando?

MPMoviePlayerController devolverá el siguiente error de que haya cambiado la notificación de estado:

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

Sé que es un archivo M4V válida, como cuando se cambio el nombre de todo está bien.

+0

1 para una buena pregunta - espero que alguien se le ocurre una manera de lograr esto .... No se – Till

+1

una solución ideal, pero he encontrado algo Esto podría ayudar a algunas personas: si se asegura de que el encabezado del tipo de contenido sea correcto, el video se reproducirá si no hay una extensión de archivo. Así que para obtener un vídeo para reproducirlo en MPMoviePlayerController necesita ** ** o bien la extensión adecuada ** ** o el tipo MIME adecuado. Lo probé con una extensión de archivo válida y un tipo de contenido incorrecto y todavía se reproducirá. – Michael

+1

Hola @Michael, ¿Te han trabajado con esta pregunta? Estoy tratando con lo mismo ahora, ¿puedo saber cómo funcionó? – Santo

Respuesta

4

Si el jugador no puede adivinar el formato de archivo, debe verificar que el CDN envíe el tipo correcto de mime. Supongo que su CDN no puede adivinar correctamente el tipo mimético ni el jugador.

En la mayoría de los casos esto se debe a la forma en que el CDN presenta el encabezado HTTP. Comprueba que el encabezado "Content-Type" esté configurado en un formato de video que coincida con tu contenido.

+2

Mi servidor devuelve el tipo de contenido video/mp4, mi archivo también es un archivo mp4 válido con codificación H.264, pero el AVPlayer no lo reproduce sin la extensión de archivo. Y esto es cinco años después con Swift 3. ¿Alguna idea de qué más podría estar mal? – shelll

0

Es una especie de hack, pero lo que se puede hacer es ejecutar cada nombre a través de un método que busca un período con tres caracteres después. Si no, solo añada .m4v automáticamente. O obtenga el tipo MIME y agregue una extensión automáticamente en función del tipo devuelto. Si está disponible. Consulte la documentación con NSString para obtener más información. ¡Buena suerte! Avíseme si eso ayudó.

1

iPhone compatible con video H.264, MPEG-4 en formatos .mp4, .m4v, .mov y archivos de audio en AAC, MP3, M4a, Apple sin pérdidas y Audible. Puede usar el método -contentsOfDirectoryAtPath: error: de NSFileManager para obtener una matriz con el contenido de un directorio (como cadenas). Luego solo realiza operaciones de cadenas.

+0

. La pregunta es acerca de las URL remotas. –

2

Dylan es correcto.

Tanto MPMoviePlayer como AVPlayer necesitan una extensión de archivo para reproducir el archivo desde la URL; de lo contrario, se mostrará un mensaje de error. Es mejor usar algún tipo de trucos.

+0

Como mencioné anteriormente, esto no es estrictamente cierto: si tiene el tipo de mime correcto en un archivo, entonces funcionará. – Michael

+0

esto no es cierto: a menudo reproduzco videos sin ningún nombre de archivo. – Magnus

6

archivo en tmp

NSString* _filePath 

Crear enlace simbólico

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) { 
     ... 
    } 
} 
... 

juego de vídeo por escabullirse

+0

buena solución, funciona a la perfección. – NSRover

+2

Ten cuidado. SymbolicLink se eliminará cuando la aplicación ingrese el fondo :( – VietHung

+0

Esto solo funciona para archivos locales. La pregunta es sobre una URL remota sin extensión de archivo. –

1

Si tiene problemas para obtener la ContentType de la conexión que podía desplazarse por la tipos MIME reproducibles y crear enlaces simbólicos al archivo real con la extensión y verificar si son reproducibles mi.De este modo:

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

} 
+0

Incluí esta línea de código junto con el código anterior, resuelve mi problema, 'NSString * slink = [_filePath stringByAppendingPathExtension: @ "mp4"]; ' – iNasir

+0

Básicamente, por encima de código convierte el sin extensión "miNombreArchivo" a algo así " myfilename.mp4" y "myfilename.m4v" y "myfilename.3gpp" y" myfilename.3gpp2 "y así sucesivamente. Todos estos enlaces simbólicos creados pueden estar en el mismo directorio o directorio diferente. – iNasir

0

WebKit manejar esto por una opción AVURLAsset privada: AVURLAssetOutOfBandMIMETypeKey, esta opción se utiliza cuando se especifica un tipo MIME en la etiqueta del HTML video,

Se puede usar esta opción como:

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

Dado que es una clave privada, es posible que desee ocultar que si va a enviarlo al AppStore.

La fuente WebKit se puede encontrar aquí: https://opensource.apple.com/source/WebCore/WebCore-7604.1.38.1.6/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm.auto.html

Cuestiones relacionadas