首頁 >後端開發 >Golang >Golang 使用 Run() 執行的指令沒有傳回

Golang 使用 Run() 執行的指令沒有傳回

WBOY
WBOY轉載
2024-02-06 10:12:03863瀏覽

Golang 使用 Run() 执行的命令没有返回

問題內容

我正在嘗試使用 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

這是一個我放在一起的可運行範例,使用 echocat 來代替。您應該能夠透過註解掉新的 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中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除