PHP: iPad no reproduce videos MP4 entregados por PHP, pero si se accede directamente lo hace

Intento encontrar una solución para este problema desde hace algunos días, probé todos los consejos que pude encontrar aquí en stackoverflow y en otras plataformas. Y aún así, no hay solución.

Estoy incrustando un video a través de una etiqueta de video HTML5:

 

Intento entregar el archivo de video MP4 por PHP en lugar de vincularlo directamente. Vincular el archivo mp4 directamente funciona y reproduce el archivo!

Pruebas:

  1. el archivo de video: https://github.com/q2apro/videotest-ipad/raw/master/video.mp4 (juega en el iPad)
  2. el archivo de video cargado por PHP con los mismos encabezados: https://github.com/q2apro/videotest-ipad/blob/master/test-headers.php (no se reproduce en el iPad) – Sourcecode
  3. el archivo de video cargado por PHP con rangos de bytes: https://github.com/q2apro/videotest-ipad/blob/master/test-byterange.php (no se reproduce en el iPad) – Sourcecode
  4. el archivo de video cargado por PHP con Byte Ranges (otro script): https://github.com/q2apro/videotest-ipad/blob/master/test-byterange-2.php (no se reproduce en el iPad, alerta “La operación podría no se completa “) – Sourcecode

Notas:

  • todos los enlaces de arriba están accediendo / reproduciendo directamente el archivo de video sin etiqueta de inserción
  • el video funciona en todos los navegadores en Windows (pero no en Safari / Chrome en iPad, probablemente tampoco en el iPhone)

Mi configuración:

  • dispositivo de prueba: iPad iOS 6 (no tengo un Mac, no puedo depurar )
  • iPad con Safari y Chrome (probé ambos navegadores)
  • mi servidor es alojamiento compartido de domainfactory
  • herramienta para la depuración: Firefox 29 Web Developer Console / WIN7

El .htaccess en la carpeta de prueba establece el tipo MIME y Accept-Ranges:

 AddType video/mp4 .mp4  Header set Accept-Ranges "bytes"  

Aunque creé el mismo encabezado (compare las URL de prueba 1. y 2. ), el iPad no está reproduciendo el archivo a través de la solicitud de PHP.

En cambio, siempre obtengo este botón de reproducción atravesado:

ipad golpeado a través del botón de reproducción

Los encabezados de 1. (llamada mp4 directa) :

mp4 llamada directa

Los encabezados de 2. Los mismos encabezados que arriba, pero configurados por PHP (mp4 entregado por PHP):

enter image description here

También intenté leer todo el archivo de video y enviarlo al navegador usando fread () , fpassthru () y file_get_contents () de PHP, pero el iPad siempre muestra el ícono de can not-play.

Mi servidor alojado no proporciona Connection keep-alive, ¿podría ser esto un problema? ¿Es el iPad que interpreta .php diferente de .mp4?

¿Alguien puede ayudarme a salir del dolor? Estoy totalmente atascado.

PD: Lo que intenté considerar:

  • Solicitudes de rango de bytes (206 contenido parcial) 01 02 03
  • correcta encoding de video 04
  • utilizó otros videos codificados mientras probaba
  • desactivado zlib.output_compression en scripts php

ACTUALIZACIÓN: Debug Console

Finalmente obtuve un MAC de un amigo, conecté el iPad, abrí la Debug Console en Safari en la Mac, cargué la página en el iPad y verifiqué los mensajes de error que aparecían en la Mac (por cierto, ¡cuánto más complicado nos podría obligar a desarrollar Apple! …). Para todos los scripts de prueba aparece este error:

 Failed to load resource: Plug-in handled load 

Wow, eso fue difícil!

1. Primer gran problema

Resultó no ser un problema de encoding, sino un problema con el encabezado del contenedor mp4 establecido durante el proceso de conversión de video: el iPad obviamente tiene un problema con los videos MP4 que están preparados para la transmisión progresiva .

Primero descubrí eso en una conversación aquí . Después de convertir un video, siempre utilicé la herramienta MP4 Fast Start para preparar el archivo de video para transmisión progresiva. Esto fue necesario para transmitir el archivo de video al Flash Player en piezas (progresivamente), por lo que no cargó todo el archivo (y el usuario tuvo que esperar).

Con Handbrake hay una configuración similar, llamada Web Optimized . Hace lo mismo:

 Web Optimized Also known as "Fast Start" This places the container header at the start of the file, optimizing it for streaming across the web. 

¡Si habilita esto y convierte su video, el iPad no reproducirá el archivo de video! En cambio, aparece el error “La operación no se pudo completar”.

ipad golpeado a través del botón de reproducción

Eche un vistazo y pruébelo usted mismo: recursos de prueba de video .

2. Segundo problema

En el entorno de producción siempre utilicé PHP para verificar el referer. Como descubrí, el iPad no envía la información del referer. Esto también evita la transmisión y también verá el símbolo can not-play (icono de reproducción atacado).

3. Tercer problema

No pude averiguar por qué, pero el iPad solo acepta la transmisión de video de este script http://ideone.com/NPSlw5

 = $ranges[1]){ break; } // Output the data echo fread($f, $chunkSize); // Flush the buffer immediately @ob_flush(); flush(); } } else { // It's not a range request, output the file anyway header('Content-Length: ' . $size); // Read the file @readfile($path); // and flush the buffer @ob_flush(); flush(); } } die(); ?> 

Espero que esta información ayude a otros a lidiar con el problema.

Actualización: Tres meses más tarde en el entorno de producción, algunos de mis usuarios aún informaron problemas de reproducción. Parece que hay otro problema con Safari. Les aconsejé que usaran Chrome para iPad , esto lo solucionó.

PD: Un par de días de investigación y problemas solo para reproducir un archivo de video que, por cierto, se ejecuta en todos los demás dispositivos. De nuevo, esto me demuestra que Apple tuvo éxito solo por una gran comercialización, no por un gran software.