Advertisement
anonymous0n

Record YouTube streams

Jul 22nd, 2019
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 5.05 KB | None | 0 0
  1. INSTALLATION (Windows)
  2. 1. Install streamlink: https://streamlink.github.io/install.html#windows-binaries
  3. 2. Install PHP 7 and make sure .php files are opened by php.exe. If you don't know what you're doing, XAMPP should install everything properly: https://www.apachefriends.org/download.html
  4. 3. Copy the code below into a file named whatever.php in notepad. Adjust the first two lines ($dir and $format) to specify the directory to save files and the default format.
  5.  
  6. USAGE
  7. 4. Run whatever.php, paste the video URL in the command line that opens and press enter. It will start recording to the directory you specified.
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18. <?php
  19. $dir = 'C:/Users/K/Videos'; # directory to save video
  20. $format = '720p'; # default format
  21.  
  22. echo 'Enter URL: ';
  23. $url = trim(fgets(STDIN));
  24. $args = explode(' ', $url);
  25. $url = explode('&', $args[0])[0]; # Remove stuff after &
  26. /* There are a few arguments that you can optionally add after the URL (no hyphens):
  27.    480/720/1080 : Choose a non-default format.
  28.    c (current) : Instead of recording from the beginning of the stream, record from the live time.
  29.    p (play) : Open the video in VLC.
  30.    q (quick) : Use an ugly filename instead of spending a second fetching the meta info.
  31.    For example, you could type:
  32.      https://www.youtube.com/watch?v=sEYzlLfLn-Y 1080 q p
  33.    To record that video in 1080p, play it in VLC and use an ugly filename.
  34. */
  35.  
  36. # If the URL is a /channel/.../live style URL, get the video URL.
  37. if(strpos($url, '/live') !== false) {
  38.     $page = file_get_contents($url);
  39.     preg_match('!"video_id":"(.*?)"!', $page, $matches);
  40.     if(empty($matches[1])) {
  41.         exit("Could not get real video URL.\n");
  42.     }
  43.     $url = 'https://www.youtube.com/watch?v=' . $matches[1];
  44. }
  45.  
  46. # Format: 480, 720 or 1080
  47. foreach(array('480', '720', '1080') as $option) {
  48.     if(in_array($option, $args)) {
  49.         $format = $option . 'p';
  50.     }
  51. }
  52.  
  53. # Play in VLC only if "play" or "p" is present in the arguments
  54. $play = 'output';
  55. if(in_array('play', $args) || in_array('p', $args)) {
  56.     $play = 'record';
  57. }
  58.  
  59. # Start from the beginning of the stream by default, unless "current" or "c" is present
  60. $hls = '--hls-live-restart';
  61. if(in_array('current', $args) || in_array('c', $args)) {
  62.     $hls = '';
  63. }
  64.  
  65. # Get video title and author.
  66. function get_meta_info($url) {
  67.     # Alternative: https://www.youtube.com/oembed?url=https://www.youtube.com/watch?v=lUOhCtXPN40&format=json
  68.     $info = json_decode(file_get_contents('https://noembed.com/embed?url=' . urlencode($url)), true);
  69.     $return = array();
  70.     if( ! empty($info['title'])) {
  71.         $return['title'] = $info['title'];
  72.         $return['author'] = $info['author_name'];
  73.     }
  74.     else if(isset($info['error']) && $info['error'] == '401 Unauthorized') {
  75.         # Embedding disabled. Fetch the info through a slightly slower method.
  76.         $page = file_get_contents($url);
  77.         preg_match('!"title":"(.*?)"!', $page, $matches);
  78.         if( ! empty($matches[1])) {
  79.             $return['title'] = stripslashes($matches[1]);
  80.             preg_match('!"author":"(.*?)"!', $page, $matches);
  81.             $return['author'] = stripslashes($matches[1]);
  82.         }
  83.     }
  84.     return $return;
  85. }
  86.  
  87. # Fetch full title for filename if "quick" and "q" are not present
  88. $code = explode('=', $url)[1];
  89. $title = date('Y-m-d H.i.s') . ' ' . $code;
  90. if( ! in_array('quick', $args) && ! in_array('q', $args)) {
  91.     $info = get_meta_info($url);
  92.     if(empty($info)) {
  93.         echo "Failed to fetch info.\n";
  94.     } else {
  95.         echo "Retrieved meta info.\n";
  96.         $video_title = $info['title'];
  97.         $video_author = $info['author'];
  98.         $title = date('Y-m-d') . ' - ' . $video_author . ' - ' . $video_title . ' - ' . $code;
  99.         # Replace characters not allowed in filenames
  100.         $find = array(
  101.             '/',
  102.             '<',
  103.             '>',
  104.             ':',
  105.             '\\',
  106.             '|',
  107.             '?',
  108.             '*'
  109.         );
  110.         $replace = array(
  111.             '/',
  112.             '<',
  113.             '>',
  114.             ':',
  115.             '/',
  116.             '|',
  117.             '?',
  118.             '*'
  119.         );
  120.         $title = str_replace($find, $replace, $title);
  121.        
  122.         if(file_exists($dir . '/' . $title . '.mp4')) {
  123.             $title .= ' (' . date('H.i.s') . ')';
  124.         }
  125.     }
  126. }
  127.  
  128. while(true) {
  129.     echo "Attempting to start recording.\n";
  130.     $response = exec('streamlink ' . $url . ' ' . $format . ' ' . $hls . ' --' . $play . ' "' . $dir . '/' . $title . '.mp4"');
  131.    
  132.     # If stream hasn't started, sleep until its scheduled time. After that, reattempt every 10 seconds.
  133.     if(strpos($response, 'error: No playable streams found') !== false) {
  134.         if( ! isset($start_time)) {
  135.             $json = json_decode(file_get_contents('https://www.youtube.com/heartbeat?video_id=' . $code), true);
  136.             if(isset($json['liveStreamability']['liveStreamabilityRenderer']['offlineSlate']['liveStreamOfflineSlateRenderer']['scheduledStartTime'])) {
  137.                 $start_time = (int) $json['liveStreamability']['liveStreamabilityRenderer']['offlineSlate']['liveStreamOfflineSlateRenderer']['scheduledStartTime'];
  138.             } else {
  139.                 echo "Start timestamp not found.\n";
  140.                 break;
  141.             }
  142.         }
  143.         if(time() > $start_time) {
  144.             $start_time = time() + 10;
  145.         }
  146.         $remaining = $start_time - time();
  147.         echo "Waiting " . $remaining . " seconds...\n";
  148.         time_sleep_until($start_time);
  149.     }
  150.     else {
  151.         # Stream finished.
  152.         break;
  153.     }
  154. }
  155.  
  156. sleep(5);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement