Fix youtube thumbnails, add youtube-dl support

This commit is contained in:
Juribiyan 2022-01-03 00:43:52 +05:00
parent 321bf99cf8
commit 3f443cbea5
3 changed files with 154 additions and 77 deletions

View File

@ -155,6 +155,7 @@ if (!$cache_loaded) {
// ---------------------------------- Attachment handling -----------------------------------
$cf['KU_FFMPEGPATH'] = '/usr/local/bin/ffmpeg'; //path to FFMPEG, on windows it's usually 'C:\ffmpeg\bin' (REQUIRED for videos)
$cf['KU_YOUTUBE_APIKEY'] = 'your_api_key'; //Your personal anal probe ID. Can be obtained it Google Dev. Console
$cf['I0_YOUTUBE_DL_PATH'] = ''; // Path to youtube-dl binary. If not empty, youtube-dl will be used instead of default API (in this case you won't need KU_YOUTUBE_APIKEY)
$cf['KU_THUMBWIDTH'] = 200; // Maximum thumbnail width
$cf['KU_THUMBHEIGHT'] = 200; // Maximum thumbnail height
$cf['KU_REPLYTHUMBWIDTH'] = 125; // Maximum thumbnail width (reply)

View File

@ -91,16 +91,19 @@ function createThumbnail($name, $filename, $new_w, $new_h) {
$system=explode(".", $filename);
$system = array_reverse($system);
if (preg_match("/jpg|jpeg/", $system[0])) {
$src_img=imagecreatefromjpeg($name);
$src_img=@imagecreatefromjpeg($name);
} else if (preg_match("/png/", $system[0])) {
$src_img=imagecreatefrompng($name);
$src_img=@imagecreatefrompng($name);
} else if (preg_match("/gif/", $system[0])) {
$src_img=imagecreatefromgif($name);
$src_img=@imagecreatefromgif($name);
} else {
return false;
}
if (!$src_img) {
// Check for the case if the image is actually wrong type
list($src_img, $actual_type)=imagecreatefromwhatever($name);
if (!$src_img)
exitWithErrorPage(_gettext('Unable to read uploaded file during thumbnailing.'), _gettext('A common cause for this is an incorrect extension when the file is actually of a different type.'));
}
$old_x = imageSX($src_img);
@ -116,7 +119,18 @@ function createThumbnail($name, $filename, $new_w, $new_h) {
$dst_img = ImageCreateTrueColor($thumb_w, $thumb_h);
fastImageCopyResampled($dst_img, $src_img, 0, 0, 0, 0, $thumb_w, $thumb_h, $old_x, $old_y, $system);
if (preg_match("/png/", $system[0])) {
if ($actual_type) {
if (($actual_type == 'jpg' || $actual_type == 'webp') && !imagejpeg($dst_img, $filename, 70)) {
exitWithErrorPage('unable to imagejpg.');
return false;
} else if ($actual_type == 'png' && !imagepng($dst_img,$filename,0,PNG_ALL_FILTERS)) {
exitWithErrorPage('unable to imagepng.');
return false;
} else if ($actual_type == 'gif' && !imagegif($dst_img, $filename)) {
exitWithErrorPage('unable to imagegif.');
return false;
}
} else if (preg_match("/png/", $system[0])) {
if (!imagepng($dst_img,$filename,0,PNG_ALL_FILTERS) ) {
exitWithErrorPage('unable to imagepng.');
return false;
@ -142,6 +156,27 @@ function createThumbnail($name, $filename, $new_w, $new_h) {
return false;
}
// Sometimes the image is of wrong type, particularly thumbnails from Youtube
function imagecreatefromwhatever($fname) {
if ($img = @imagecreatefromjpeg($fname)) {
$type = 'jpg';
return array($img, $type);
}
if ($img = @imagecreatefromwebp($fname)) {
$type = 'webp';
return array($img, $type);
}
if ($img = @imagecreatefrompng($fname)) {
$type = 'png';
return array($img, $type);
}
if ($img = @imagecreatefromgif($fname)) {
$type = 'gif';
return array($img, $type);
}
return array(false, false);
}
/* Author: Tim Eckel - Date: 12/17/04 - Project: FreeRingers.net - Freely distributable. */
/**
* Faster method than only calling imagecopyresampled()
@ -210,14 +245,32 @@ function fetch_video_data($site, $code, $maxwidth, $thumb_tmpfile) {
if (!in_array($site, array('you', 'vim', 'cob', 'scl')))
return array('error' => 'unsupported_site');
$use_youtube_dl = I0_YOUTUBE_DL_PATH !== '' && $site === 'you';
// Pre-setup
if ($use_youtube_dl) {
putenv('PATH=' . I0_YOUTUBE_DL_PATH . PATH_SEPARATOR . getenv('PATH'));
}
else {
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt ($ch, CURLOPT_TIMEOUT, 10);
if (I0_CURL_PROXY)
curl_setopt($ch, CURLOPT_PROXY, I0_CURL_PROXY);
}
// Fetching the data
if ($use_youtube_dl) {
exec('youtube-dl --dump-json https://www.youtube.com/watch?v='.$code, $json, $er);
if (!$er) {
$ydl_info = json_decode($json[0]);
}
else {
return array('error' => _gettext('API returned invalid data.'));
}
}
else {
// Getting a URL
switch ($site) {
case 'cob':
@ -251,8 +304,22 @@ function fetch_video_data($site, $code, $maxwidth, $thumb_tmpfile) {
$data = json_decode($result, true);
if ($data == NULL)
return array('error' => _gettext('API returned invalid data.'));
}
// Find needed thumbnail width
if ($use_youtube_dl) {
$options_available = count($ydl_info->thumbnails);
$i = 0;
foreach($ydl_info->thumbnails as &$thumb) {
$i++;
if ($thumb->width >= $maxwidth || $options_available == $i) {
$thumb_url = $thumb->url;
$thumbwidth = $thumb->width;
break;
}
}
}
else {
switch ($site) {
case 'cob':
$widths_available = array(
@ -297,6 +364,7 @@ function fetch_video_data($site, $code, $maxwidth, $thumb_tmpfile) {
break;
}
}
}
// Get thumbnail URL
switch ($site) {
@ -307,7 +375,9 @@ function fetch_video_data($site, $code, $maxwidth, $thumb_tmpfile) {
$thumb_url = preg_replace('/\.webp/', '.jpg', $data[0]['thumbnail_'.$chosen_preset]);
break;
case 'you':
if (!$use_youtube_dl) {
$thumb_url = $data['items'][0]['snippet']['thumbnails'][$chosen_preset]['url'];
}
break;
case 'scl':
$thumb_url = $data['thumbnail_url'];
@ -356,8 +426,14 @@ function fetch_video_data($site, $code, $maxwidth, $thumb_tmpfile) {
case 'you':
$r['width'] = 1920;
$r['height'] = 1080;
if ($use_youtube_dl) {
$r['title'] = $ydl_info->title;
$duration = $ydl_info->duration;
}
else {
$r['title'] = $data['items'][0]['snippet']['title'];
$duration = preg_replace_callback('/PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?/', 'ISO8601_callback', $data['items'][0]['contentDetails']['duration']);
}
break;
case 'scl':
$r['width'] = 500;
@ -371,8 +447,8 @@ function fetch_video_data($site, $code, $maxwidth, $thumb_tmpfile) {
default:
return array('error' => _gettext('API returned invalid data.'));
}
if ($r['width'] <= 0 || $r['height'] <= 0) {
// var_dump($r);
return array('error' => _gettext('API returned invalid data.'));
}
// Convert duration into readable string

View File

@ -64,7 +64,7 @@
// ---------------------------------- Attachment handling -----------------------------------
$cf['KU_FFMPEGPATH'] = '/usr/local/bin/ffmpeg'; //path to FFMPEG, on windows it's usually 'C:\ffmpeg\bin' (REQUIRED for videos)
$cf['KU_YOUTUBE_APIKEY'] = 'your_api_key'; //Your personal anal probe ID. Can be obtained it Google Dev. Console
$cf['I0_YOUTUBE_DL_PATH'] = ''; // Path to youtube-dl binary. If not empty, youtube-dl will be used instead of default API (in this case you won't need KU_YOUTUBE_APIKEY)
// ------------------------------------- Misc settings --------------------------------------
$cf['I0_CURL_PROXY'] = false; // Proxy to use when fetching external resources, for example 'socks5h://127.0.0.1:9050' — to connect through TOR