Tôi muốn truyền phát video đến IPad của mình qua thẻ video HTML5 với tấm thảm5 (5.3.5) trên chương trình phụ trợ. Thông thường, framework serverside thậm chí không nên đóng một vai trò nào trong điều này, nhưng bằng cách nào đó nó cũng vậy.Phát trực tuyến video tới ipad không hoạt động với Tapestry5
Dù sao, hy vọng ai đó ở đây có thể giúp tôi. Hãy ghi nhớ rằng dự án của tôi là rất nhiều mẫu thử nghiệm và những gì tôi mô tả được đơn giản hóa/giảm xuống các phần liên quan. Tôi sẽ rất cảm kích nếu mọi người không đáp ứng với nghĩa vụ bắt buộc "bạn muốn làm điều sai trái" hoặc các nitpicks bảo mật/hiệu suất không liên quan đến vấn đề.
Vì vậy, ở đây nó đi:
Cài đặt
Tôi có một đoạn video lấy từ Apple HTML5 giới thiệu vì vậy tôi biết rằng định dạng không phải là một vấn đề. Tôi có một trang tml "Play" đơn giản chỉ chứa thẻ "video".
Vấn đề
tôi bắt đầu bằng cách thực hiện một RequestFilter để xử lý các yêu cầu từ các điều khiển video bằng cách mở file video tham chiếu và truyền nó cho khách hàng. Đó là cơ bản "nếu đường dẫn bắt đầu với 'tập tin' sau đó sao chép tập tin đầu vào để đáp ứng outputstream". Tính năng này hoạt động rất tốt với Chrome nhưng không hoạt động với Ipad. Tốt thôi, tôi nghĩ, phải là một số tiêu đề tôi đang mất tích vì vậy tôi nhìn vào Apple Showcase một lần nữa và bao gồm cùng một tiêu đề và loại nội dung nhưng không có niềm vui.
Tiếp theo, mặc dù vậy, chúng ta hãy xem điều gì sẽ xảy ra nếu tôi để t5 phân phối tệp. Tôi đã sao chép video vào ngữ cảnh webapp, tắt bộ lọc yêu cầu của tôi và đặt tên tệp đơn giản vào thuộc tính src của video. Tính năng này hoạt động trong Chrome và iPad. Điều đó khiến tôi ngạc nhiên và nhắc tôi xem xét cách xử lý các tệp tĩnh/yêu cầu ngữ cảnh. Vì vậy, đến nay tôi đã chỉ nhận được cho đến nay như để cảm thấy như có hai con đường khác nhau mà tôi đã xác nhận bằng cách chuyển ra hardwired "video src" để một tài sản với một @Path ("bối cảnh:"). Điều này, một lần nữa, hoạt động trên Chrome nhưng không hoạt động trên iPad.
Vì vậy, tôi thực sự bị mất ở đây. Nước bí mật này trong các yêu cầu "bối cảnh đơn giản" nào cho phép nó hoạt động trên IPad? Không có gì đặc biệt xảy ra và đó là cách duy nhất hoạt động. Vấn đề là, tôi có thể không thực sự phục vụ những vids từ bối cảnh webapp của tôi ...
Giải pháp
Vì vậy, nó quay ra rằng có tiêu đề http này được gọi là "Range" và rằng IPad, không giống như Chrome sử dụng với video. Các "bí mật nước sốt" sau đó là xử lý servlet cho yêu cầu tài nguyên tĩnh biết làm thế nào để đối phó với các yêu cầu phạm vi trong khi T5 không. Dưới đây là triển khai tùy chỉnh của tôi:
OutputStream os = response.getOutputStream("video/mp4");
InputStream is = new BufferedInputStream(new FileInputStream(f));
try {
String range = request.getHeader("Range");
if(range != null && !range.equals("bytes=0-")) {
logger.info("Range response _______________________");
String[] ranges = range.split("=")[1].split("-");
int from = Integer.parseInt(ranges[0]);
int to = Integer.parseInt(ranges[1]);
int len = to - from + 1 ;
response.setStatus(206);
response.setHeader("Accept-Ranges", "bytes");
String responseRange = String.format("bytes %d-%d/%d", from, to, f.length());
logger.info("Content-Range:" + responseRange);
response.setHeader("Connection", "close");
response.setHeader("Content-Range", responseRange);
response.setDateHeader("Last-Modified", new Date().getTime());
response.setContentLength(len);
logger.info("length:" + len);
byte[] buf = new byte[4096];
is.skip(from);
while(len != 0) {
int read = is.read(buf, 0, len >= buf.length ? buf.length : len);
if(read != -1) {
os.write(buf, 0, read);
len -= read;
}
}
} else {
response.setStatus(200);
IOUtils.copy(is, os);
}
} finally {
os.close();
is.close();
}
Đây là thông tin hữu ích; không có lý do tại sao Tapestry không thể xử lý điều này tự động bên trong mã xử lý tài sản chuẩn; chúng tôi chỉ không biết rằng nó cần làm. Việc thêm mức thông tin này vào JIRA của chúng tôi là bước đầu tiên. –
Câu trả lời hay. Làm việc như một say mê ngay lập tức. Cảm ơn rất nhiều. –