Hướng dẫn viết class get link Youtube

Cập nhật: Lượt xem: 1957 [ PHP ]

Hướng dẫn viết class get link download video youtube bằng php, nhanh chóng và đơn giản bằng cách sử dụng API get_video_info của youtube.

Hướng dẫn viết class get link Youtube

Tìm một vòng trên google search thấy có khá nhiều bạn có nhu cầu tìm code lấy link file video từ youtube. Có lẽ là có rất nhiều lý do khác nhau, dù hiện tại đã có quá nhiều công cụ hỗ trợ việc đó như extension Savior trên Cốc Cốc, hoặc phần mềm IDM. Cả hai đều hỗ trợ tốt việc getlink và tải về. Nhưng đó là get từ client, vậy server thì sao ?

Tuy nhiên vẫn còn rất nhiều lý do khác, ví dụ như tạo một trang chia sẻ video cá nhân, bạn có thể thêm chức năng import from Youtube. Sẽ rất hay đúng không. Không nói nhiều về các lý do nữa ta sẽ bắt đầu vào bài viết : get link youtube.

Bài viết ngày hôm nay sẽ hướng dẫn bạn viết một class, tạm gọi là YoutubeDownloader. Class này có chức năng như sau :

  1. Get link download của tất cả các chất lượng mà video có.

API : get_video_info

Youtube hỗ trợ nhiều API để làm việc với video, bạn có thể đọc tại trang tài liệu của họ : , Tuy nhiên để sử dụng các API này đòi hỏi đăng ký application để lấy API Key, và mình cũng không biết rằng hiện tại có API nào hỗ trợ get link trực tiếp của video hay không. Nhưng khi sử dụng các API này bạn sẽ phải bị ràng buộc rất nhiều quy định về sở hữu trí tuệ, bản quyền, …

Bên cạnh các API đó, youtube còn cung cấp một vài API không được mô tả trong trang tài liệu dành cho developer. Trong đó có API mà chúng ta sử dụng : get_video_info. API này cho phép ta lấy khá nhiều thông tin về video. Trong đó có link của các định dạng, chất lượng mà video hỗ trợ.

Vì không có trong trang tài liệu, nên có thể nói API này không được support. Có lẽ cũng sẽ không gặp quá nhiều rắc rối về bản quyền… đó chỉ là suy đoán của mình thôi. Quan trọng là API này hỗ trợ ta lấy link trực tiếp của video mà không phải đăng ký bất cứ gì với youtube.

Bù lại với sự tự do, ta không hề biết gì về những thay đổi trong API này, cũng như không biết các giới hạn, quy định về nó. Không biết gì ngoài một vài thông tin được chia sẻ bởi cộng đồng. Có lẽ đây là API mà player của youtube sử dụng.

Để tránh các trường hợp ngoài ý muốn, bạn cũng nên đọc qua quy định sử dụng API tại  : Terms of Service.

Endpoint

http://www.youtube.com/get_video_info

Tham số

  • video_id : ID của video

Dữ liệu trả về

Dữ liệu được trả về ở dạng text, đã được url encode. Dữ liệu không phải json cũng không phải xml nên hơi khó xử lý một chút. Tuy nhiên có thể sử dụng hàm parse_str để tạo ra các biến từ text này.

Trong mớ dữ liệu này, có một vài thông tin quan trọng mà ta cần :

  • title : Tiêu đề của video.
  • thumbnail_url : Đường dẫn đến file ảnh thumbnail.
  • author : Tên tác giả video.
  • url_encoded_fmt_stream_map : Chứa url của các định dạng video.
  • length_seconds : Thời lượng.

Ưu, nhược điểm

Ưu điểm :

  • Sử dụng đơn giản, không phải đăng ký các thông tin phức tạp
  • Lấy được link trực tiếp của các video

Nhược điểm :

  • Dữ liệu dạng text, không hỗ trợ json, xml
  • Link được get có thể không download được nếu đem link đó cho một người khác sử dụng ở vùng khác với server get link

Giải pháp :

Từ nhược điểm trên, sẽ có một số trường hợp không tải được, là khi bạn muốn tạo dịch vụ get link : bạn getlink và đưa cho người dùng tải, mà người dùng nằm ở những khu vực, quốc gia khác với server, thì có thể sẽ không download được. Mình cũng không thể xác minh được việc này, tuy nhiên có khả năng rất lớn.

Để tránh trường hợp đó, ta phải sử dụng cách download video từ youtube về server, sau đó cho người dùng tải file từ server. Hoặc cả client và server đều sử dụng chung một proxy. Cách này rất tốn tài nguyên. Vì vậy để cân bằng các trường hợp, thì ta nên cung cấp hai link, một link trực tiếp từ youtube, một link gián tiếp thông qua server.

