2011-07-25 67 views
15

我desperatly试图找到有关于在iOS,Safari浏览器上运行的Web应用程序(如iPad上,iPad2和iPhone 4)的解决方案:HTML 5/QuickTime的音频缓存在Safari浏览器在iOS

这是我前段时间写的一个网络应用程序,它允许用户搜索并收听简短的音乐样本(MP3,全部从〜100 kB到〜1.5 MB)。音频播放器是基于Flash的,因此目前它不适用于iOS设备,我必须在HTML 5或“直接”QuickTime对象中实施替代方案。

我的两个HTML 5和QuickTime的替代品用于iOS设备工作正常,到目前为止,但有一个主要的问题,我不能找到一个解决方案:

与Flash和HTML最多5兼容的浏览器上我的iPad 2上的Windows Safari在加载并播放它们时不会将audiofiles存储在browsercache中 - 既不支持HTML 5音频标签也不支持QuickTime-Object。每次我从服务器加载音频文件进行播放时(使用JavaScript命令,所以不需要更改或重新加载整个页面),它会再次完全下载。

如果用户收听样本A然后收听样本B,则Safari忘记了已经播放样本A并且如果我想再次收听整个MP3,请再次下载整个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"; 
} 

所以每当一首歌曲被加载/播放,我可以通过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> 

的cache.manifest看起来是这样的:

CACHE MANIFEST 

song01.mp3 
song02.mp3 

,并正确地从Apache的返回为“文本/缓存清单“通过将

AddType text/cache-manifest manifest 

添加到此目录的.htaccess。

的Apache的日志清楚地表明,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" 

到目前为止,我什么也没做,只是在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)" 

播放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)" 

再次播放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)" 

播放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)" 

每个文件在播放时都会再次完全下载。因此,“AppleCoreMedia”(无论这可能是什么,我认为由HTML 5音频元素触发的QuickTime插件)无论是无法访问应用程序缓存还是仅仅无法实现其中的文件。因此,如果我现在将iPad切换到“飞行模式”,Safari无法访问/加载/播放这些文件。

我也尝试使用QuickTime的对象,而不是一个HTML 5音频标签的(据我所知HTML 5音频和视频在Safari总是使用QuickTime?),并与像控制它:

document.movie1.SetURL('song02.mp3'); 

没有什么变化,就像使用HTML 5音频一样,加载/播放时再次下载所有内容。

而且,即使这会在那里工作还是会出现一个问题:

正确实现,我将不得不玩它之前加载应用程序缓存中的MP3文件。当这样做时,似乎不可能显示“真实”进度:更新后从应用程序缓存中触发的ProgressEvent似乎没有提供关于迄今为止加载的数据的任何信息以及文件的完整大小。这只是“文件1从2”等等,而不是“真正的”进度,我可以确定如下所示:“100 kB的1.2 MB加载”,就像我可以使用音频元素一样。

所有其他类似的Web SQL/Web数据库或本地存储存储方法是没有帮助或者:

我没有看到获取MP3数据到本地存储或网络数据库和/或获取的任何方式它再次发挥它。 HTML 5 Canvas元素有一个toDataURL()函数来生成一个Base64编码表示并将其用于存储 - Audio元素似乎没有这样的东西。

我最后一个真正“脏”的方法是尝试使用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; 

我尝试使用生成的AJAX responseText作为音频源标记中的source-argument。惊喜:它在我的iPad 2上无法在Safari上运行,播放器无法加载“文件”,虽然在Windows上的Chrome中运行良好。可能是Safari/iOS上Base64-URI的大小限制?

并再次:即使这是在的iOS/Safari浏览器的工作,我不知道的方式来确定从AJAX查询一个真正的进步......

我想的最后一件事是不在加载歌曲时替换音频或源标签,但将它们留在DOM结构中时,检查歌曲加载时是否已经存在,如果尚未加载歌曲,只需添加新的音频标签。不起作用... 如果您动态添加多个播放器实例(无论是否使用HTML 5标签或QuickTime对象)而不是“覆盖”它们,Safari会尽快为您加载第一个MP3甚至可以在DOM树中插入新的音频或QuickTime元素 - 甚至不需要在新实例中加载/播放内容!只要不播放或插入其他任何与音频/媒体相关的内容,只要不重新播放文件即可重复播放。顺便说一句:在JavaScript中使用Audio-objects并将它们“保存”到数组中不起作用,或者不会使Safari缓存任何内容。

这会产生大量不必要的流量,并且如果您处于低带宽的蜂窝网络中,则会花费不必要的很长时间!

我这个问题,现在工作了三天,甚至没有来接近解决方案...

任何想法?

+2

+1呈现:)我重新标记它在iPhone上,因为它不是具体的iPad和iPhone的标签被越来越多的人认购。 – Kay

+0

也许这包含一些有趣的链接和信息http://stackoverflow.com/questions/1612116/html5-local-storage-of-audio-element-source-is-it-possible – Kay

+0

肯定一些有趣的花絮在那一个凯,但没有IOS问题的答案。 –

回答

2

我几乎可以肯定,这是由设计,不能被重写; CoreMedia会根据需要有目的地流式传输文件,并在播放器被解雇时将其抛弃而不缓存。这是由于存储空间有限,电池使用时间长等原因造成的,因为绝大多数情况下,您只需载入一个媒体文件,然后多次播放,然后摆脱它。只要内容类型是媒体类型,就会发生。

另一篇文章引用了对PNG中的数据进行编码以使浏览器缓存它的想法,但我没有尝试过。

您可能会尝试将各种音频样本合并到一个文件中,然后传输每个样本的开始/停止时间(基本上是一个索引)。那么你可以在一个音频播放器中加载文件并跳到必要的位置并在指定的时间播放。如果该位置尚未下载,我相信Safari会使用范围标题在文件中向前跳转(但可以根据容器的类型以及容器是否有索引)。

另一种选择是使用可动态播放音频的流媒体服务器。只需让玩家参与流式播放但流式播放静音(正确的协议应该使用最小的带宽播放这种情况),然后请求一个示例触发流媒体服务器播放该示例。不幸的是不理想或非常高效。

0

尝试这个技巧我几周前在Twitter上看到过,但实际上没有时间尝试:添加一个iframe,并将源设置为媒体文件URL。这听起来很奇怪,但它来自一个非常流行的JS家伙鸣叫...

哦,我看到它在这里:How can I autoplay media in iOS >= 4.2.1 Mobile Safari?

防守值得一试

1

如果有人还在外面拉着自己的头发在这个东西(我最近失去了一个周末的话),Safari浏览器在iOS 6有一个Web Audio API。

https://developer.apple.com/technologies/ios6/

+0

你不应该公开讨论iOS的beta版本功能。 – Till

+0

为什么不能?它是Apple.com上的公共信息:“iOS 6上Safari的新功能可让您使用Web Audio API为交互式Web应用程序创建音频”。这是一个好消息,我实际上是用HTML 5制作儿童游戏,而且我在遇到落后的声音时遇到了麻烦。 – SondreB