溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Golang怎么調(diào)用FFmpeg轉(zhuǎn)換視頻流

發(fā)布時(shí)間:2023-02-24 11:38:22 來源:億速云 閱讀:114 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“Golang怎么調(diào)用FFmpeg轉(zhuǎn)換視頻流”,在日常操作中,相信很多人在Golang怎么調(diào)用FFmpeg轉(zhuǎn)換視頻流問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Golang怎么調(diào)用FFmpeg轉(zhuǎn)換視頻流”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!

    問題背景

    問題背景是在,由于視頻采集端使用的是H264編碼采集的裸流,而網(wǎng)絡(luò)流媒體大多是以FLV為主的直播方式進(jìn)行的,為了實(shí)現(xiàn)實(shí)時(shí)直播,當(dāng)前是打算直接使用FFmpeg將H264裸流實(shí)時(shí)轉(zhuǎn)成FLV視頻流。

    為什么是使用FLV視頻流呢,因?yàn)橄鄬?duì)簡(jiǎn)單,加上FLV Header后將每個(gè)NALU打包成Tag并進(jìn)去大致就行了。但是這塊怕有疏忽,最終還是想使用成熟的工具FFmpeg。

    方法實(shí)現(xiàn)

    1. 使用FFmpeg-go封裝好的方法

    FFmpeg-go

    上面有具體的Demo,但是只有流轉(zhuǎn)文件,也只有文件轉(zhuǎn)流的方法,對(duì)于流轉(zhuǎn)流還是需要自己動(dòng)手處理一下。

    import ffmpeg "github.com/u2takey/ffmpeg-go"
     
    err := ffmpeg.Input("pipe:", ffmpeg.KwArgs{
            "format":     "rawvideo",
            "video_size": fmt.Sprintf("%dx%d", 480, 1064)}).WithInput(filein).
            Output("pipe:",
                ffmpeg.KwArgs{"c:v": "libx264", "f": "flv", "crf": "24"}).
            WithOutput(buf, errorbuf).
            Run()
    if err != nil {
            panic(err)
    }
    bufs := make([]byte, 1024)
    out, _ := os.OpenFile("res2.flv", os.O_CREATE|os.O_RDWR|os.O_APPEND, 0644)
    for {
        n, err := buf.Read(bufs)
        if n == 0 || err == io.EOF {
            out.Close()
            break
        } else {
            //此處處理輸出流,這邊簡(jiǎn)單地寫到文件里
            out.Write(bufs)
        }
    }

    其中

    filein   是輸入的H264視頻裸流   buf是輸出的視頻流
    雖說代碼是這么寫,但是實(shí)際上是run不起來的,不清楚具體是什么原因,因此后續(xù)還是打算直接調(diào)用ffmpeg可執(zhí)行程序。

    2. 直接調(diào)用FFmpeg

    首先需要在電腦上下載好ffmpeg并且添加到環(huán)境變量,保證執(zhí)行Powshell或者cmd指令的ffmpeg時(shí)能夠正常運(yùn)行,接下來還是直接上代碼。

    cmd := exec.Command("ffmpeg", "-re", "-r", "30", "-i", "pipe:0", "-vcodec", "libx264", "-f", "flv", "pipe:1", "-y", "another.flv")
     
    //獲取輸入流
    stdin, err := cmd.StdinPipe()
    if err != nil {
        fmt.Println("Error getting stdout pipe:", err)
        return
    }
     
    //要寫東西進(jìn)去的時(shí)候只需要
    stdin.Write(bytes) 
     
    //獲取輸出流
    stdout, err := cmd.StdoutPipe()
    if err != nil {
        fmt.Println("Error getting stdout pipe:", err)
        return
    }
     
    // Start the command
    err = cmd.Start()
    if err != nil {
        fmt.Println("Error starting command:", err)
        return
    }

    這邊需要注意到的點(diǎn)是,如果不加上"-re"的話,需要等stdin.close()之后,整個(gè)ffmpeg才會(huì)運(yùn)行,才能見到有輸出流。

    其次,這邊加了 “-y” "another.flv",是用來進(jìn)行對(duì)比的,這里ffmpeg將會(huì)把輸出同時(shí)放在兩個(gè)地方,一個(gè)寫入到文件another.flv里(-y 是覆蓋原有文件),另一個(gè)通過stdout傳出來,我將stdout的數(shù)據(jù)流保存成out.flv后發(fā)現(xiàn)同another.flv對(duì)比發(fā)現(xiàn)并不相同?;蛟S視頻流和文件不應(yīng)該這么處理。

    到此,關(guān)于“Golang怎么調(diào)用FFmpeg轉(zhuǎn)換視頻流”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI