I'm trying to create a music streaming service using youtube-dl and ffmpeg. When the user sends a POST request with the video URL, my handler code works like this:
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-----------------------") }
I created a pipeline using ffmpeg and youtube-dl. During the testing phase, I sent a POST request, but the request was not completed. If I look at the logs, I don't see "Complete----------------". I think the process seems to be stuck. Do you have any ideas? Is my usage correct?
This is pretty close - we also need to close *io.PipeWriter
.
Otherwise ffmpeg
thinks more data can be passed. This will appear in the program as EOF
.
Here's a runnable example I put together, using echo
and cat
instead. You should be able to reproduce the issue by commenting out the new 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-----------------------") }
The above is the detailed content of The command executed by Golang using Run() does not return. For more information, please follow other related articles on the PHP Chinese website!