Rumah >pembangunan bahagian belakang >Golang >Perintah yang dilaksanakan oleh Golang menggunakan Run() tidak kembali

Perintah yang dilaksanakan oleh Golang menggunakan Run() tidak kembali

WBOY
WBOYke hadapan
2024-02-06 10:12:03863semak imbas

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

Kandungan soalan

Saya cuba mencipta perkhidmatan penstriman muzik menggunakan youtube-dl dan ffmpeg. Apabila pengguna menghantar permintaan POST dengan URL video, kod pengendali saya berfungsi seperti ini:

 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-----------------------")
}

Saya mencipta saluran paip menggunakan ffmpeg dan youtube-dl. Semasa fasa ujian, saya menghantar permintaan POST, tetapi permintaan itu tidak diselesaikan. Jika saya lihat pada log, saya tidak nampak "Lengkap----------------". Saya rasa proses itu nampaknya tersekat. Adakah anda mempunyai sebarang idea? Adakah penggunaan saya betul?


Jawapan betul


Ini agak dekat - kita masih perlu tutup *io.PipeWriter .

Jika tidak ffmpeg 认为可以通过更多数据。这将在程序中显示为 EOF.

Berikut ialah contoh runnable yang saya kumpulkan untuk menghasilkan semula isu menggunakan 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-----------------------")
}

Atas ialah kandungan terperinci Perintah yang dilaksanakan oleh Golang menggunakan Run() tidak kembali. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam