Artykuły na każdy temat
[PHP] Ściąganie filmów z YouTube i przerabianie ich na mp3
<?php
// For the purity of conscience
set_time_limit(0);
// Config
$config['user'] = 'MrSuicideSheep';
$config['path']['mp3'] = './mp3/'.$config['user'].'/';
$config['path']['wget'] = 'D:\xampp\htdocs\yt-downloader\wget.exe';
$config['path']['ffmpeg'] = 'D:\xampp\htdocs\yt-downloader\ffmpeg.exe';
// Do what you have to do
$list = get_video_list($config['user']);
// Grab videos
foreach($list as $item)
{
$video_address = get_youtube_video($item[0]);
$video_file = get_temporary_file_name();
$audio_file = get_temporary_file_name();
system($config['path']['wget'].' -O "'.$video_file.'" "'.$video_address.'"', $wget_return);
if($wget_return == 0)
{
// Convert file
system($config['path']['ffmpeg'].' -i "'.$video_file.'" -vn -f mp3 "'.$audio_file.'"', $ffmpeg_return);
if($ffmpeg_return == 0)
{
// Create the file name wihout illegal symbols (Windows rule)
$new_file_name = $config['path']['mp3'].trim(preg_replace('#[\\\\/\:\*\?"<>|]#', '', $item[1])).'.mp3';
// This code is not here for fun
rename($audio_file, $new_file_name);
}
}
if(file_exists($video_file))
{
unlink($video_file);
}
if(file_exists($audio_file))
{
unlink($audio_file);
}
}
// Whatever
echo 'Done!';
function get_video_list($user)
{
for($h = 1; $h <= $how || !$initiated; $h += 50)
{
$list = json_decode(file_get_contents('http://gdata.youtube.com/feeds/api/users/'.$user.'/uploads?v=2&alt=jsonc&max-results=50&start-index='.$h));
if(!$initiated)
{
$how = $list -> data -> totalItems;
$initiated = true;
}
foreach($list -> data -> items as $item)
{
$data[] = array($item -> id, trim($item -> title));
}
}
return $data;
}
function get_youtube_video($video_id)
{
while(1)
{
$ch = curl_init('http://www.youtube.com/get_video_info?video_id='.$video_id);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$video_info = curl_exec($ch);
$headers = curl_getinfo($ch);
curl_close($ch);
if($headers['http_code'] == 200)
{
break;
}
else
{
sleep(1);
}
}
parse_str($video_info);
if($url_encoded_fmt_stream_map)
{
$video_available_formats = explode(',', $url_encoded_fmt_stream_map);
for($h = 0, $how = count($video_available_formats); $h < $how; ++$h)
{
parse_str($video_available_formats[$h]);
$available_formats[$h]['itag'] = $itag;
$available_formats[$h]['url'] = urldecode($url).'&signature='.$sig;
}
// Choose the best format (order by audio bitrate) -> warto rzucić okiem na kilka tabel z sieci odnośnie "YouTube media encoding options"
$format_order = array(141, 38, 37, 22, 46, 45, 102, 101, 172, 84, 85, 120, 35, 44, 34, 43, 100, 140, 171, 82, 83, 18, 6, 5, 139, 36, 17);
for($h = 0, $how = array(count($format_order), count($available_formats)); $h < $how[0]; ++$h)
{
for($i = 0; $i < $how[1]; ++$i)
{
if($format_order[$h] == $available_formats[$i]['itag'])
{
$chosen_format = $i;
break 2;
}
}
}
if(is_int($chosen_format))
{
return $available_formats[$chosen_format]['url'];
}
}
return false;
}
function get_temporary_file_name()
{
return './tmp/'.uniqid().'.tmp';
}
?>
Podobno kanały podlegające VEVO mają specjalną enkrypcje utrudniającą ściąganie. Nie wiem, nie sprawdzałem ale skoro inne serwisy (np. ten wymieniony powyżej) potrafią ściągać z tego typu kanałów to możliwość obejścia jej jest do wykonania. Oczywiście jeżeli chcemy wykorzystać skrypt na Linux'ie to potrzebujemy troszeczkę zmienić "zapytania" obok funkcji system(). wget.exe jak i ffmpeg.exe dostępne są w sieci więc nie będziecie mieli problemów ze znalezieniem ich. Dodatkowo skrypt wymaga dopracowania tj. konwersja nazwy plików tak aby w przypadku napotkania specyficznych znaków nie kończyła się krzakami w nazwie pliku. Tutaj na pomoc przyjdzie funkcja iconv(). Skrypt nie sprawdza czy film jest zablokowany na mocy praw autorskich w określonym kraju (warto dorobić taką funkcjonalność). Ponadto niektóre zwrócone adresy mogą nie działać. Wtedy warto spróbować z kolejnym formatem. Wobec itag'ów warto poszukać po sieci opracowań na ten temat (jak np. takie). wget został wykorzystany chociażby dlatego, że PHP nie radzi sobie ze ściąganiem plików o dużej gramaturze. Dodatkowo itag'i można dobierać także pod innymi kątami np. (extension). Nie jest przypadkiem, że powstała funkcja get_temporary_file_name(). Wynika to z prostego faktu, że tmpfile() i tempnam() nie spełniły moich oczekiwań. Na całe szczęście YouTube nie streamuje filmów w sposób mocno utrudniający pobieranie co bardzo cieszy. Właściwie streamowanie to tylko słowa, bo ze skryptu wszystko wynika Komentarze
Dodaj komentarz