Skip to content

Instantly share code, notes, and snippets.

@FirePanther
Last active November 17, 2016 04:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FirePanther/b43549ef07efca4d0ebdaddeca5482d3 to your computer and use it in GitHub Desktop.
Save FirePanther/b43549ef07efca4d0ebdaddeca5482d3 to your computer and use it in GitHub Desktop.
download all youtube videos of channels
<?php
/**
* @author FirePanther (http://suat.be)
* @copyright DevMe (http://devme.de)
* @description youtube.php: Download all videos of channels
* @date 17/04/16
* @dependencies - youtube-dl (same location): https://yt-dl.org/downloads/2016.04.13/youtube-dl
* - brew: AtomicParsley, coreutils (gtouch, gecho)
*/
date_default_timezone_set('Europe/Berlin');
define('API_KEY', '...');
$channels = [
'Vsauce' => 'UC6nSFpj9HTCZ5t-N3Rm3-HA',
'Kurzgesagt – In a Nutshell' => 'UCsXVk37bltHxD1rDPwtNM8Q',
'Vsauce2' => 'UCqmugCqELzhIMNYnsjScXXw',
'Vsauce3' => 'UCwmFOfFuvRPI112vR5DNnrA'
];
$pls = getChannelUploadsId(array_values($channels));
foreach ($pls as $pl) {
$items = getPlaylistVideos($pl);
$itemsNum = count($items);
$i = 0;
foreach ($items as $item) {
if (!$i) echo 'Channel: '.$item['snippet']['channelTitle']."\n";
echo (++$i)." of $itemsNum\n";
echo $item['snippet']['title'].' ('.$item['snippet']['resourceId']['videoId'].'): ';
echo dlVid(
$item['snippet']['channelTitle'],
$item['snippet']['title'],
$item['snippet']['resourceId']['videoId'],
$item['snippet']['publishedAt']
)."\n";
}
}
/**
* Returns an array with the channel id as key and the uploads playlist id
* as value.
*/
function getChannelUploadsId($cIds) {
$a = @json_decode(fgc('https://www.googleapis.com/youtube/v3/channels?part=contentDetails&maxResults='.count($cIds).'&id='.implode(',', $cIds).'&key='.API_KEY), 1);
if (isset($a['items']) && count($a['items'])) {
$items = $a['items'];
$uploads = [];
foreach ($items as $item) {
if (isset($item['contentDetails']['relatedPlaylists']['uploads'])) {
$uploads[$item['id']] = $item['contentDetails']['relatedPlaylists']['uploads'];
}
}
return $uploads;
} else {
return null;
}
}
/**
* Get all items (videos) of a playlist.
*/
function getPlaylistVideos($pl, $page = null) {
$a = @json_decode(fgc('https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&'.($page ? 'pageToken='.$page.'&' : '').'playlistId='.$pl.'&key='.API_KEY), 1);
if (isset($a['nextPageToken'])) {
return array_merge($a['items'], getPlaylistVideos($pl, $a['nextPageToken']));
} else {
return $a['items'];
}
}
/**
* Downloads a single video.
*/
function dlVid($channel, $title, $v, $publishedAt) {
if (!is_dir('cache')) mkdir('cache', 0777);
if (is_file("cache/downloaded-$v")) return 'skip';
$dir = "channels/$channel";
if (!is_dir($dir)) mkdir($dir, 0777, 1);
$filename = "$title.mp4";
$filename = $dir.'/'.str_replace(" ⁄ ⁄ ", " ⁄ ⁄ ", str_replace("/", " ⁄ ", $filename));
$filename = preg_replace_callback('~[^\w\s/!-.]+~', function($m) {
return '\\x'.implode('\\x', str_split(bin2hex($m[0]), 2));
}, $filename);
$filename = escapeshellarg($filename);
exec('./youtube-dl -q --no-call-home --recode-video mp4 --embed-subs '.
' -f bestvideo[ext=mp4]+bestaudio[ext=m4a] '.
'--embed-thumbnail --add-metadata -o '.
'"'.__dir__.'/cache/dl-'.$v.'.%(ext)s" '.
'--exec "/usr/local/bin/gtouch -a -m -d \"'.date('Y-m-d', strtotime($publishedAt)).'\" {} && mv {} \"\$(/usr/local/bin/gecho -e \"'.str_replace("'", '', $filename).'\")\"" "'.$v.'"');
file_put_contents("cache/downloaded-$v", '');
return 'ok';
}
/**
* file_get_contents - cached
*/
function fgc($url, $cache = 1) {
$cs = md5($url);
if ($cache && is_file('cache/'.$cs) && filemtime('cache/'.$cs) < time()+3600*24) {
return file_get_contents('cache/'.$cs);
} else {
$src = file_get_contents($url);
if ($src && $cache) file_put_contents('cache/'.$cs, $src);
return $src;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment