Go + FFmpeg互動丨學習記錄
theme: cyanosis highlight: monokai
零、前言
注:本文未完待續
主要思路:
使用 Golang 和 FFmpeg 互動可以分為以下幾個步驟:
- 安裝 FFmpeg: 首先需要安裝 FFmpeg,可以在終端中輸入命令來安裝。
- 建立一個Golang專案,並在其中建立一個接收上傳視訊檔案的介面。
- 在介面中接收上傳的檔案,並使用Golang中的 exec 包來執行 FFmpeg 命令來轉碼視訊。
- 轉碼後的檔案可以儲存在本地或上傳到雲端儲存伺服器。
- 將視訊資訊儲存到 MySQL 資料庫中。
- 在Golang中使用GORM或其他ORM庫來連線資料庫並存儲資料。
- 在程式碼中使用 exec.Command 函式來執行 FFmpeg 命令。該函式需要 ffmpeg 的完整路徑和命令列引數,並返回一個 *exec.Cmd 型別的物件。
- 通過使用 .StdoutPipe() 和 .Start() 方法來執行 FFmpeg 命令並獲取命令輸出。
- 使用 io.Copy() 函式將轉碼後的視訊檔案寫入本地檔案或上傳到雲端儲存伺服器。
- 使用GORM將上傳視訊檔案的資訊儲存到資料庫中。
一、本地IO
以下是一個程式碼示例,實現從本地來,到本地去的功能,記得改路徑和名稱!
```Go package main
import ( "fmt" "os/exec" )
func main() { // 設定視訊原始檔路徑 inputFile := "input.mp4" // 設定轉碼後文件路徑 outputFile := "output.mp4"
// 設定 ffmpeg 命令列引數
args := []string{"-i", inputFile, "-c", "copy", outputFile}
// 建立 *exec.Cmd
cmd := exec.Command("ffmpeg", args...)
// 執行 ffmpeg 命令
if err := cmd.Run(); err != nil {
fmt.Println(err)
return
}
fmt.Println("轉碼成功")
} ```
如果你沒有報錯的話,可以看到,有輸出檔案,但是這一來一回有什麼用呢?
事實上目的就是讓這個轉碼後的視訊檔案是可以線上播放的。
二、儲存到資料庫
光從本地來到本地去總是不長久的,我們要開啟資料庫的大門;
首先需要準備好資料庫和表,這裡我們同樣使用Navicat來操作,具體操作步驟如下,不需要的可以跳過:
新建連線 -> MySQL -> 連線名隨便 -> 密碼隨便(強烈建議與資料庫密碼相同否則可能會產生一些錯誤) -> 雙擊左側開啟 -> 右鍵information_schema -> 新建資料庫 -> 名稱隨便 -> 字符集utf8mb4
然後執行如下程式碼即可,注意修改你的路徑、名稱、資料庫名稱等資訊:
```Go package main
import ( "fmt" "os/exec"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
// 定義 Video struct,用來儲存視訊資訊 type Video struct { gorm.Model Name string Path string }
func main() { // 連線資料庫 db, err := gorm.Open("mysql", "root:password@/database?charset=utf8&parseTime=True&loc=Local") if err != nil { panic("failed to connect to the database") } defer db.Close()
// 建立表
db.AutoMigrate(&Video{})
// FFmpeg命令轉換視訊
cmd := exec.Command("ffmpeg", "-i", "input.mp4", "-vcodec", "libx264", "-acodec", "aac", "-strict", "-2", "output.mp4")
err = cmd.Run()
if err != nil {
fmt.Println(err)
}
// 在資料庫裡儲存視訊資訊
video := Video{Name: "output", Path: "output.mp4"}
db.Create(&video)
} ```
Navicat中效果如下:
幾點說明:
- 這個 ffmpeg 示例中的命令是將視訊 "input.mp4" 轉換為新的視訊檔案 "output.mp4"。
- 在這個命令中,我們使用了 "-i" 引數來指定輸入檔案,"-vcodec" 和 "-acodec" 引數來指定視訊和音訊編碼,"-strict" 和 "-2" 引數來指定編碼標準。
- 其中 "-vcodec" 指定了視訊編碼為 libx264,"-acodec" 指定音訊編碼為 aac ,這兩個編碼是線上播放視訊常用的編碼方式,所以這個轉碼後的視訊檔案是可以線上播放的。
- 如果你想要轉換成其它格式,可以查詢ffmpeg的文件和引數來實現。
三、前端實現與使用者互動
思路一:Nginx
Nginx 的作用是作為一個反向代理伺服器,用於將使用者的請求轉發到後端伺服器進行處理。
反向代理伺服器可以幫助實現負載均衡、安全性、快取等功能。
如果想使用 Nginx 作為 Web 伺服器來處理使用者的請求並將其轉發到後端伺服器,可以這樣做:
- 首先,需要在自己的伺服器上安裝 Nginx。
- 然後,需要編寫 Nginx 的配置檔案來處理使用者的請求。舉個例子,如果想將所有的 /upload 請求轉發到後端伺服器的 /upload 介面,可以在 Nginx 的配置檔案中新增如下程式碼:
location /upload {
proxy_pass http://backend_server:8000/upload;
}
- 在後端伺服器上實現對 /upload 介面的處理,如接收視訊檔案並進行轉碼。可以使用 Gin 或其他框架來實現這個功能,並將轉碼後的檔案儲存到資料庫中。
- 完成以上步驟後,當用戶在前端網頁上上傳視訊檔案時,這個檔案會被髮送到 Nginx,然後 Nginx 會將請求轉發到後端伺服器進行處理。後端伺服器接收到請求後會呼叫 ffmpeg 將視訊轉碼並存儲在資料庫中。
如果是在web端指定本地要作為輸入的視訊路徑,這部分需要在前端進行實現,可以在前端頁面上使用 HTML input 標籤來實現檔案選擇功能,並在選擇檔案後使用 JavaScript 來獲取檔案路徑併發送到後端伺服器。
例如,在 HTML 中使用 input 標籤來實現檔案選擇功能:
HTML
<input type="file" id="input-file">
使用 JavaScript 程式碼來獲取檔案路徑併發送到後端伺服器:
```javascript
```
思路二:GoFTP
使用 GoFTP 來上傳和下載視訊,可以在 Go 中使用第三方庫:https://github.com/jlaffaye/ftp ;
使用這個庫可以在 Go 中實現 FTP 協議的上傳和下載功能,並可以輕鬆地將視訊檔案上傳到伺服器並在伺服器上進行轉碼。如此,可以將檔案上傳和轉碼的功能放在同一個伺服器上,而不需要使用反向代理伺服器來轉發請求。
使用 GoFTP 來上傳和下載視訊檔案的話不需要使用 HTML 和 JavaScript 。可以使用 Go 程式來直接與 FTP 伺服器進行互動。可以使用 GoFTP 庫,在 Go 中編寫程式來連線到 FTP 伺服器實現:連線到FTP伺服器,登入,上傳檔案,下載檔案等操作。
當然,如果需要在web上獲取使用者選擇的視訊檔案路徑,可以使用HTML和JavaScript來實現這部分功能,但是FTP上傳和下載操作可以直接在Go程式中實現。
以下是一個示例程式碼:
```Go package main
import ( "fmt" "os"
"github.com/jlaffaye/ftp"
)
func main() { // 連線到 FTP 伺服器 conn, err := ftp.Connect("ftp.example.com:21") // ftp.example.com:21是一個模擬的FTP伺服器地址,實際使用中需要替換成真正的FTP伺服器的地址。 if err != nil { fmt.Println("Error connecting to FTP server:", err) return } defer conn.Quit()
// 登入到 FTP 伺服器
// 需要提前設定好username and password
if err := conn.Login("username", "password"); err != nil {
fmt.Println("Error logging in to FTP server:", err)
return
}
// 開啟本地檔案
file, err := os.Open("example.txt")
if err != nil {
fmt.Println("Error opening local file:", err)
return
}
defer file.Close()
// 上傳檔案到 FTP 伺服器
if err := conn.Stor("example.txt", file); err != nil {
fmt.Println("Error uploading file:", err)
return
}
fmt.Println("File uploaded successfully!!!")
} ```
一個新的問題出現了,如何搭建一個本地測試用的伺服器呢?好問題,如下:
在本地搭建一個測試用的FTP伺服器可以使用一些常用的FTP伺服器軟體來實現,如FileZilla Server, ProFTPD等。
- 對於windows系統,可以使用FileZilla Server,下載地址:https://filezilla-project.org/download.php?type=server 下載完成後安裝,配置好FTP使用者名稱和密碼,設定好訪問許可權,就可以在本地測試使用了。
- 對於Linux系統,可以使用ProFTPD, 安裝方法可以使用apt-get,yum等安裝工具,配置好FTP使用者名稱和密碼,設定好訪問許可權,就可以在本地測試使用了。
三個注意:
- 首席需要注意的是,在安裝和配置FTP伺服器的過程中,需要遵循安全原則,如設定強密碼,限制訪問許可權等,以防止未經授權的訪問。
- 其次還需要注意的是,在使用FTP伺服器時需要注意防火牆設定,確保FTP伺服器能夠正常訪問。
- 最後需要注意的是,如果您使用的是公網IP地址,需要注意安全性,因為您的FTP伺服器可能會被惡意攻擊。
兩種方法的對比:
使用 Nginx 作為反向代理伺服器和使用 GoFTP 上傳和下載視訊檔案,兩種方法有一些不同的優缺點。
使用 Nginx 作為反向代理伺服器的優點:
- 可以提高系統的安全性,因為 Nginx 可以對使用者的請求進行驗證和過濾。
- 可以實現負載均衡,可以提高系統的可用性和穩定性。
- 可以實現快取功能,可以提高系統的效能。
使用 Nginx 作為反向代理伺服器的缺點:
- 可能會增加系統的複雜度。
- 可能會增加系統的運維成本。
使用 GoFTP 上傳和下載視訊檔案的優點:
- 不需要使用額外的伺服器或框架,可以簡化系統的架構。
- 可以直接在 Go 程式中實現檔案上傳和下載功能。
使用 GoFTP 上傳和下載視訊檔案的缺點:
- 可能沒有Nginx那麼高的安全性,負載均衡和快取功能。
- 可能需要自己手動實現檔案上傳和下載的功能,運維成本可能更高。
總結來說,對於需要高安全性,高併發,高可用性的系統,使用 Nginx 作為反向代理伺服器可能會更好。但是如果你的系統不需要如此高階的功能,並且希望簡化系統架構,減少運維成本,使用 GoFTP 來上傳和下載視訊檔案可能是一個更好的選擇。
兩種方法的結合:
當然,這兩種方法是可以結合起來使用的。
-
使用 Nginx 作為反向代理伺服器,來過濾和驗證使用者的請求,並將請求轉發到 Go 程式中進行處理。
-
在 Go 程式中可以使用 GoFTP 上傳和下載視訊檔案,並在檔案上傳完成後使用 ffmpeg 進行轉碼,將轉碼後的檔案儲存到資料庫。
這樣做的好處是,Nginx 可以提供高安全性、高併發、高可用性等功能,而 GoFTP 可以提供簡化系統架構、減少運維成本等功能,壞處很顯然,就是實現麻煩。
四、FileZillaServer + X-Plore
這裡介紹一種基於上文思路二,使用FileZillaServer + X-Plore實現的區域網下不同裝置之間的檔案互傳方法;
FileZillaServer
是什麼?
是能在本地搭建一個測試用的FTP伺服器的軟體。
怎麼下載怎麼用?
下載地址:FileZilla中文網 - 免費開源的FTP解決方案
前面的安裝以及初始化步驟可以參考:
FileZilla搭建FTP伺服器圖解教程 - 知乎 (zhihu.com)
記得第一個要設定為根目錄;
完成設定之後在本地的資源管理器中(以前是可以用瀏覽器的)輸入ftp://127.0.0.1
進入即可。
然後就可以看到該使用者可以看到的檔案列表了。
這個時候可以為該使用者新增新的可見的非根目錄的資料夾,並且需要人為地指定它在伺服器端的路徑,例如/myAdditional
,隨後確定後重新整理頁面,就可以發現多了一個資料夾,這樣就可以做到本地的檔案結構和伺服器端的不一樣。
有趣的是,這一操作可以讓我們重新組織本地檔案系統下的各個路徑。
還有我們可以使用一個比較方便的視覺化的客戶端來操作:FileZilla-Client;
由於操作比較簡單這裡就不給出介紹了,下載地址同上。
Android訪問FTP伺服器
可供使用的APP有:
- AndFTP
- 螞蟻科技
- Turbo FTP 客戶端
- ES 檔案資源管理器
- 簡易 FTP 客戶端
- 管理員之手應用程式
- Termius - SSH / SFTP
- FTP 伺服器
- X-Plore
筆者的選擇是X-Plore,非常好用;
下載之後點選FTP,然後輸入剛才在PC端設定的IP(就是cmd中ipconfig的ipv4那個)以及賬戶+密碼,就可以連線到FTP伺服器了。
這個時候我們再執行思路二中的示例程式碼,記得寫好要傳輸的檔案,執行即可實現檔案互傳,非常方便。