Home > Backend Development > Golang > The command executed by Golang using Run() does not return

The command executed by Golang using Run() does not return

WBOY
Release: 2024-02-06 10:12:03
forward
852 people have browsed it

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

Question content

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-----------------------")
}
Copy after login

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?


Correct answer


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-----------------------")
}
Copy after login

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!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template