cpw*_*cpw 15 iphone safari audio caching ios
我不顾一切地试图找到一个必须在iOS-Safari(例如iPad,iPad2和iPhone 4)上运行的Web应用程序的解决方案:
这是我前段时间写的一个网络应用程序,它允许用户搜索和收听短音乐样本(MP3,全部从~100 kB到~1.5 MB).音频播放器是基于Flash的,因此它目前无法在iOS设备上运行,我将不得不在HTML 5或"直接"QuickTime对象中实现替代方案.
我的HTML 5和QuickTime替代iOS设备到目前为止工作正常,但有一个主要问题我无法找到解决方案:
与Flash不同,我的iPad 2上的大多数支持HTML 5的浏览器在加载和播放后都不会将audioiofiles存储在browsercache中 - 无论是HTML 5音频标签还是QuickTime-Object.每次我从服务器加载一个音频文件进行播放时(使用JavaScript命令,所以不用更改或重新加载整个页面),它会再次完全下载.
如果用户收听样本A然后收听样本B,Safari忘记播放样本A并再次下载整个MP3,如果我想再次收听它.在具有可能窄带宽的移动设备上,这种行为是不可能的.
有没有办法在Safari的缓存中存储由HTML 5或QuickTime打开的下载的音频文件,因此它记得已经下载了它们 - 就像它缓存了常见的"网络文件",如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";
}
Run Code Online (Sandbox Code Playgroud)
因此,无论何时加载/播放歌曲,我都可以使用AJAX访问PHP会话,插入播放文件的文件名并通过调用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>
Run Code Online (Sandbox Code Playgroud)
cache.manifest看起来像这样:
CACHE MANIFEST
song01.mp3
song02.mp3
Run Code Online (Sandbox Code Playgroud)
并通过添加从Apache正确返回为"text/cache-manifest"
AddType text/cache-manifest manifest
Run Code Online (Sandbox Code Playgroud)
到此目录的.htaccess.
Apache-logs清楚地表明Safari(分别是"AppleCoreMedia")在涉及音频文件时并不关心应用程序缓存:
Safari本身似乎承认清单并确实预加载文件:
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"
Run Code Online (Sandbox Code Playgroud)
到目前为止,我除了在Safari中打开我的测试应用程序外什么也没做.
播放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)"
Run Code Online (Sandbox Code Playgroud)
播放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)"
Run Code Online (Sandbox Code Playgroud)
再次播放song1.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)"
Run Code Online (Sandbox Code Playgroud)
再次播放song2.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)"
Run Code Online (Sandbox Code Playgroud)
播放时,每个文件都会完全再次下载.所以"AppleCoreMedia"(无论这可能是什么,我猜想由HTML 5音频元素触发的QuickTime插件?)要么没有访问应用程序缓存,要么只是没有实现其中的文件.因此,如果我现在将iPad切换到"飞行模式",Safari将无法访问/加载/播放文件.
我还尝试使用QuickTime对象而不是HTML 5音频标签(据我所知,Safari中的HTML 5音频和视频总是使用QuickTime?)并使用以下内容控制它:
document.movie1.SetURL('song02.mp3');
Run Code Online (Sandbox Code Playgroud)
没有什么变化,就像使用HTML 5音频一样,加载/播放时会再次下载所有内容.
即使这样可行仍然存在问题:
为了正确实现,我必须在播放之前在应用程序缓存中加载MP3文件.执行此操作时,似乎无法显示"真正的"进度:更新后从应用程序缓存中触发的ProgressEvent似乎不提供有关目前加载的数据和文件的完整大小的任何信息.它只是"文件1从2"等等,而不是"真正的"进展,我可以确定类似:"100 kB 1.2 MB加载",因为我可以使用音频元素.
所有其他存储方法,如Web SQL/Web数据库或本地存储也没有帮助:
我没有看到任何方法将MP3数据导入本地存储或Web数据库和/或再次将其发送出去.HTML 5 Canvas-element有一个toDataURL()函数来生成Base64编码的表示并将其用于存储 - 音频元素似乎没有这样的东西.
我最后一个真正"脏"的方法是尝试使用AJAX和PHP的组合加载"手动"Base64编码的MP3:PHP脚本输出一个MP3文件的Base64表示并由AJAX加载,所以我可以存储Base64表示,例如本地存储或Web数据库:
$infile = 'song01.mp3';
$contents = file_get_contents($infile);
$base64 = base64_encode($contents);
$audio = 'data:audio/mp3;base64,'.$base64;
echo $audio;
Run Code Online (Sandbox Code Playgroud)
我尝试使用生成的AJAX responseText作为audio-source-tag中的source-argument.惊喜:它在我的iPad 2上的Safari中不起作用,播放器无法加载"文件",尽管这在Windows上的Chrome中运行良好.可能是Safari/iOS上Base64-URI的大小限制?
再说一遍:即使这在iOS/Safari中有效,我也不知道从AJAX查询中确定真正进展的方法......
我想到的最后一件事是在加载歌曲时没有替换音频或源标签,而是将它们保留在DOM结构中,检查加载歌曲时它是否已存在,只需添加一个新的音频标签歌曲尚未加载.不起作用......如果你动态添加多个播放器实例(无论是HTML 5 -tags还是QuickTime-objects),而不是"覆盖"它们,Safari会忘记你偶尔加载第一个MP3在DOM树中插入一个新的音频或QuickTime元素 - 您甚至不必在新实例中加载/播放内容!只要您不播放或插入任何其他音频/媒体相关的内容,重复播放而无需完全重新加载文件.顺便说一句:在JavaScript中使用Audio-objects并将它们"保存"到一个数组中也不起作用/不会使Safari缓存任何东西.
如果您处于带宽较低的蜂窝网络中,这会产生大量不必要的流量,并且会花费不必要的长时间!
我现在正在解决这个问题三天,甚至没有接近解决方案......
有任何想法吗?
我几乎可以肯定这是设计使然,无法被覆盖;CoreMedia 的东西有目的地根据需要流式传输文件,并在播放器关闭时将其丢弃而不缓存它。这是由于存储空间、电池寿命等有限,因为绝大多数时候,您加载一个媒体文件,播放它多次,然后删除它。每当内容类型是媒体类型时就会发生这种情况。
另一篇文章提到了将数据编码为 PNG 以使浏览器缓存它的想法,但我还没有尝试过。
您可以尝试将各种音频样本合并到一个文件中,然后传输每个样本的开始/停止时间(基本上是一个索引);然后您可以将文件加载到单个音频播放器中并跳转到必要的位置并仅播放指定的时间。如果该位置尚未下载,我相信 Safari 将使用范围标头在文件中向前跳转(但这可能取决于容器的类型以及容器是否有索引)。
另一种选择是使用可以动态播放音频的流媒体服务器。只需在播放器参与时让流继续运行,但流式传输保持沉默(在这种情况下,正确的协议应使用最小带宽),然后请求样本触发流式传输服务器播放该样本。不幸的是,这并不理想或非常有效。
| 归档时间: |
|
| 查看次数: |
4298 次 |
| 最近记录: |