2011-07-25 25 views
15

Tôi đang cố gắng tìm giải pháp cho ứng dụng web chạy trên iOS-Safari (ví dụ: iPad, iPad2 và iPhone 4):HTML 5/QuickTime bộ nhớ đệm âm thanh trong Safari trên iOS

Đó là một ứng dụng web tôi đã viết một số thời gian trước đây cho phép người dùng tìm kiếm và nghe các mẫu nhạc ngắn (MP3, tất cả từ ~ 100 kB đến ~ 1,5 MB). Trình phát âm thanh dựa trên Flash, vì vậy nó không hoạt động trên các thiết bị iOS vào lúc này và tôi sẽ phải thực hiện một thay thế trong HTML 5 hoặc với đối tượng QuickTime "trực tiếp".

Cả tôi HTML 5 và QuickTime-alternatives dành cho iOS-thiết bị hoạt động tốt cho đến nay, nhưng có một vấn đề lớn tôi không thể tìm thấy một giải pháp cho:

Không giống như Flash và hầu hết các trình duyệt HTML 5 có khả năng trên Windows Safari trên iPad 2 của tôi sẽ không lưu trữ các audiofiles trong browsercache sau khi tải và chơi chúng - không phải với các thẻ âm thanh HTML 5 cũng như với một đối tượng QuickTime. Mỗi khi tôi tải một tập tin âm thanh để phát lại từ máy chủ (với JavaScript-Lệnh, vì vậy mà không thay đổi hoặc tải lại toàn bộ trang), nó sẽ được tải xuống hoàn toàn.

Nếu người dùng nghe mẫu A và sau đó lấy mẫu B, Safari đã quên mất việc đã phát mẫu A và tải xuống toàn bộ MP3 một lần nữa nếu tôi muốn nghe lại. Trên thiết bị di động có dải hẹp có khả năng, hành vi này không nằm trong câu hỏi.

Có cách nào để lưu trữ các tệp audiofiles đã tải xuống bằng HTML 5 hoặc QuickTime trong bộ nhớ cache của Safari để nó nhớ đã tải xuống chúng - như lưu trữ các tệp web "bình thường" như HTML, CSS hoặc hình ảnh JPEG hay Flash lưu trữ các đối tượng như vậy trong bộ nhớ cache cục bộ của nó? Lần đầu tiên tôi cố gắng sử dụng Cache ứng dụng với tệp kê khai - mặc dù đây không thực sự là mục đích dành cho ứng dụng của tôi ... Tôi không có tập hợp tệp tĩnh mà tôi muốn lưu trong bộ nhớ cache hoặc "khả dụng ngoại tuyến" - Tôi chỉ muốn lưu vào bộ nhớ cache các tệp MP3 mà người dùng đã phát.

Nó nên có thể sử dụng một "biểu hiện năng động": Một là được phân tách bởi module Apache PHP và liệt kê các file đã chơi cho đến nay từ một phiên PHP - một cái gì đó như thế này:

session_start(); 

header("Content-Type: text/cache-manifest, charset=UTF-8"); 
echo "CACHE MANIFEST\n"; 
foreach($_SESSION['playedSongs'] as $song) 
{ 
     echo $song."\n"; 
} 

Vì vậy, bất cứ khi nào một bài hát được tải/phát, tôi có thể truy cập phiên PHP bằng AJAX, chèn tên tệp của tệp đã phát và cập nhật thủ công tệp kê khai bằng cách gọi window.applicationCache.update() hoặc .swapCache().

Có hai vấn đề với điều này:

Đầu tiên: Nó không hoạt động. Và tôi thậm chí còn không có được đến mức cố gắng sử dụng một biểu hiện năng động:

<!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> 

Các cache.manifest trông như thế này:

CACHE MANIFEST 

song01.mp3 
song02.mp3 

và được trả về đúng từ Apache như "text/cache-manifest "bằng cách thêm

AddType text/cache-manifest manifest 

vào thư mục .htaccess của thư mục này.

Apache-logs rõ ràng cho thấy Safari (tương ứng "AppleCoreMedia") không quan tâm đến bộ nhớ cache ứng dụng khi nói đến âm thanh-files:

Safari chính nó có vẻ thừa nhận manifest và thực sự preload các tệp:

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" 

Tính đến thời điểm này, tôi không làm gì ngoài việc mở ứng dụng thử nghiệm của mình trong Safari.

song01.mp3 Playing:

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 Playing:

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

Chơi song1.mp3 một lần nữa:

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

Playing song2.mp3 một lần nữa:

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

