thucnguyenblog logo

Tạo website live stream lại các kênh truyền hình

thucnguyenit35
24/06/2018 - 12:44:00

Với sự phát triển của mạng internet và các thiết bị, việc xem trực tuyến các kênh truyền hình không khó khăn như trước đây nữa. Với số lượng người dùng đông đảo thì các website xem tv trực tuyến luôn phải tìm cách tự bảo vệ mình để tránh bị mất nhiều bandwidth dẫn đến giật lag cho người dùng. Các webdeveloper sẽ không thể nhúng tùy tiện các link live stream này lên website của họ được.

Trong bài viết này mình sẽ trình bày một cách cơ bản để tự tạo cho mình một hệ thống live stream dùng các link live từ các website khác. Những gì mình trình bày dưới đây chỉ là giải pháp kỹ thuật và demo, bạn không thể áp dụng được với tất các các link live stream ở các website khác, và bạn đừng bao giờ nghĩ là bạn sẽ live stream lậu một kênh truyền hình nào đó nhé :).

Demo được thực hiện bằng ngôn ngữ và các công cụ: C#, ASP.NET Webforms, C# Console App, RedisCache for Windows.

Trước hết hãy làm rõ một số khái niệm đã nhé.

- HLS là gì?:

HLS là viết tắt cho Http Live Streaming, một kỹ thuật truyền phát media dựa trên giao thức HTTP do Apple phát triển. Khác với kỹ thuật phát video thông thường, HLS chia tệp tin video (hoặc một luồng live) thành một loạt các file nhỏ. Sau đó, player từ phía trình duyệt sẽ request và phát các file nhỏ liên tiếp nhau, tạo thành một video hoàn chỉnh. HLS hỗ trợ phát stream dưới nhiều dạng chất lượng khác nhau, và player sẽ tự động lựa chọn tốc độ cho phù hợp với băng thông mạng

Video stream sẽ được chia thành các file nhỏ có đuôi mở rộng .ts. Trình duyệt sẽ tải các file .m3u8 để đọc các cấu hình như: đường dẫn các file .ts, duration của các file ts... Link .m3u8 này nếu không được bảo vệ thì các bạn có thể mở bằng 1 số phần mềm như VLC, nhúng vào web thì dùng thư viện jwplayer hoặc videojs,...

Cấu trúc file m3u8 có dạng như sau:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:3308725
#EXT-X-TARGETDURATION:6
#EXTINF:5.480,
http://domain.com/vtv3-mid-3308725.ts
#EXTINF:4.680,
http://domain.com/vtv3-mid-3308726.ts
#EXTINF:5.760,
http://domain.com/vtv3-mid-3308727.ts
#EXTINF:4.000,
http://domain.com/vtv3-mid-3308728.ts
#EXTINF:5.080,
http://domain.com/vtv3-mid-3308729.ts
#EXTINF:5.920,
http://domain.com/vtv3-mid-3308730.ts
#EXTINF:4.520,
http://domain.com/vtv3-mid-3308731.ts

Để ngăn chặn nhúng link này tự do thì họ luôn có cách để bảo vệ, điển hình là chỉ cho phép nhúng trên 1 số domain

Sau đây mình sẽ lấy kênh NinhBinhTV phát trực tiếp trên VTVGo ra làm ví dụ.

URL: http://vtvgo.vn/xem-truc-tuyen-kenh-th-ninh-b%C3%ACnh-183.html

Lấy Link M3u8:

View source của link trên các bạn sẽ tìm được link .m3u8

C# dùng regex để tách lấy link m3u8 này.

 private static string getM3u8Url(string html)
{
string pattern = @"var link = '([^']*\.m3u8)";
var mc = Regex.Match(html, pattern);
return mc.Success ? mc.Groups[1].Value : null;
}

Đọc nội dung file M3u8:

Dùng WebClient để download nội dung file m3u8, vì VTVGo chỉ cho phép nhúng link này vào website của họ nên khi download file này mình cần thêm Origin và Referer

private static string webOrigin = "http://vtvgo.vn";
private static string webReferer = "http://vtvgo.vn/trang-chu.html";

Như đã nói ở phía trên, file m3u8 có chứa link đến các file .ts, chúng ta sẽ download hết các file .ts này về dưới dạng bytes array, chuyển sang base64 rồi lưu vào redis với key chính là tên file .ts.

Nội dung file m3u8 chúng ta cũng sẽ lưu và redis. Vì file m3u8 thay đổi theo thời gian, chúng ta sẽ thực hiện việc đọc m3u8 và lưu file .ts này theo tần suất 2s/lần. Rất khó để trình bày các bước rõ ràng nên mình sẽ để source demo ở cuối bài, các bạn download về vọc thêm :).

Chúng ta đã tạo Console app chạy để download file ts và file m3u8. Tiếp theo chúng ta sẽ tạo website để đọc những thứ trong redis ra thôi.

Tạo website live stream:

Chúng ta tạo một website xử lý 2 nhiệm vụ là trả ra content file .m3u8 và content file .ts mà player sẽ yêu cầu.

TS.aspx

protected void Page_Load(object sender, EventArgs e)
{
string file = Page.RouteData.Values["file"].ToString();
if (string.IsNullOrEmpty(file))
{
Response.Clear();
Response.StatusCode = 404;
Response.ClearContent();
Response.End();
return;
}
var dataStr = RedisCacheService.Instance.Get(file + ".ts").ToString();
if (string.IsNullOrEmpty(dataStr))
{
Response.Clear();
Response.StatusCode = 404;
Response.ClearContent();
Response.End();
return;
}
var data = Convert.FromBase64String(dataStr);
Response.AddHeader("Content-Length", data.Length.ToString());
Response.AddHeader("Content-Type", "video/MP2T");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.BinaryWrite(data);
Response.End();
}

M3U8.aspx

protected void Page_Load(object sender, EventArgs e)
{
Response.ContentType = "application/x-mpegURL";
var listM3u8Str = RedisCacheService.Instance.Get("M3U8_CONTENT") as string;
if (string.IsNullOrEmpty(listM3u8Str))
{
Response.Clear();
Response.StatusCode = 404;
Response.ClearContent();
Response.End();
return;
}
var listM3u8 = JsonConvert.DeserializeObject<List<string>>(listM3u8Str);
if (listM3u8.Count > 0)
Response.Write(listM3u8.First());
else
{
Response.Clear();
Response.StatusCode = 404;
Response.ClearContent();
Response.End();
return;
}
}

 

Cuối cùng, chạy console app để download file .m3u8 và file .ts, hãy đảm bảo console app vẫn đang chạy bình thường

build and run website thôi.

 

Kết quả

Thực hiện hơi phức tạp một chút với FPTPlay

Source cho các bạn vọc nhé:  VTVLive.zip


Tags: hls m3u8
 Author infomation:
Xin chào các bạn! Tôi tên là Thức, tôi sinh ra và lớn lên tại quê hương Yên Mỹ, Yên Mô, Ninh Bình, từ thời Trung học tôi đã yêu thích tin học và công nghệ. Tôi tốt nghiệp ngành Công nghệ thông tin tại Đại học Mở Hà Nội, hiện tại tôi đang là một Web Developer. Tôi tạo ra blog này nhằm mục đích chia sẻ kinh nghiệm, kiến thức mà tôi đã trải qua trong cuộc sống, vì thế sẽ có thể thiếu sót mong các bạn đóng góp để giúp tôi hoàn thiện hơn.
 Share:

 Related Post