微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决有没有人使用 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 举报,一经查实,本站将立刻删除。