Mọi tệp đều được tải xuống lại hoàn toàn khi phát. Vì vậy, "AppleCoreMedia" (bất cứ điều gì có thể chính xác, QuickTime-plugin được kích hoạt bởi phần tử âm thanh HTML 5 mà tôi cho là?) Hoặc không có quyền truy cập vào Cache ứng dụng hoặc đơn giản là không nhận ra các tệp trong đó . Vì vậy, nếu tôi chuyển iPad sang "Chế độ trên máy bay" ngay bây giờ, Safari không thể truy cập/tải/phát tệp.

Tôi cũng đã cố gắng sử dụng một QuickTime đối tượng thay vì một HTML 5 âm thanh-tag (như xa như tôi biết HTML 5 âm thanh và video trong Safari luôn luôn sử dụng QuickTime?) Và kiểm soát nó với một cái gì đó như:

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

Không có gì thay đổi, nó giống như sử dụng âm thanh HTML 5 và mọi thứ được tải xuống lại khi tải/phát.

Và thậm chí nếu điều này sẽ làm việc ở đó sẽ vẫn là một vấn đề:

Để thực hiện đúng cách mà tôi sẽ phải tải MP3-file trong Cache ứng dụng trước khi chơi nó. Khi thực hiện điều này, dường như không thể hiển thị tiến trình "thực": ProgressEvent được kích hoạt từ Cache ứng dụng sau khi cập nhật nó dường như không cung cấp bất kỳ thông tin nào về dữ liệu được tải cho đến nay và kích thước đầy đủ của một tệp. Nó chỉ là "File 1 from 2" và vân vân, và không phải là một tiến trình "thực" mà tôi có thể xác định thứ gì đó như: "100 kB của 1,2 MB được tải" như tôi có thể làm với phần tử âm thanh.

Tất cả các lưu trữ các phương pháp khác như Web SQL/Cơ sở dữ liệu Web hoặc lưu trữ địa phương không giúp một trong hai:

tôi không thấy bất cứ cách nào để nhận dữ liệu MP3 vào địa phương lưu trữ hoặc Web Cơ sở dữ liệu và/hoặc nhận được nó ra một lần nữa để chơi nó. Phần tử Canvas 5 của HTML có hàm toDataURL() - để tạo ra một biểu diễn được mã hóa Base64 và sử dụng nó để lưu trữ - phần tử Audio dường như không có bất cứ thứ gì như thế này.

Cách tiếp cận "bẩn" thực sự cuối cùng của tôi là cố gắng tải "MP3" được mã hóa Base64 theo cách thủ công với sự kết hợp của AJAX và PHP: Tập lệnh PHP xuất ra một biểu diễn Base64 của tệp MP3 và được tải bởi AJAX , vì vậy tôi có thể lưu trữ ví dụ đại diện Base64dưới dạng Bộ nhớ cục bộ hoặc trong Cơ sở dữ liệu web:

$infile = 'song01.mp3'; 
$contents = file_get_contents($infile); 
$base64 = base64_encode($contents); 
$audio = 'data:audio/mp3;base64,'.$base64; 
echo $audio; 

Tôi đã thử sử dụng kết quả AJAX kết quả làm đối số nguồn trong thẻ nguồn âm thanh. Suprise: Nó không hoạt động trong Safari trên iPad 2 của tôi, người chơi chỉ không tải được "file", mặc dù nó hoạt động tốt trong Chrome trên Windows. Có thể giới hạn kích thước cho Base64-URI trên Safari/iOS?

Và một lần nữa: Ngay cả nếu điều này đang làm việc trong iOS/Safari Tôi không biết một cách để xác định một tiến bộ thực tế từ một AJAX truy vấn ...

Điều cuối cùng tôi đã nghĩ đến việc không thay thế các thẻ âm thanh hoặc nguồn khi tải một bài hát nhưng để chúng trong cấu trúc DOM, kiểm tra xem nó đã có sẵn khi một bài hát được tải và chỉ thêm một thẻ âm thanh mới nếu bài hát chưa được tải. Không hoạt động ... Nếu bạn thêm nhiều người chơi-thể hiện động (một lần nữa không quan trọng nếu HTML 5 -tags hoặc QuickTime-objects) thay vì "ghi đè" chúng, Safari quên về việc đã tải MP3 đầu tiên ngay khi bạn thậm chí chèn một phần tử âm thanh hoặc QuickTime mới vào cây DOM - bạn thậm chí không phải tải/phát một thứ gì đó trong cá thể mới! Phát lặp lại mà không cần tải lại hoàn toàn tệp chỉ hoạt động miễn là bạn không phát lại hoặc chèn bất kỳ nội dung âm thanh/phương tiện nào khác có liên quan. BTW: Chỉ cần sử dụng các đối tượng Âm thanh trong JavaScript và "lưu" chúng vào một mảng không hoạt động hoặc không làm cho bất kỳ thứ gì trong bộ nhớ cache của Safari.

