что-то маловато кода, можешь портировать мой старый PHP класс
<?php
/**
* Downloads videos from [YouTube](https://youtube.com).
*
* @author info@ensostudio.ru
*/
class YouTubeVideo
{
/**
* YouTube video formats and file extensions
*/
public const FORMATS = [
'5' => 'flv',
'6' => 'flv',
'34' => 'flv',
'35' => 'flv',
'18' => 'mp4',
'22' => 'mp4',
'37' => 'mp4',
'38' => 'mp4',
'83' => 'mp4',
'82' => 'mp4',
'85' => 'mp4',
'84' => 'mp4',
'43' => 'webm',
'44' => 'webm',
'45' => 'webm',
'46' => 'webm',
'100' => 'webm',
'101' => 'webm',
'102' => 'webm',
'13' => '3gp',
'17' => '3gp',
'36' => '3gp',
];
/**
* @var string Video ID
*/
protected string $id;
/**
* @var array|false Video data
*/
protected $info;
/**
* @var array|false List of links
*/
protected $links;
/**
* @param string $id the video identifier
* @return void
*/
public function __construct(string $id)
{
$this->id = $id;
}
/**
* Gets information about video.
*
* @return array|false
*/
public function getInfo()
{
if (!isset($this->info)) {
// Loads video data
$curl = curl_init('https://youtube.com/get_video_info?video_id=' . $this->id);
curl_setopt_array(
$curl,
[
CURLOPT_TIMEOUT => 5,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HEADER => false,
]
);
$data = curl_exec($curl);
curl_close($curl);
// Parses data
parse_str($data, $this->info);
if (empty($this->info) || empty($this->info['status']) || $this->info['status'] !== 'ok') {
$this->info = false;
}
}
return $this->info;
}
/**
* Gets direct links to video.
*
* @return array|false
*/
public function getLinks()
{
if (!isset($this->links)) {
$this->links = false;
$info = $this->getInfo();
if ($info !== false) {
$linksMap = explode(',', $info['url_encoded_fmt_stream_map']);
if (!empty($linksMap)) {
$fmtList = explode(',', $info['fmt_list']);
foreach ($linksMap as $key => $link) {
parse_str($link, $parts);
$fmtParts = explode('/', $fmtList[$key], 3);
$ext = static::FORMATS[$parts['itag']];
// Creates array of information about video
$this->links[$ext . '-' . $fmtParts[1]] = [
'ext' => $ext,
'sizes' => $fmtParts[1],
'url' => $parts['url'],
];
}
}
}
}
return $this->links;
}
/**
* Downloads video to local directory.
*
* @param string $format the video format
* @param string $dir the directory to save video
* @param string|null $name the name of video file without extension
* @return void
* @throws InvalidArgumentException
*/
public function load(string $format, string $dir, string $name = null)
{
$links = $this->getLinks();
if ($links === false || !isset($links[$format])) {
throw new InvalidArgumentException("Video in format '$format' not found");
}
// Sets default name of video file
if ($name === null) {
$info = $this->getInfo();
$name = $info === false ? $this->id : $info['title'];
}
$name = preg_replace('/[^-.\w]+/ui', '_', $name);
// Handler of video copy
$file = fopen(realpath($dir) . DIRECTORY_SEPARATOR . $name . '.' . $links[$format]['ext'], 'w');
if ($file) {
$url = $links[$format]['url'] . '&title=' . urlencode($name);
$curl = curl_init($url);
curl_setopt_array(
$curl,
[
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HEADER => false,
CURLOPT_FILE => $file
]
);
curl_exec($curl);
curl_close($curl);
fclose($file);
}
}
}