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

CodeIgniter 影片上傳轉檔實戰:上傳 + ffmpeg 轉 FLV + 入庫

     編輯:PHP 綜合知識

完整流程概覽

  1. 設定上傳規則(路徑、類型、大小)。
  2. 執行上傳,取得檔案資訊。
  3. 呼叫 exec("ffmpeg -i ...") 轉碼為 FLV。
  4. 更新資料庫記錄轉檔後檔名。

Controller 程式碼

<?php
$file = 'video_file'; // input name

$config['upload_path']   = './video_folder/';
$config['allowed_types'] = 'mov|mpeg|mp3|avi';
$config['max_size']      = '50000'; // KB
$config['max_width']     = '';
$config['max_height']    = '';

$this->load->library('upload', $config);

if (!$this->upload->do_upload($file)) {
    $err_msgs .= '上傳失敗:' . $this->upload->display_errors() . '<br>';
} 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 轉檔:同目錄輸出 .flv
    $cmd = "ffmpeg -i " . escapeshellarg($full_path) . " " . escapeshellarg($directory_path . $raw_name . ".flv");
    exec($cmd, $output, $return_var);

    if ($return_var !== 0) {
        log_message('error', "ffmpeg 失敗: " . implode("\n", $output));
        show_error('影片轉檔失敗');
    }

    // 寫入資料庫
    $this->db->set('video', $raw_name . '.flv');
    $this->db->where('id', $id);
    $this->db->update('user_videos');
}
?>

關鍵安全與健壯性細節

1. escapeshellarg() 必加

防止檔名含空格、分號、反引號等導致命令注入。

2. ffmpeg 路徑與參數優化

$ffmpeg = '/usr/bin/ffmpeg'; // 明確指定路徑
$cmd = "{$ffmpeg} -y -i " . escapeshellarg($full_path) .
       " -c:v libx264 -preset fast -crf 23 -c:a aac -b:a 128k " .
       escapeshellarg($directory_path . $raw_name . ".flv");
  • -y:覆蓋輸出檔不詢問。
  • -preset fast -crf 23:速度/品質平衡預設值。
  • 指定編碼器避免相容性問題。

3. 非同步處理(生產環境必備)

轉檔耗時秒~分級,不可阻塞 HTTP 請求。建議:

  • 將任務寫入 Queue(Redis/RabbitMQ/Database)。
  • Worker 進程(Supervisor + PHP CLI)消費 Queue 執行 ffmpeg。
  • 完成後回寫 DB 狀態、發送通知(WebSocket/Email/Push)。

4. 檔案驗證

// 上傳後再次驗證 MIME
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime = $finfo->file($full_path);
if (!in_array($mime, ['video/quicktime', 'video/mpeg', 'video/mp4', 'video/x-msvideo'])) {
    unlink($full_path);
    show_error('檔案類型不符');
}

資料庫結構建議

CREATE TABLE user_videos (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    video VARCHAR(255) NOT NULL,   // 儲存 xxx.flv
    original_name VARCHAR(255),
    status ENUM('pending','processing','ready','failed') DEFAULT 'pending',
    duration INT DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved