Hi mọi người,
Cho em hỏi là ở app Back End (em dùng Java Spring) thông thường theo em hiểu là khi expose 1 API để trả về video cho client sử dụng thì quá trình sẽ là :
- Chuyển file video thành mảng byte (byte [])
- Set mảng array vào body của Response
- Set header của Response Content-type = video/mp4.
Em nghĩ đây là cách cơ bản nhất.Nhưng em có search thì em thấy để trả về 1 API video thì cần phải có Response có header liên quan đến Range của video nữa và hình như Spring Webflux có hỗ trợ việc này. Link em xem ạ https://www.youtube.com/watch?v=_PEPaWFs064
- Mọi người cho em hỏi là Range này là gì và nó có tác dụng của nó đối với viêc API trả về video ạ ? (Em nghĩ chắc chắn nó sẽ có ưu điểm gì thì người ta mới dùng nó )?Em thấy nó call API liên tục khi video đang chạy thì có gây sập server ko ạ ?
- Và cho em xin lời khuyên để làm BackEnd trả về API Video như này thì dùng Spring Boot bình thường hay dùng Spring WebFlux sẽ tốt hơn ạ ?
Cảm ơn mọi người!
1. Nếu anh không nhầm thì cái Range này để lấy từng phần của video, bởi vì khi video mà lớn thì nó sẽ tạo ra 1 request rất dài, mà 1 request http sẽ thường có 1 khoảng thời gian timeout, như jetty đang để timeout mặc định đâu đó 60 giây như vậy nếu tốc độ tải chậm nó sẽ gây ra tình trạng video bị interrupt, vậy cần chia nhỏ việc tải file để đảm bảo khả năng download liên tục.
2. Spring WebFlux có vẻ hỗ trợ cho lập trình reactive nhỉ? Vậy thì có vẻ nó không có tác dụng lắm đối với việc tải file này, vì reactive thích hợp cho việc tổng hợp data từ nhiều luồng, đây em chỉ có 1 luồng đọc file và ghi vào output stream mà thôi. Nên em có thể dùng cái gì cũng được, anh nghĩ là như nhau nên em chọn cái gì đơn giản thì làm.
3. Trên thực tế thì ngày nay việc stream video thường dùng các giao thức kiểu hls. Các file media sẽ được cắt thành nhiều phần nhỏ từ đó mà việc đọc file cũng dễ dàng và nhanh chóng hơn.
Anh ơi ! Em có 1 thắc mắc ,em xin phép hỏi anh là khi trả về 1 API Video thì body của response ngoài byte array (1) thì còn là các đối tượng ByteArrayResource,InputStreamResource (2).Sự khác nhau của (1) và (2) cụ thể là như thế nào ạ ? Em có search google rồi mà vẫn ko hiểu ạ.
1. ByteArrayResource là 1 lớp wrap lại 1 mảng byte. Nó thích hợp trong trường hợp em có 1 mảng byte và em cần truyền mảng byte này cho client. Đối với trường hợp download file thì em cũng sẽ không hay dùng cái này, vì nếu đọc cả 1 file rồi biến nó thành byte array rồi mới truyền xuống client nó sẽ gây ra tốn RAM hoặc hết RAM.
2. InputStreamResource là 1 lớp wrap lại 1 inputstream. Nó rất thích hợp trong việc em download file. Nó sẽ không load toàn bộ file lên bộ nhớ, nó sẽ đọc dần dần ví dụ 1024 bytes 1 lần, như vậy nó sẽ giúp em tiết kiệm được RAM và bảo vệ an toàn cho hệ thống.
Vậy từ câu trả lời của anh theo em hiểu là cách tốt nhất trong trường hợp dowload file cũng như trả về video cho cilent hiển thị (như tik tok) thì nên dùng InputStreamResource thay vì trả về thẳng mảng byte hay ByteArrayResource có đúng ko a ?
Đúng rồi em ạ.
Mình nhớ Range là client gửi lên cho server chứ ?
Để giải thích điều này thì nên quay lại lịch sử xem video thời xưa với các định dạng video 1 file duy nhất. (Mp4…)
Thời xưa ví dụ chúng ta đang xem video có tổng dung lượng là 10 phút.
Ví dụ chúng ta đang xem đến phút thứ 1:02 và chúng ta muốn tua nhanh đến phút thứ 9.
Trong trường hợp xấu nhất, client chưa tải hết byte của video hoặc chưa tải được buffer byte đến phút thứ 9. Client sẽ cần chờ 1 khoản thời gian để chờ tải các byte đến phút thứ 9 sau đó mới tiếp túc xem video từ phút thứ 9 được. (Thật tốn thời gian)
Về sau thì người ta đã nghĩ ra ý tưởng hay hơn.
Ví dụ tổng video 10 phút của chúng ta có 10_000 byte.
Khi chúng ta muốn tua nhanh và xem đến phút thứ 9 để xem. Client sẽ tính toán phút thứ 9 thì sẽ ở khoảng byte thứ bao nhiêu sau đó gửi một request mới đến server với key ở Header là Range và value là vị trí của byte.
Với ví dụ trên chúng ta sẽ gửi 1 request mới với Range có value là 9_000. Server sau đó sẽ trả về các byte tiếp theo bắt đầu từ 9_000 đến 10_000.
Hiện tại thì các website video sử dụng HLS khá nhiều, và đa số các website video lớn trên thế giới đang chuyển dần đến hết sử dụng HLS ( HTTP Live Streaming ) bởi các ưu điểm của nó rất tốt cho các ứng dụng video đa quốc gia, Line Streaming …etc…
Cảm ơn anh đã chia sẻ !