Ce tutoriel a pour but de vous expliquer comment télécharger une ressource (fichier, stream, ...) distante vers votre serveur.
Notre exemple d'application, sera le téléchargement d'une vidéo Youtube.
Ce tutoriel n'est pas encore complet !
cUrl pour effectuer des requêtes HTTP
Pour nos requêtes HTTP, nous allons utiliser la librairie cUrl avec PHP.
Cette librairie nous permet de large possibilité en terme de transfert de données (elle ne fait pas que HTTP !).
A completer...
Classe pour le téléchargement/sauvegarde de ressources (fichiers, vidéos, ...)
Maintenant utilisons cURl dans notre classe pour télécharger des fichiers.
FileDownloader.class.php :
<?php
set_time_limit(0); // pour les long donwload...
class FileDownloader {
protected $DL_DIR = "downloadDir/";
protected function curl_get_contents($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
protected function curl_save_contents($url, $filename) {
if(!file_exists($this->DL_DIR))
mkdir($this->DL_DIR); // création du répertoire si inexistant
$fp = fopen($this->DL_DIR . $filename, "w");
if(FALSE !== $fp) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_exec($ch);
curl_close($ch);
}
else
throw new Exception($this->DL_DIR . $filename . " erreur d'ouverture.");
fclose($fp);
}
}
?>
Classe pour le téléchargement de vidéos Youtube
Cette classe permet de parser une page web de Youtube à la recherche de la vidéo uniquement. Puis il est ensuite possible de télécharger cette vidéo sur votre serveur.
Elle permet aussi de récupérer une vidéos en fonction du format vidéo (mp4, flv, webm, ...) définis dans YouTube.
Elle étends (extends) de FileDownloader pour utiliser les méthodes de récupération de fichiers (avec cUrl dans notre cas).
Voici notre classe (YoutubeDownloader.class.php) :
<?php
require_once("FileDownloader.class.php");
class YoutubeDonwloader extends FileDownloader {
private $_url;
/* Constantes de format video */
const _3GP = "3gp";
const FLV = "flv";
const MP4 = "mp4";
const VIDEO = "flv";
const WEBM = "webm";
private $_video_types = array(
5 => self::FLV,
13 => self::_3GP,
17 => self::MP4,
18 => self::MP4,
22 => self::MP4,
34 => self::FLV,
35 => self::FLV,
37 => self::MP4,
38 => self::VIDEO, /* n'importe quel format */
43 => self::WEBM,
44 => self::WEBM,
45 => self::WEBM
);
public function __construct($url) {
$this->DL_DIR = "ytdl/";
$this->_url = $url;
}
private function checkVideoFormat($format) {
$videos_format = array_values($this->_video_types);
if( in_array($format, $videos_format) )
return true;
return false;
}
public function getVideoInfos() {
$video_infos = array();
$contents = parent::curl_get_contents($this->_url);
if(preg_match('#url_encoded_fmt_stream_map=([^&$]*)#', $contents, $match)) {
foreach( explode(',', urldecode($match[1])) as $url_map) {
if(preg_match('#url=([^;,\"]+).*&itag=(\d+)#', urldecode($url_map), $result)) {
$video_format = isset($this->_video_types[$result[2]]) ? $this->_video_types[$result[2]] : $this->_video_types[38];
$video_url = $result[1];
if(!isset($video_infos[$video_format])) // un lien par format (à revoir, je crois qu'il y a plusieurs qualités par format)
$video_infos[$video_format] = $video_url;
}
}
}
return $video_infos;
}
public function getVideoUrlByFormat($format) {
$url = null;
if( $this->checkVideoFormat($format) ) {
$infos = $this->getVideoInfos();
if( !in_array($format, array_keys($infos)) ) {
throw new Exception("Format non disponible ($format) pour cette video. Formats disponibles : ". implode(', ', array_keys($infos)));
}
$url = $infos[$format];
}
return $url;
}
public function saveVideoByFormat($format, $filename = null) {
$url = $this->getVideoUrlByFormat($format);
if(!is_null($url)) {
parent::curl_save_contents($url, (is_null($filename)) ? "YoutubeDonwloader-".time().".".$format : $filename);
}
}
}
?>
Et on test notre application :
<?php
try {
$ytdl = new YoutubeDonwloader($_GET['url']); // https://www.youtube.com/watch?v=xxxxxxxxxx
//$video_url = $ytdl->getVideoUrlByFormat(YoutubeDonwloader::MP4); // Juste les infos
$ytdl->saveVideoByFormat(YoutubeDonwloader::MP4);
echo "DL => OK".PHP_EOL;
} catch(Exception $ex) {
echo "DL => KO".PHP_EOL;
echo $ex->getMessage().PHP_EOL;
}
?>
Exemple d'utilisation : http://<host>/<script_path>?url=https://www.youtube.com/watch?v=Lcwk0yoerg8
Voilà ! Vous pouvez télécharger les sources ici : http://uptobox.com/ze7yvuu731ht
Si vous avez des suggestions ou remarques n'hésitez pas !