用戶上傳視頻(mov、mpeg、mp3、avi 等格式),服務端自動轉碼為 FLV 格式供 Web 播放器播放,並將轉碼後文件信息入庫。
<?php class Video extends CI_Controller { public function upload() { $file = 'video_file'; // 表單文件字段名 // 上傳配置 $config['upload_path'] = './video_folder/'; $config['allowed_types'] = 'mov|mpeg|mp3|avi|mp4|wmv|flv'; $config['max_size'] = 50000; // 50MB $config['max_width'] = ''; $config['max_height'] = ''; $config['encrypt_name'] = TRUE; // 加密文件名,避免衝突 $this->load->library('upload', $config); if (!$this->upload->do_upload($file)) { // 上傳失敗 $error = $this->upload->display_errors(); log_message('error', "視頻上傳失敗: $error"); $this->session->set_flashdata('error', '上傳失敗: ' . $error); redirect('video/upload_form'); } else { // 上傳成功,獲取文件信息 $data = $this->upload->data(); $video_path = $data['file_name']; $directory_path = $data['file_path']; $full_path = $data['full_path']; $raw_name = $data['raw_name']; // 不含副檔名 // FFmpeg 轉碼命令 $output_file = $raw_name . '.flv'; $cmd = "ffmpeg -i " . escapeshellarg($full_path) . " " . escapeshellarg($directory_path . $output_file); // 執行轉碼(同步阻塞,大文件建議異步隊列) exec($cmd . " 2>&1", $output, $return_var); if ($return_var === 0) { // 轉碼成功,更新數據庫 $this->db->where('id', $video_id); // 假設有 video_id $this->db->update('user_videos', [ 'video' => $output_file, 'status' => 'converted', 'converted_at' => date('Y-m-d H:i:s') ]); $this->session->set_flashdata('success', '視頻上傳並轉碼成功!'); } else { // 轉碼失敗 log_message('error', "FFmpeg 轉碼失敗: " . implode("\n", $output)); $this->session->set_flashdata('error', '轉碼失敗,請聯繫管理員'); } redirect('video/list'); } } }
同步 exec() 會阻塞 PHP 進程,導致用戶等待超時。推薦架構:
lpush('video_convert_queue', json_encode([
'input' => $full_path,
'output' => $directory_path . $output_file,
'video_id' => $video_id
]));
// 2. Worker 進程消費隊列(Supervisor 管理常駐進程)
// worker.php
while (true) {
$task = $redis->rpop('video_convert_queue');
if ($task) {
$data = json_decode($task, true);
exec("ffmpeg -i " . escapeshellarg($data['input']) . " " . escapeshellarg($data['output']) . " 2>&1", $out, $ret);
// 更新 DB 狀態...
}
sleep(1);
}
FFmpeg 支持 -progress 參數輸出進度信息,配合 WebSocket 推送前端顯示進度條。
apt-get install ffmpeg / yum install ffmpegffmpeg -version 可正常輸出版本信息exec() / shell_exec() 未被 disable_functions 禁用./video_folder/ 可寫權限composer require php-ffmpeg/php-ffmpeg,面向對象 API,更優雅