Như cách tốt nhất là đừng cung cấp dịch vụ như vậy, quá vô ích và hao tốn tài nguyên, hiện tại có khá nhiên plugin, extension và phần mềm có thể get link tại client side. Như vậy sẽ không sợ bị khác khu vực, quốc gia.

Ví dụ

Bạn click vào link sau đây, và sẽ tải về một file, file này chính là các dữ liệu về video mà chúng ta cần : Demo URL. Bạn tải về và mở lên bằng trình soạn thảo text.

Class YoutubeDownloader

Class đơn giản, viết theo Singleton Pattern, nhằm phục vụ mục đích tìm hiểu, học tập, code trong này được tham khảo từ project YoutubeDownloader. Bao gồm các phương thức thực hiện các tính năng sau :

  • Lấy link của tất cả các chất lượng mà video hỗ trợ

Get nội dung của API

Ta sử dụng CURL để có tốc độ nhanh hơn:

function curlGet($URL) {
    $ch = curl_init();
    $timeout = 3;
    curl_setopt( $ch , CURLOPT_URL , $URL );
    curl_setopt( $ch , CURLOPT_RETURNTRANSFER , 1 );
    curl_setopt( $ch , CURLOPT_CONNECTTIMEOUT , $timeout );
    $tmp = curl_exec( $ch );
    curl_close( $ch );
    return $tmp;
}

Như đã nói ở phần trước, API get_video_info sẽ trả về các dữ liệu dạng URL Encoded, vì vậy để lấy dữ liệu, ta sử dụng hàm parse_str để chuyển các tham số trong text thành các biến. Về cấu trúc của dữ liệu trả về, bạn có thể xem qua ví dụ ở phần trước.

public function getLink($id)
{
    $API_URL = self::$endpoint . "?&video_id=" . $id;
    $video_info = $this->curlGet($API_URL);
 
    $url_encoded_fmt_stream_map = '';
    parse_str($video_info);
 
    if(isset($url_encoded_fmt_stream_map)){
        $my_formats_array = explode(',',$url_encoded_fmt_stream_map);
    }
    else
    {
        return 'No encoded format stream found.';
    }
    if (count($my_formats_array) == 0) {
        return 'No format stream map found - was the video id correct?';
    }
    $avail_formats[] = '';
    $i = 0;
    $ipbits = $ip = $itag = $sig = $quality = $type = $url = '';
    $expire = time();
    foreach($my_formats_array as $format) {
        parse_str($format);
        $avail_formats[$i]['itag'] = $itag;
        $avail_formats[$i]['quality'] = $quality;
        $type = explode(';',$type);
        $avail_formats[$i]['type'] = $type[0];
        $avail_formats[$i]['url'] = urldecode($url) . '&signature=' . $sig;
        parse_str(urldecode($url));
        $avail_formats[$i]['expires'] = date("G:i:s T", $expire);
        $avail_formats[$i]['ipbits'] = $ipbits;
        $avail_formats[$i]['ip'] = $ip;
        $i++;
    }
    return $avail_formats;
}

Phương thức này trả về một mảng các link trực tiếp đến các file có chất lượng khác nhau mà video hỗ trợ.

Sử dụng

Để sử dụng class bạn gọi nó như sau :

require_once 'YoutbeDownloader.php';
$qualitys = YoutbeDownloader::getInstance()->getLink('ql3cZuSwiE8');
foreach($qualitys as $video)
{
    echo "<a href='" . $video['url'] . "'>" . $video['quality'] . "-" . $video['type'] .  "</a></br>";
}

Ngoài ra, nếu bạn muốn lưu về server, bạn có thể sử dụng hàm file_put_contentsfwrite.

Các class tương tự

  1. Youtube downloader : Bài hướng dẫn này tham khảo nhiều từ project này..

Kết luận

Việc getlink và download video youtube bằng php, chạy trên server này thực sự không thích hợp để làm dịch vụ getlink cho người dùng, Vì hiện tại có quá nhiều phần mềm client-side làm điều đó, các phần mềm này nhanh hơn việc chạy trên serverside nhiều. Hơn nữa trong nhiều trường hợp các link get được nhưng không sử dụng được tại client-side.

Trong bài viết tiếp theo, chúng ta sẽ khắc phục tình trạng trên, bằng cách get thông tin video ngay trên client-side. Ta sẽ sử dụng javascript để request thông tin của video, lấy các link và cho phép người dùng tải về. Như vậy sẽ không gặp phải nhược điểm như get tại server-side.