# # 対応サムネイルを追加するコード # # exclude 'mp4' and 'webm' $config['ffmpeg_ext_files'][] = 'flv'; $config['ffmpeg_ext_files'][] = 'wmv'; $config['ffmpeg_ext_files'][] = 'asf'; $config['ffmpeg_ext_files'][] = 'mpeg'; $config['ffmpeg_ext_files'][] = 'mpg'; $config['ffmpeg_ext_files'][] = 'avi'; $config['ffmpeg_ext_files'][] = 'ts'; $config['ffmpeg_ext_files'][] = 'm2ts'; $config['ffmpeg_ext_files'][] = 'mov'; $config['ffmpeg_ext_files'][] = 'mkv'; # imagemagick, graphicsmagick extensions $config['imgm_ext_files'][] = 'mpo'; $config['imgm_ext_files'][] = 'avif'; $config['imgm_ext_files'][] = 'tiff'; $config['imgm_ext_files'][] = 'webp'; $config['imgm_ext_files'][] = 'svg'; $config['allowed_ext_files'] = array_merge( $config['allowed_ext_files'], $config['imgm_ext_files'], $config['ffmpeg_ext_files']); if (! function_exists('postHundlerIcThumb')) { class ImageIC { public $src, $format, $image, $size; public function __construct($src, $format = false, $size = false) { global $config; $this->src = $src; $this->format = $format; if ($config['thumb_method'] == 'imagick') { $classname = 'ImageImagick'; } elseif (in_array($config['thumb_method'], array('convert', 'convert+gifsicle', 'gm', 'gm+gifsicle'))) { $classname = 'ImageConvert'; } else { $classname = 'Image' . strtoupper($this->format); if (!class_exists($classname)) { error('IC-1:'._('Unsupported file format: ') . $this->format); } } $this->image = new $classname($this, $size); if (!$this->image->valid()) { $this->delete(); error('IC-2:' . $config['error']['invalidimg']); } $this->size = (object)array('width' => $this->image->_width(), 'height' => $this->image->_height()); if ($this->size->width < 1 || $this->size->height < 1) { $this->delete(); error('IC-3:' . $config['error']['invalidimg']); } } public function resize($extension, $max_width, $max_height) { global $config; if ($config['thumb_method'] == 'imagick') { $classname = 'ImageImagick'; } elseif ($config['thumb_method'] == 'convert') { $classname = 'ImageConvert'; } elseif ($config['thumb_method'] == 'convert+gifsicle') { $classname = 'ImageConvert'; $gifsicle = true; } elseif ($config['thumb_method'] == 'gm') { $classname = 'ImageConvert'; $gm = true; } elseif ($config['thumb_method'] == 'gm+gifsicle') { $classname = 'ImageConvert'; $gm = true; $gifsicle = true; } else { $classname = 'Image' . strtoupper($extension); if (!class_exists($classname)) { error('IC-4:'._('Unsupported file format: ') . $extension); } } $thumb = new $classname(false); $thumb->src = $this->src; $thumb->format = $this->format; $thumb->original_width = $this->size->width; $thumb->original_height = $this->size->height; $x_ratio = $max_width / $this->size->width; $y_ratio = $max_height / $this->size->height; if (($this->size->width <= $max_width) && ($this->size->height <= $max_height)) { $width = $this->size->width; $height = $this->size->height; } elseif (($x_ratio * $this->size->height) < $max_height) { $height = ceil($x_ratio * $this->size->height); $width = $max_width; } else { $width = ceil($y_ratio * $this->size->width); $height = $max_height; } $thumb->_resize($this->image->image, $width, $height); return $thumb; } public function to($dst) { $this->image->to($dst); } public function delete() { file_unlink($this->src); } public function destroy() { $this->image->_destroy(); } } function postHundlerIcThumb($post) { global $board, $config; if (! $post->has_file) { return; }; if ($config['spoiler_images'] && isset($_POST['spoiler'])) { return; }; foreach ($post->files as &$file) { # exclude 'spoiler' and thumb-generated file. if ($file->thumb == 'file' || $file->thumb == '') { $result = postHandlerVideoThumb($file, $post); if ($result === true) { continue; } elseif ($result === false) { # do nothing } else { return 'postHandlerVideoThumb: ' . $result; # error }; $result = postHandlerImageThumb($file, $post); if ($result === true) { continue; } elseif ($result === false) { # do nothing } else { return 'postHandlerImageThumb:' . $result; # error }; }; }; }; function postHandlerImageThumb(&$file, &$post) { global $board, $config; if (! in_array($file->extension, $config['imgm_ext_files'])) { # $post->body .= 'postHandlerImageThumb:fileext[' . $file->extension . '] '; return false; }; if (! in_array($config['thumb_method'], ['gm', 'convert', 'imagick'])) { # $post->body .= 'postHandlerImageThumb:thumb_method[' . $config['thumb_method'] . '] '; return false; }; require_once dirname(__FILE__) . '/image.php'; $file_thumb = $board['dir'] . $config['dir']['thumb'] . $file->file_id . '.'; if ($config['thumb_ext']) { $file_thumb .= $config['thumb_ext']; } else { $file_thumb .= $file->extension; }; $image = new ImageIC($file->file_path); $thumb = $image->resize( $config['thumb_ext'] ? $config['thumb_ext'] : $file->extension, $post->op ? $config['thumb_op_width'] : $config['thumb_width'], $post->op ? $config['thumb_op_height'] : $config['thumb_height'] ); $thumb->to($file_thumb); $file_thumbwidth = $thumb->width; $file_thumbheight = $thumb->height; $thumb->_destroy(); $file_thumb = mb_substr($file_thumb, mb_strlen($board['dir'] . $config['dir']['thumb'])); $file->thumb = $file_thumb; $file->thumbwidth = $file_thumbwidth; $file->thumbheight = $file_thumbheight; return true; }; function postHandlerVideoThumb(&$file, &$post) { # return string if error. global $board, $config; if (! $config['webm']['use_ffmpeg']) { return false; }; if (! in_array($file->extension, $config['ffmpeg_ext_files'])) { return false; }; # ref: vichan/inc/lib/webm/ffmpeg.php: get_webm_info, require_once dirname(__FILE__) . '/lib/webm/ffmpeg.php'; $video_info = get_video_info($file->file_path); if (! empty($video_info['error'])) { return 'postHandlerVideoThumb:' . $video_info['error']['msg']; }; $file->width = $video_info['width']; $file->height = $video_info['height']; $file = set_thumbnail_dimensions($post, $file); $tn_path = $board['dir'] . $config['dir']['thumb'] . $file->file_id . '.jpg'; if(0 == make_webm_thumbnail($file->file_path, $tn_path, $file->thumbwidth, $file->thumbheight, $video_info['duration'])) { $file->thumb = $file->file_id . '.jpg'; return true; }; return false; }; function get_video_info($filename) { global $board, $config; $filename = escapeshellarg($filename); $ffprobe = $config['webm']['ffprobe_path']; $ffprobe_out = array(); $info = array(); exec("$ffprobe -v quiet -print_format json -show_format -show_streams $filename", $ffprobe_out); $ffprobe_out = json_decode(implode("\n", $ffprobe_out), 1); $info['duration'] = $ffprobe_out['format']['duration']; foreach ($ffprobe_out['streams'] as $stream) { if ($stream['width'] != '' && $stream['height'] != '') { $info['width'] = $stream['width']; $info['height'] = $stream['height']; break; }; }; return $info; }; }; # mp4 と webm 以外の動画にもサムネイルを付ける(インラインプレイヤーとは別設定) # この行で設定が有効になる。 event_handler('post', 'postHundlerIcThumb');