我正在嘗試使用 youtube-dl 和 ffmpeg 建立音樂串流服務。當使用者發送帶有視訊 URL 的 POST 請求時,我的處理程序程式碼的工作原理如下:
router.POST("/submit", func(c *gin.Context) { body := Body{} if err := c.BindJSON(&body); err != nil { c.AbortWithError(http.StatusBadRequest, err) return } w := c.Writer header := w.Header() header.Set("Content-Type", "audio/mp3") w.WriteHeader(http.StatusOK) fetchMusic(c, body.Data) }) func fetchMusic(c *gin.Context, data string) { r, w := io.Pipe() defer r.Close() ydl := exec.Command("youtube-dl", data, "-o-") ffmpeg := exec.Command("ffmpeg", "-i", "/dev/stdin", "-vn", "-f", "mp3", "-") ydl.Stdout = w ydl.Stderr = os.Stderr ffmpeg.Stdin = r ffmpeg.Stdout = c.Writer ffmpeg.Stderr = os.Stderr fmt.Println("Starting-----------------------") go func() { if err := ydl.Run(); err != nil { panic(err) } }() if err := ffmpeg.Run(); err != nil { panic(err) } fmt.Println("Done-----------------------") }
我用 ffmpeg 和 youtube-dl 創建了一個管道。在測試階段,我發送了 POST 請求,但請求未完成。如果我查看日誌,我看不到“完成----------------”。我認為這個過程似乎被卡住了。你有什麼主意嗎?我的用法正確嗎?
這非常接近 - 我們還需要關閉 *io.PipeWriter
。
否則 ffmpeg
認為可以透過更多資料。這將在程式中顯示為 EOF
。
這是一個我放在一起的可運行範例,使用 echo
和 cat
來代替。您應該能夠透過註解掉新的 defer w.Close()
來重現該問題:
package main import ( "fmt" "io" "os" "os/exec" ) func main() { r, w := io.Pipe() defer r.Close() echo := exec.Command("echo", "hello") cat := exec.Command("cat") echo.Stdout = w echo.Stderr = os.Stderr cat.Stdin = r cat.Stdout = os.Stdout cat.Stderr = os.Stderr fmt.Println("Starting-----------------------") go func() { // -- I added this -- defer w.Close() if err := echo.Run(); err != nil { panic(err) } }() if err := cat.Run(); err != nil { panic(err) } fmt.Println("Done-----------------------") }
以上是Golang 使用 Run() 執行的指令沒有傳回的詳細內容。更多資訊請關注PHP中文網其他相關文章!