使用此插件需要注意:
1.服务器必须安装FFmpeg
需要正确配置FFmpeg路径
3.PHP需要有执行shell命令的权限
4.转换大文件可能需要较长时间,建议配置适当的PHP执行时间
限制
建议在使用前测试FFmpeg是否正确安装并可用。
<?php
class videotowebm {
/**
* 插件配置方法
* @return array 配置数组
*/
function config() {
$configs = array();
$configs[] = array(
'configname' => '启用转换',
'hash' => 'enabled',
'inputhash' => 'switch',
'tips' => '开启后将自动转换上传的视频为WebM格式',
'defaultvalue' => '1'
);
$configs[] = array(
'configname' => '视频质量',
'hash' => 'quality',
'inputhash' => 'number',
'tips' => 'WebM视频质量(1-51,数值越小质量越高)',
'defaultvalue' => '51'
);
$configs[] = array(
'configname' => '删除原视频',
'hash' => 'delete_original',
'inputhash' => 'switch',
'tips' => '转换完成后是否删除原始视频文件',
'defaultvalue' => '1'
);
$configs[] = array(
'configname' => 'FFmpeg路径',
'hash' => 'ffmpeg_path',
'inputhash' => 'text',
'tips' => 'FFmpeg可执行文件的完整路径,如:/usr/bin/ffmpeg',
'defaultvalue' => '/usr/bin/ffmpeg'
);
return $configs;
}
/**
* 钩子定义
* @return array 钩子数组
*/
function hook() {
$hooks = array();
$hooks[] = array(
'hookname' => 'upload_convert_video',
'hookedfunction' => 'cms:common:upload:=',
'enabled' => 1
);
return $hooks;
}
/**
* 监听上传钩子方法
* @param string $class 被监听的方法名
* @param array $args 原方法的参数数组
* @param mixed $return 原方法的返回值
* @return mixed 处理后的返回值
*/
function upload_convert_video($class, $args, $return) {
if(!$return || !isset($return['url']) || empty($return['url']) || $return['error']) return $return;
// 检查是否启用转换
if(!config('enabled')) return $return;
// 获取视频质量设置
$quality = intval(config('quality'));
if($quality < 1) $quality = 1;
if($quality > 51) $quality = 51;
// 获取FFmpeg路径
$ffmpeg = config('ffmpeg_path');
// 获取实际文件路径
$file_path = rtrim(dirname(dirname(dirname(__FILE__))), DIRECTORY_SEPARATOR) . str_replace('/', DIRECTORY_SEPARATOR, $return['url'][0]);
// 检查文件是否为视频
$video_extensions = array('mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv', '3gp');
$file_extension = strtolower(pathinfo($file_path, PATHINFO_EXTENSION));
if(!in_array($file_extension, $video_extensions)) {
return $return;
}
// 检查ffmpeg是否可用
exec("{$ffmpeg} -version", $output, $return_var);
if($return_var !== 0) {
error_log('FFmpeg not available at path: ' . $ffmpeg);
return $return;
}
// 生成新的WebM文件名
$webm_file = substr($file_path, 0, strrpos($file_path, '.')) . '.webm';
// 构建FFmpeg命令
$cmd = sprintf(
'%s -i %s -c:v libvpx-vp9 -crf %d -b:v 0 -c:a libopus %s 2>&1',
escapeshellarg($ffmpeg),
escapeshellarg($file_path),
$quality,
escapeshellarg($webm_file)
);
// 执行转换
exec($cmd, $output, $return_var);
if($return_var === 0 && file_exists($webm_file)) {
// 更新返回的URL为WebM文件
$return['url'][0] = '/' . substr($webm_file, strlen(dirname(dirname(dirname(__FILE__)))) + 1);
// 检查是否需要删除原视频文件
if(config('delete_original')) {
unlink($file_path);
}
return $return;
}
error_log('Video conversion failed. Command output: ' . implode("\n", $output));
return $return;
}
}