Estoy desesperadamente tratando de encontrar una solución para una aplicación web que tiene que ejecutarse en un IOS-Safari (por ejemplo, en el iPad, iPad2 y iPhone 4):HTML 5/QuickTime almacenamiento en caché de audio en Safari en iOS
Es una aplicación web que escribí hace algún tiempo que permite al usuario buscar y escuchar muestras de música cortas (MP3, todo desde ~ 100 kB a ~ 1.5 MB). El reproductor de audio está basado en Flash, por lo que no funciona en dispositivos iOS en este momento y tendré que implementar una alternativa en HTML 5 o con un objeto QuickTime "directo".
Tanto mi HTML 5 y QuickTime-alternativas para iOS dispositivos funcionan muy bien hasta ahora, pero hay un gran problema que no puedo encontrar una solución a:
A diferencia de la mayoría de Flash y HTML 5-navegadores capaces de Windows Safari en mi iPad 2 no almacenará los audiofiles en el browsercache después de cargarlos y reproducirlos, ni con etiquetas de audio HTML 5 ni con QuickTime-Object. Cada vez que cargo un archivo de audio para reproducirlo desde el servidor (con Comandos de JavaScript, sin cambiar o volver a cargar toda la página), vuelve a descargarse por completo.
Si un usuario escucha la muestra A y luego muestra B, Safari se olvidó de haber reproducido la muestra A y descarga todo el MP3 nuevamente si me gusta volver a escucharlo. En un dispositivo móvil con un ancho de banda potencialmente estrecho, este comportamiento está fuera de cuestión.
Hay una forma de almacenar audiofilos descargados por HTML 5 o QuickTime en la memoria caché de Safari para que los recuerde haberlos descargado, como en caché los "archivos web" habituales como HTML, CSS o imágenes JPEG, o como Flash almacena tales objetos en su caché local?
Mi primer intento fue tratar de usar el caché de la aplicación con un archivo de manifiesto, aunque este no es realmente el propósito para mi aplicación ... No tengo un conjunto estático de archivos que quiero tener en caché o "disponible sin conexión": solo quiero almacenar en caché los archivos MP3 que el usuario ya ha reproducido.
Debería ser posible utilizar un "manifiesto dinámica": Uno que es analizada por el módulo de Apache PHP y una lista de los archivos reproducidos hasta el momento de una sesión de PHP - algo como esto:
session_start();
header("Content-Type: text/cache-manifest, charset=UTF-8");
echo "CACHE MANIFEST\n";
foreach($_SESSION['playedSongs'] as $song)
{
echo $song."\n";
}
Así que cada vez se carga/reproduce una canción, pude acceder a la sesión de PHP con AJAX, insertar el nombre del archivo reproducido y actualizar manualmente el manifiesto llamando a window.applicationCache.update() o .swapCache().
Hay dos problemas con este:
En primer lugar: No funciona. Y ni siquiera llegar al punto de tratar de utilizar un manifiesto dinámica:
<!DOCTYPE html>
<html manifest="cache.manifest">
<head>
<title>Test</title>
<script type="text/javascript">
function playStuff(id)
{
if(id == 1)
{
window.document.getElementById("audio").innerHTML = '<audio controls preload="automatic" autobuffer><source src="song01.mp3" type="audio/mp3" /></audio>';
}
else if(id == 2)
{
window.document.getElementById("audio").innerHTML = '<audio controls preload="automatic" autobuffer><source src="song02.mp3" type="audio/mp3" /></audio>';
}
}
</script>
</head>
<body>
<div id="audio"></div><br />
<br />
<input type="button" value="playStuff(1)" onclick="playStuff(1)" />
<input type="button" value="playStuff(2)" onclick="playStuff(2)" />
</body>
</html>
El cache.manifest se ve así:
CACHE MANIFEST
song01.mp3
song02.mp3
y se devuelve correctamente desde Apache como "text/cache-manifest "agregando
AddType text/cache-manifest manifest
al .htaccess de este directorio.
Los Apache-logs muestran claramente que el Safari (respectivamente "AppleCoreMedia") no se preocupa por el caché de la aplicación cuando se trata de archivos de audio:
Safari sí parece reconocer el manifiesto y de hecho la precarga archivos:
192.168.0.40 - - [23/Jul/2011:12:45:46 +0200] "GET /websql/index2.html HTTP/1.1" 200 2619 "-" "Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; de-de) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5"
192.168.0.40 - - [23/Jul/2011:12:45:46 +0200] "GET /websql/cache.manifest HTTP/1.1" 200 79 "-" "Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; de-de) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5"
192.168.0.40 - - [23/Jul/2011:12:45:46 +0200] "GET /websql/cache.manifest?%3E HTTP/1.1" 200 79 "-" "Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; de-de) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5"
192.168.0.40 - - [23/Jul/2011:12:45:46 +0200] "GET /websql/song02.mp3 HTTP/1.1" 200 120525 "-" "Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; de-de) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5"
192.168.0.40 - - [23/Jul/2011:12:45:46 +0200] "GET /websql/song01.mp3 HTTP/1.1" 200 120525 "-" "Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; de-de) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5"
Hasta este momento no hice más que abrir mi aplicación de prueba en Safari.
Jugar song01.mp3:
192.168.0.40 - - [23/Jul/2011:12:47:25 +0200] "GET /websql/song01.mp3 HTTP/1.1" 206 2 "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:47:25 +0200] "GET /websql/song01.mp3 HTTP/1.1" 206 120525 "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:47:25 +0200] "GET /websql/song01.mp3 HTTP/1.1" 206 120525 "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:47:25 +0200] "GET /websql/song01.mp3 HTTP/1.1" 304 - "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:47:25 +0200] "GET /websql/song01.mp3 HTTP/1.1" 206 120525 "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:47:29 +0200] "GET /websql/song01.mp3 HTTP/1.1" 304 - "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:47:29 +0200] "GET /websql/song01.mp3 HTTP/1.1" 206 120525 "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
song2.mp3 Jugar:
192.168.0.40 - - [23/Jul/2011:12:48:04 +0200] "GET /websql/song02.mp3 HTTP/1.1" 206 2 "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:48:04 +0200] "GET /websql/song02.mp3 HTTP/1.1" 206 120525 "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:48:04 +0200] "GET /websql/song02.mp3 HTTP/1.1" 206 120525 "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:48:04 +0200] "GET /websql/song02.mp3 HTTP/1.1" 304 - "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:48:04 +0200] "GET /websql/song02.mp3 HTTP/1.1" 206 120525 "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:48:05 +0200] "GET /websql/song02.mp3 HTTP/1.1" 304 - "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:48:05 +0200] "GET /websql/song02.mp3 HTTP/1.1" 206 120525 "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
Jugar song1.mp3 nuevo:
192.168.0.40 - - [23/Jul/2011:12:48:38 +0200] "GET /websql/song01.mp3 HTTP/1.1" 304 - "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:48:38 +0200] "GET /websql/song01.mp3 HTTP/1.1" 206 120525 "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:48:38 +0200] "GET /websql/song01.mp3 HTTP/1.1" 206 120525 "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:48:38 +0200] "GET /websql/song01.mp3 HTTP/1.1" 304 - "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:48:38 +0200] "GET /websql/song01.mp3 HTTP/1.1" 206 120525 "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:48:40 +0200] "GET /websql/song01.mp3 HTTP/1.1" 304 - "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:48:40 +0200] "GET /websql/song01.mp3 HTTP/1.1" 206 120525 "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
Juego song2.mp3 nuevo:
192.168.0.40 - - [23/Jul/2011:12:49:12 +0200] "GET /websql/song02.mp3 HTTP/1.1" 304 - "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:49:12 +0200] "GET /websql/song02.mp3 HTTP/1.1" 206 120525 "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:49:12 +0200] "GET /websql/song02.mp3 HTTP/1.1" 206 120525 "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:49:12 +0200] "GET /websql/song02.mp3 HTTP/1.1" 304 - "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:49:12 +0200] "GET /websql/song02.mp3 HTTP/1.1" 206 120525 "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:49:13 +0200] "GET /websql/song02.mp3 HTTP/1.1" 304 - "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
192.168.0.40 - - [23/Jul/2011:12:49:13 +0200] "GET /websql/song02.mp3 HTTP/1.1" 206 120525 "-" "AppleCoreMedia/1.0.0.8J2 (iPad; U; CPU OS 4_3_3 like Mac OS X; de_de)"
Todos los archivos se vuelven a descargar completamente al reproducirlo. Así que "AppleCoreMedia" (cualquiera que sea esto exactamente, el complemento QuickTime que se desencadena por el elemento de audio HTML 5, supongo?) O bien no tiene acceso a la memoria caché de la aplicación o simplemente no se da cuenta de los archivos en ella . Entonces, si cambio mi iPad a "Modo Avión" ahora, Safari no puede acceder/cargar/reproducir los archivos.
También he intentado usar un QuickTime a objetos en lugar de un audio-etiqueta HTML 5 (por lo que yo sé HTML 5 audio y vídeo en Safari siempre usar QuickTime?) Y controlarlo con algo como:
document.movie1.SetURL('song02.mp3');
Nada cambia, es como usar audio HTML 5 y todo vuelve a descargarse cuando lo carga/reproduce.
E incluso si esto no funciona todavía estaría un problema:
Para aplicar correctamente que iba a tener que cargar el archivo MP3 en el caché de la aplicación antes de reproducirlo. Al hacer esto, parece imposible mostrar un progreso "real": el ProgressEvent que se activa desde la caché de la aplicación después de actualizarlo no parece proporcionar ninguna información sobre los datos cargados hasta el momento y el tamaño completo de un archivo. Es solo "Archivo 1 de 2" y así sucesivamente, y no un progreso "real" donde pude determinar algo así como: "100 kB de 1.2 MB cargados", como puedo hacer con el elemento de audio.
Todos los otros almacenamiento enfoque, tales como Web/Base de datos SQL Web o almacenamiento local no son de ayuda, ya sea:
no veo ninguna manera de conseguir los datos MP3 en almacenamiento o en la web de base de datos local y/o conseguir de nuevo para jugarlo. El elemento Canvas de HTML 5 tiene una función toDataURL() para producir una representación codificada en Base64 y usarla para el almacenamiento: el elemento de audio no parece tener algo como esto.
Mi último enfoque realmente "sucio" fue tratar de cargar MP3 codificados en Base64 "manualmente" con una combinación de AJAX y PHP: Un script PHP genera una representación Base64 de un archivo MP3 y es cargado por AJAX , así que podría almacenar la representación de Base64, por ejemplocomo almacenamiento local o en la base de datos Web:
$infile = 'song01.mp3';
$contents = file_get_contents($infile);
$base64 = base64_encode($contents);
$audio = 'data:audio/mp3;base64,'.$base64;
echo $audio;
He intentado utilizar el AJAX responseText resultante como la fuente de argumento en una fuente-etiquetas de audio. Suprise: No funciona en Safari en mi iPad 2, el reproductor simplemente no carga el "archivo", aunque esto funciona bien en Chrome en Windows. ¿Posiblemente una limitación de tamaño para Base64-URI en Safari/iOS?
Y otra vez: Incluso si esto estaba trabajando en IOS/Safari no sé de una manera de determinar un progreso real a partir de una consulta AJAX ...
La última cosa que estaba pensando no era reemplazando las etiquetas de audio o fuente cuando carga una canción pero dejándolas en la estructura DOM, verifique si ya está allí cuando se cargue una canción y simplemente agregue una nueva etiqueta de audio si todavía no se ha cargado una canción. No funciona ... Si agrega varias instancias de jugador dinámicamente (una vez más, no importa si se trata de etiquetas HTML 5 u objetos QuickTime) en lugar de "sobreescribirlas", Safari se olvida de haber cargado el primer MP3 tan pronto como usted incluso inserte un nuevo elemento de audio o QuickTime en el árbol DOM; ¡ni siquiera tiene que cargar/reproducir algo en la nueva instancia! La reproducción repetida sin la recarga completa del archivo solo funciona siempre que no reproduzca ni inserte nada más relacionado con audio/medios. Por cierto: solo el uso de Audio-objetos en JavaScript y "guardarlos" en una matriz tampoco funciona/no hace que Safari cache nada.
Esto produce mucho tráfico innecesario y toma mucho tiempo innecesario si está en una red celular con un ancho de banda bajo.
estoy trabajando en este problema para los tres días sin ni siquiera acercarse a una solución ...
¿Alguna idea?
+1 para la presentación :) Me reetiquetado que en el iPhone porque no es iPad etiqueta específica y el iPhone está suscrito por más gente. – Kay
Quizás esto contenga algunos enlaces e información interesantes http://stackoverflow.com/questions/1612116/html5-local-storage-of-audio-element-source-is-it-possible – Kay
Definitivamente algunos datos interesantes en ese Kay, pero no hay respuestas para los problemas de IOS. –