Điều này tạo ra nhiều lưu lượng truy cập không cần thiết và mất thời gian dài không cần thiết nếu bạn đang ở trong một mạng di động có băng thông thấp!

Tôi đang làm việc trong vấn đề này trong ba ngày ngay bây giờ mà không cần đến gần giải pháp ...

Bất kỳ ý tưởng nào?

+2

+1 để trình bày :) Tôi đã gắn thẻ lại trên iphone vì thẻ iPad và iphone cụ thể không được đăng ký bởi nhiều người hơn. – Kay

+0

Có thể điều này chứa một số liên kết và thông tin thú vị http://stackoverflow.com/questions/1612116/html5-local-storage-of-audio-element-source-is-it-possible – Kay

+0

Chắc chắn một số mẩu tin thú vị trong đó Kay, nhưng không có câu trả lời cho các vấn đề iOS. –

Trả lời

2

Tôi gần như chắc chắn rằng điều này là do thiết kế và không thể bị ghi đè; các công cụ CoreMedia cố ý truyền tải tệp khi cần và ném nó đi mà không cần lưu vào bộ đệm khi trình phát bị loại bỏ. Điều này là do hạn chế lưu trữ, tuổi thọ pin, vv kể từ khi phần lớn thời gian, bạn tải một tập tin phương tiện truyền thông, chơi nó tuy nhiên nhiều lần, sau đó thoát khỏi nó. Bất cứ khi nào loại nội dung là một loại phương tiện truyền thông điều này sẽ xảy ra.

Bài đăng khác đã tham chiếu ý tưởng mã hóa dữ liệu trong PNG để trình duyệt lưu vào bộ nhớ cache, nhưng tôi chưa thử.

Bạn có thể thử hợp nhất các mẫu âm thanh khác nhau thành một tệp rồi truyền thời gian bắt đầu/dừng cho mỗi mẫu (một chỉ mục cơ bản); sau đó bạn có thể tải các tập tin trong một máy nghe nhạc duy nhất và nhảy đến vị trí cần thiết và chơi chỉ trong thời gian quy định. Nếu vị trí đó chưa được tải xuống, tôi tin rằng Safari sẽ sử dụng tiêu đề dải để chuyển tiếp trong tệp (nhưng điều đó có thể phụ thuộc vào chính xác loại vùng chứa nào và liệu vùng chứa có chỉ mục) hay không.

Một giải pháp thay thế khác là sử dụng máy chủ phương tiện truyền trực tuyến có thể phát âm thanh động. Chỉ có luồng phát khi trình phát tương tác nhưng phát trực tuyến im lặng (giao thức phù hợp nên sử dụng băng thông tối thiểu cho trường hợp này), sau đó yêu cầu một mẫu kích hoạt máy chủ phát trực tuyến để phát mẫu đó. Không phải là lý tưởng hoặc đáng tiếc hiệu quả không may.

0

Hãy thử mẹo này tôi đã xem trên twitter của tôi một vài tuần trước nhưng không bao giờ thực sự có thời gian để thử: Thêm khung nội tuyến và đặt nguồn thành URL của tệp phương tiện. Nghe có vẻ kỳ lạ, nhưng nó là từ một tweet JS rất phổ biến ...

Oh và tôi nhìn thấy nó ở đây: How can I autoplay media in iOS >= 4.2.1 Mobile Safari?

Def giá trị một thử

1

Trong trường hợp bất cứ ai vẫn còn kéo tóc của họ ra trên công cụ này (tôi đã mất một ngày cuối tuần để nó gần đây), Safari trên iOS 6 có API âm thanh trên web.

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

+0

Bạn không nên thảo luận về các tính năng phát hành beta của iOS ở nơi công cộng. – Till

+0

Tại sao không? Đó là thông tin công khai trên Apple.com: "Các tính năng mới trong Safari trên iOS 6 cho phép bạn tạo âm thanh cho các ứng dụng web tương tác bằng API âm thanh web". Đây là tin tốt, tôi thực sự đang xây dựng trò chơi cho trẻ em trong HTML 5 dành cho iPad và tôi đang gặp sự cố với âm thanh bị trễ. – SondreB

Các vấn đề liên quan