我正在尝试使用 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中文网其他相关文章!