Bạn có thể gửi các tiêu đề được gửi bởi máy chủ cả có và không có kịch bản PHP? Tôi tự hỏi nếu kịch bản PHP đang gửi một khác nhau Content-Type
hơn phục vụ các tập tin bình thường. Bạn cũng cần phải chỉ định thuộc tính type
trên các yếu tố source
, do đó trình duyệt không phải tải xuống cả hai clip để xác định xem nó có thể phát chúng hay không.
Tôi không thể tạo lại sự cố của bạn. Tôi đã cố gắng tạo lại sự cố trong Safari 4.0.4 và WebKit hiện tại hàng đêm, với following test page. Tôi chỉ đơn giản là sử dụng mod_rewrite để gửi đến các định dạng khác nhau dựa trên một tham số thay vì PHP, nhưng tôi không nghĩ rằng nên tạo sự khác biệt, trừ khi bằng cách nào đó PHP đang sửa đổi tệp.
<!DOCTYPE html>
<title>Auido test</title>
<audio controls autobuffer>
<source src="gnossienne-no-1?foo=bar&format=.mp4">
<source src="gnossienne-no-1?foo=bar&format=.ogg">
</audio>
Bạn có thể thử ví dụ của tôi và cho tôi biết nếu nó phù hợp với bạn không?
chỉnh sửa Ah. Sau khi poking xung quanh nó nhiều hơn một chút, có vẻ như vấn đề là do một cách kỳ lạ mà các yếu tố <audio>
trong Safari cư xử trong cố gắng để xác định kích thước của nội dung.
Dưới đây là một đoạn trích từ gói chụp Safari khi gặp phải phần tử <audio>
trỏ đến tệp được phân phối trực tiếp từ Apache. Như bạn có thể thấy, trước tiên, nó cố gắng tìm nạp hai byte đầu tiên của phương tiện, có lẽ vì vậy nó có thể nhận được một Content-Length back, và có thể các header khác. Sau đó nó cố gắng tìm kiếm toàn bộ. Sau đó, không thể giải thích, nó cố gắng lấy lại hai byte đầu tiên một lần nữa, nhưng chuyển các tiêu đề bộ nhớ đệm thích hợp để nhận được phản hồi "304 không được sửa đổi".Và cuối cùng, vẫn không thể giải thích, nó lấy lại 3440 byte cuối cùng của tập tin trên một lần nữa. Nó thực hiện tất cả những điều này trong các kết nối TCP riêng biệt, bổ sung thêm chi phí đáng kể, ngoài việc nạp dữ liệu một vài lần.
GET /stackoverflow/audio-test/say-noid3?foo=bar&format=.mp3 HTTP/1.1
Host: ephemera.continuation.org
Range: bytes=0-1
Connection: close
User-Agent: Apple Mac OS X v10.6.2 CoreMedia v1.0.0.10C540
Accept: */*
Accept-Encoding: identity
Cookie: [redacted]
HTTP/1.1 206 Partial Content
Date: Tue, 05 Jan 2010 02:12:48 GMT
Server: Apache
Last-Modified: Tue, 05 Jan 2010 02:02:08 GMT
ETag: "b2a80ad-11f6-47c6139aaa800"
Accept-Ranges: bytes
Content-Length: 2
Content-Range: bytes 0-1/4598
Connection: close
Content-Type: audio/mpeg
# 2 bytes of data
GET /stackoverflow/audio-test/say-noid3?foo=bar&format=.mp3 HTTP/1.1
Host: ephemera.continuation.org
Range: bytes=0-4597
Connection: close
User-Agent: Apple Mac OS X v10.6.2 CoreMedia v1.0.0.10C540
Accept: */*
Accept-Encoding: identity
Cookie: [redacted]
HTTP/1.1 206 Partial Content
Date: Tue, 05 Jan 2010 02:12:48 GMT
Server: Apache
Last-Modified: Tue, 05 Jan 2010 02:02:08 GMT
ETag: "b2a80ad-11f6-47c6139aaa800"
Accept-Ranges: bytes
Content-Length: 4598
Content-Range: bytes 0-4597/4598
Connection: close
Content-Type: audio/mpeg
# 4598 bytes of data
GET /stackoverflow/audio-test/say-noid3?foo=bar&format=.mp3 HTTP/1.1
Host: ephemera.continuation.org
Range: bytes=0-1
Connection: close
User-Agent: Apple Mac OS X v10.6.2 CoreMedia v1.0.0.10C540
Accept: */*
Accept-Encoding: identity
Cookie: [redacted]
If-None-Match: "b2a80ad-11f6-47c6139aaa800"
If-Modified-Since: Tue, 05 Jan 2010 02:02:08 GMT
HTTP/1.1 304 Not Modified
Date: Tue, 05 Jan 2010 02:12:49 GMT
Server: Apache
Connection: close
ETag: "b2a80ad-11f6-47c6139aaa800"
# no data
GET /stackoverflow/audio-test/say-noid3?foo=bar&format=.mp3 HTTP/1.1
Host: ephemera.continuation.org
Range: bytes=1158-4597
Connection: close
User-Agent: Apple Mac OS X v10.6.2 CoreMedia v1.0.0.10C540
Accept: */*
Accept-Encoding: identity
Cookie: [redacted]
HTTP/1.1 206 Partial Content
Date: Tue, 05 Jan 2010 02:12:49 GMT
Server: Apache
Last-Modified: Tue, 05 Jan 2010 02:02:08 GMT
ETag: "b2a80ad-11f6-47c6139aaa800"
Accept-Ranges: bytes
Content-Length: 3440
Content-Range: bytes 1158-4597/4598
Connection: close
Content-Type: audio/mpeg
# 3440 bytes of data
Nhưng dù sao, về cách giao dịch với đầu ra của tập lệnh PHP của bạn. Ở đây, Safari lại cố gắng tải xuống hai byte đầu tiên, nhưng tập lệnh của bạn bỏ qua yêu cầu Range
và trả về toàn bộ. Rõ ràng, WebKit không thích điều đó, và vì vậy nó cố gắng một lần nữa, mà không có yêu cầu Range
. Một lần nữa, kịch bản của bạn gửi toàn bộ nội dung. Safari hiện đang thử lại một lần nữa, thêm tiêu đề Icy-Metadata
, cho biết nó cho rằng nó đang tải xuống luồng và muốn gửi siêu dữ liệu trực tuyến. Cuối cùng nó chấp nhận đầu ra của nó và phần tử <audio>
có thể phát.
GET /say.php?text=this%20is%20a%20test&format=.mp3 HTTP/1.1
Host: tts.mindtrove.info
Range: bytes=0-1
Connection: close
User-Agent: Apple Mac OS X v10.6.2 CoreMedia v1.0.0.10C540
Accept: */*
Accept-Encoding: identity
HTTP/1.1 200 OK
Date: Tue, 05 Jan 2010 02:14:28 GMT
Server: Apache
X-Powered-By: PHP/5.2.10
Content-Length: 4598
Connection: close
Content-Type: audio/mpeg
# 4598 bytes of data
GET /say.php?text=this%20is%20a%20test&format=.mp3 HTTP/1.1
Host: tts.mindtrove.info
Connection: close
User-Agent: Apple Mac OS X v10.6.2 CoreMedia v1.0.0.10C540
Accept: */*
HTTP/1.1 200 OK
Date: Tue, 05 Jan 2010 02:14:28 GMT
Server: Apache
X-Powered-By: PHP/5.2.10
Content-Length: 4598
Connection: close
Content-Type: audio/mpeg
# 4598 bytes of data
GET /say.php?text=this%20is%20a%20test&format=.mp3 HTTP/1.1
Host: tts.mindtrove.info
Accept: */*
User-Agent: Apple Mac OS X v10.6.2 CoreMedia v1.0.0.10C540
Icy-Metadata: 1
Connection: close
HTTP/1.1 200 OK
Date: Tue, 05 Jan 2010 02:14:28 GMT
Server: Apache
X-Powered-By: PHP/5.2.10
Content-Length: 4598
Connection: close
Content-Type: audio/mpeg
# 4598 bytes of data
Nói tóm lại, có vẻ như Safari (hay chính xác hơn, QuickTime, mà Safari sử dụng để xử lý tất cả các phương tiện truyền thông và tải phương tiện truyền thông) có một cách tiếp cận hoàn toàn braindamaged truyền thông tải về. Một cái gì đó trong cách bạn gửi dữ liệu của bạn trở lại, có lẽ thực tế là bạn không đáp ứng với yêu cầu Range
, làm cho nó nghĩ rằng bạn đang gửi phương tiện truyền thông, khiến nó tải xuống nội dung nhiều lần (mặc dù ngay cả khi đối mặt với một máy chủ trả lời một yêu cầu Range
, nó vẫn thực hiện nhiều yêu cầu hơn so với yêu cầu thực sự).
Lời khuyên của tôi sẽ là cố gắng trả lời phù hợp với yêu cầu Range
; khi cung cấp phương tiện, trình duyệt có thể sẽ sử dụng chúng để cố gắng giảm thiểu băng thông, bằng cách chỉ đệm nhiều như chúng cần để có thể phát qua (mặc dù có thuộc tính autobuffer
cho biết rằng bạn muốn chúng lưu toàn bộ nội dung, trình duyệt có thể bỏ qua điều đó). Tôi khuyên bạn nên sử dụng để cho phép Apache xử lý các yêu cầu về tệp, bộ nhớ đệm và phạm vi, nhưng dường như bạn đang ở trên Dreamhost, chưa cài đặt mod_xsendfile
, vì vậy bạn sẽ phải tự xử lý Range
của riêng mình.
Tôi không chắc liệu bạn có được thông báo về chỉnh sửa hay không, nhưng tôi đã chỉnh sửa câu trả lời của mình để bao gồm trường hợp kiểm tra phù hợp với tôi và dường như phù hợp với những gì bạn đang làm. Bạn có thể kiểm tra xem trường hợp thử nghiệm của tôi có hoạt động cho bạn không? –