Я отчаянно пытаюсь найти решение для веб-приложения, которое должно запускаться на iOS-Safari (например, на iPad, iPad2 и iPhone 4):
Это веб-приложение, которое я написал некоторое время назад, которое позволяет пользователю искать и прослушивать короткие музыкальные сэмплы (MP3, все от ~ 100 кБ до ~ 1,5 МБ). Звуковой проигрыватель основан на Flash, поэтому он не работает на iOS-устройствах в данный момент, и мне придется реализовать альтернативу либо в HTML 5, либо с помощью "прямого" объекта QuickTime.
Оба моих HTML 5- и QuickTime-альтернативы для iOS-устройств работают до сих пор, но есть одна серьезная проблема, с которой я не могу найти решение:
В отличие от Flash, и большинство браузеров с поддержкой HTML 5 в Safari на моем iPad 2 не будут хранить аудиофайлы в браузерах после загрузки и воспроизведения их - ни с аудио-тегами HTML 5, ни с QuickTime-Object. Каждый раз, когда я загружаю аудиофайл для воспроизведения с сервера (с помощью JavaScript-команд, поэтому без изменения или перезагрузки всей страницы), он полностью загружается.
Если пользователь прослушивает образец A, а затем образец B, Safari забыл о том, что сыграл образец A, и снова загружает весь MP3, если мне нравится его слушать снова. На мобильном устройстве с потенциально узкой полосой с таким поведением не может быть и речи.
Есть ли способ сохранить загруженные аудиофайлы, открытые HTML 5 или QuickTime в кеше Safari, чтобы он помнил, что уже загрузил их - например, он кэширует обычные "веб файлы", такие как HTML, CSS или JPEG-изображения, или как Flash-магазины такие объекты в локальном кеше?
Моя первая попытка заключалась в попытке использовать кэш приложений с файлом манифеста - хотя это не является целью для моего приложения... У меня нет статического набора файлов, которые я хочу использовать в кешировании или "доступный в автономном режиме" - я просто хочу кэшировать MP3 файлы, которые пользователь еще играл.
Должно быть возможно использовать "динамический манифест": один, который анализируется модулем Apache PHP и перечисляет файлы, которые были воспроизведены до сих пор из сеанса PHP - примерно так:
session_start();
header("Content-Type: text/cache-manifest, charset=UTF-8");
echo "CACHE MANIFEST\n";
foreach($_SESSION['playedSongs'] as $song)
{
echo $song."\n";
}
Поэтому всякий раз, когда песня загружается/воспроизводится, я могу получить доступ к сеансу PHP с помощью AJAX, вставить имя файла воспроизводимого файла и вручную обновить манифест, вызывая window.applicationCache.update() или .swapCache().
Есть две проблемы с этим:
Прежде всего: он не работает. И я даже не дошел до того, чтобы использовать динамический манифест:
<!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>
Файл cache.manifest выглядит следующим образом:
CACHE MANIFEST
song01.mp3
song02.mp3
и корректно возвращается из Apache как "text/cache-manifest", добавляя
AddType text/cache-manifest manifest
в .htaccess этого каталога.
Apache-журналы ясно показывают, что Safari (соответственно "AppleCoreMedia" ) не заботится о кеше приложения, когда речь заходит о аудио файлах:
Сафари, похоже, подтверждает манифест и действительно загружает файлы:
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"
До этого момента я ничего не делал, кроме как открыть тестовое приложение в Safari.
Воспроизведение песни01.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:
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)"
Повторное воспроизведение песни1.mp3:
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)"
Повторное воспроизведение песни2.mp3:
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)"
Каждый файл полностью загружается при воспроизведении. Итак, "AppleCoreMedia" (что бы это ни было, плагин QuickTime, который запускается аудио-элементом HTML 5, я полагаю?) Либо не имеет доступа к кэшу приложений, либо просто не понимает файлы в нем, Поэтому, если теперь я переключу iPad на "Режим полета", Safari не сможет получить доступ/загрузить/воспроизвести файлы.
Я также попытался использовать объект QuickTime вместо аудиотекста HTML 5 (насколько я знаю, что аудио и видео HTML 5 в Safari всегда используют QuickTime?) и управляя им чем-то вроде:
document.movie1.SetURL('song02.mp3');
Ничего не меняется, это похоже на использование аудио HTML 5, и все загружается снова при загрузке/воспроизведении.
И даже если это будет работать, все равно будет проблема:
Чтобы правильно реализовать это, мне пришлось бы загрузить MP3 файл в кэш приложения, прежде чем играть в него. При этом кажется невозможным показать "реальный" прогресс: ProgressEvent, который запускается из кэша приложений после его обновления, похоже, не предоставляет никакой информации о загруженных данных до сих пор и о полном размере файла. Это просто "Файл 1 из 2" и т.д., А не "реальный" прогресс, когда я мог бы определить что-то вроде: "100 кБ 1,2 МБ загружен", как я могу сделать с аудиоэлементом.
Все другие подходы к хранению, такие как Web SQL/Web Database или Local Storage, также не помогают:
Я не вижу способа получить данные MP3 в локальном хранилище или в веб-базе данных и/или снова получить его, чтобы воспроизвести его. Элемент Canvas HTML 5 имеет функцию toDataURL(), чтобы создать представление с кодировкой Base64 и использовать его для хранения. Элемент Audio не имеет ничего подобного.
Мой последний действительно "грязный" подход пытался загрузить "вручную" Base64-encoded-MP3 с помощью комбинации AJAX и PHP: PHP- script выводит Base64-представление MP3 файла и загружается AJAX, поэтому я мог бы хранить представление Base64, например как локальное хранилище или в веб-базе данных:
$infile = 'song01.mp3';
$contents = file_get_contents($infile);
$base64 = base64_encode($contents);
$audio = 'data:audio/mp3;base64,'.$base64;
echo $audio;
Я попытался использовать результирующий AJAX responseText в качестве аргумента source в теге audio-source. Suprise: он не работает в Safari на моем iPad 2, плеер просто не загружает "файл", хотя это отлично работает в Chrome на Windows. Возможно ограничение размера для Base64-URI на Safari/iOS?
И снова: даже если это работало в iOS/Safari, я не знаю, как определить реальный прогресс из AJAX-запроса...
Последнее, о чем я думал, не заменяет аудио- или исходные теги при загрузке песни, а оставляет их в DOM-структуре, проверяет, есть ли она там, когда песня загружена, и просто добавьте новый аудио- если песня еще не загружена. Не работает... Если вы добавляете несколько экземпляров игроков динамически (опять же, независимо от того, есть ли HTML 5-тэги или объекты QuickTime) вместо "перезаписывания", Safari забывает, что когда-либо загружал первый MP3, как только вы даже вставляете новый аудио- или QuickTime -Element в дереве DOM - вам даже не нужно загружать/воспроизводить что-то в новом экземпляре! Повторное воспроизведение без полной перезагрузки файла работает до тех пор, пока вы не воспроизводите или не добавляете какие-либо другие аудио/медиа. BTW: Просто использование аудио-объектов в JavaScript и "сохранение" их в массив не работает либо/не делает кэш Safari ничего.
Это создает много ненужного трафика и занимает ненужное долгое время, если вы находитесь в сотовой сети с низкой пропускной способностью!
Я работаю над этой проблемой уже три дня, даже не приближаясь к решению...
Любые идеи?