有没有人使用 go-av 解析 mp4 音频然后使用 oto/portaudio 输出它?

问题描述

使用 go-av 获取音频

func audio() (<-chan []byte,error) {
    buffer := make(chan []byte,1024)
    go func() {
     ......
      for inCtx.AvReadFrame(pkt) >= 0 {
            if pkt.StreamIndex() == audioStreamIndex {
                l := pCodecCtx.AvcodecDecodeAudio4((*avcodec.Frame)(unsafe.Pointer(utilFrame)),&gotName,pkt)
                //fmt.Println("AvcodecDecodeAudio4:",l)
                if l < 0 {
                    fmt.Println("codec decode audio4 error")
                    os.Exit(1)
                }
                if gotName > 0 {

                    fram := getFramBytes(utilFrame)
                    fmt.Println("buf add:",index)
                    buffer <- fram

                }
            }
            pkt.AvFreePacket()
        }
        go func() {
            for {
                if len(buffer) <= 0 {
                    fmt.Println("close buf")
                    close(buffer)
                    break
                }
            }
        }()

        (*avcodec.Context)(unsafe.Pointer(pCodecCtxOrig)).Avcodecclose()
    }()
    return buffer,nil
}
func getFramBytes(f *avutil.Frame) []byte {
    data := avutil.Data(f)
    var bf = make([]byte,len(data))
    for i := 0; i < len(data); i++ {

        if data[i] != nil {
            bf = append(bf,*data[i])
        }
    }
    return bf
}

然后输出

func main() {

    portaudio.Initialize()
    defer portaudio.Terminate()
    out := make([]int32,8192)
    stream,err := portaudio.OpenDefaultStream(0,1,44100,len(out),&out)
    defer stream.Close()
    if err != nil {
        fmt.Println(err)
        return
    }
    err = stream.Start()
    if err != nil {
        fmt.Println(err)
        return
    }
    defer stream.Stop()
    buf,err := audio()
    if err != nil {
        fmt.Println(err)
        return
    }
    //index := 0
    //c,err := oto.NewContext(44100,2,8192)
    //if err != nil {
    //  return
    //}
    //defer c.Close()
    //
    //p := c.NewPlayer()
    //defer p.Close()
    for {
        select {
        case frame,ok := <-buf:
            if !ok {
                os.Exit(0)
            }
            //index += 1
            //fmt.Println("$$:",index)
            //if _,err := io.copy(p,bytes.NewReader(frame)); err != nil {
            //  fmt.Println(err)
            //  return
            //}
            err := binary.Read(bytes.NewReader(frame),binary.BigEndian,out)
            if err != nil {
                fmt.Println("binary.Read:",err)
                os.Exit(0)
            }
            err = stream.Write()
            if err != nil {
                fmt.Println("stream.Write:",err)
                os.Exit(0)
            }
        }
    }

}

** 结果是**

binary.Read:意外的 EOF

如果使用oto则没有效果

有没有人用过这个方法,或者有没有其他方法可以用go-av播放音视频?

使用上有问题吗?感觉是音频解码的数据转换有问题。

可能是getFramBytes有问题

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)