首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

CodeIgniter 視頻上傳與 FFmpeg 轉碼 FLV 完整實戰

     編輯:PHP 相關知識

需求場景

用戶上傳視頻(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');
        }
    }
}

關鍵技術點解析

1. 安全的命令執行

2. FFmpeg 常用轉碼參數

3. 異步處理大文件(生產環境必須)

同步 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);
}

4. 進度追蹤(進階)

FFmpeg 支持 -progress 參數輸出進度信息,配合 WebSocket 推送前端顯示進度條。

環境依賴檢查

  1. 服務器安裝 FFmpeg:apt-get install ffmpeg / yum install ffmpeg
  2. 驗證:ffmpeg -version 可正常輸出版本信息
  3. PHP exec() / shell_exec() 未被 disable_functions 禁用
  4. 上傳目錄 ./video_folder/ 可寫權限

資料表結構建議

擴展:現代化替代方案

  • PHP-FFMpeg 庫:composer require php-ffmpeg/php-ffmpeg,面向對象 API,更優雅
  • 雲端轉碼:阿里云 MPS、騰訊云 MPS、AWS MediaConvert,無需維護 FFmpeg 服務器
  • 前端直傳 + 觸發轉碼:OSS 直傳 → 事件通知 → 函數計算/隊列轉碼
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved