Skip to content

Receive audio with ffmpeg #108

Closed
Closed
@projetoarduino

Description

@projetoarduino

I'm trying to change the gstreamer-receive example to use ffmpeg, can someone tell me what I'm doing wrong because I don't hear any audio when I run the software

package main

import (
	"fmt"
	"time"
	"os"
    "os/exec"

	"github.com/pion/rtcp"
	"github.com/pion/webrtc/v3"
	//gst "gstreamer-sink"
)

func check(err error) {
	if err != nil {
		panic(err)
	}
}

func main() {
	// Prepare the configuration
	config := webrtc.Configuration{
		ICEServers: []webrtc.ICEServer{
			{
				URLs: []string{"stun:stun.l.google.com:19302"},
			},
		},
	}

	// Create a new RTCPeerConnection
	peerConnection, err := webrtc.NewPeerConnection(config)
	if err != nil {
		panic(err)
	}

	// Set a handler for when a new remote track starts, this handler creates a gstreamer pipeline
	// for the given codec
	peerConnection.OnTrack(func(track *webrtc.TrackRemote, receiver *webrtc.RTPReceiver) {

		// Send a PLI on an interval so that the publisher is pushing a keyframe every rtcpPLIInterval
		go func() {
			ticker := time.NewTicker(time.Second * 3)
			for range ticker.C {
				rtcpSendErr := peerConnection.WriteRTCP([]rtcp.Packet{&rtcp.PictureLossIndication{MediaSSRC: uint32(track.SSRC())}})
				if rtcpSendErr != nil {
					fmt.Println(rtcpSendErr)
				}				
			}
		}()

		//codecName := strings.Split(track.Codec().RTPCodecCapability.MimeType, "/")[1]
		//fmt.Printf("Track has started, of type %d: %s \n", track.PayloadType(), codecName)
		//pipeline := gst.CreatePipeline(track.PayloadType(), strings.ToLower(codecName))
		//pipeline.Start()
		
		buf := make([]byte, 1400)
		chBuff := make(chan []byte, 1400)

		go playTrack(chBuff)

		for {
			i, _, readErr := track.Read(buf)
			if readErr != nil {
				panic(err)
			}
			chBuff <- buf[:i]
			//pipeline.Push(buf[:i])
			//fmt.Printf("%x", buf[:i])
			//fmt.Println(track.PayloadType())			
		}
	})

	// Set the handler for ICE connection state
	// This will notify you when the peer has connected/disconnected
	peerConnection.OnICEConnectionStateChange(func(connectionState webrtc.ICEConnectionState) {
		fmt.Printf("Connection State has changed %s \n", connectionState.String())
	})

	// Wait for the offer to be pasted
	offer := webrtc.SessionDescription{}
	Decode(MustReadStdin(), &offer)

	// Set the remote SessionDescription
	err = peerConnection.SetRemoteDescription(offer)
	if err != nil {
		panic(err)
	}

	// Create an answer
	answer, err := peerConnection.CreateAnswer(nil)
	if err != nil {
		panic(err)
	}

	// Create channel that is blocked until ICE Gathering is complete
	gatherComplete := webrtc.GatheringCompletePromise(peerConnection)

	// Sets the LocalDescription, and starts our UDP listeners
	err = peerConnection.SetLocalDescription(answer)
	if err != nil {
		panic(err)
	}

	// Block until ICE Gathering is complete, disabling trickle ICE
	// we do this because we only can exchange one signaling message
	// in a production application you should exchange ICE Candidates via OnICECandidate
	<-gatherComplete

	// Output the answer in base64 so we can paste it in browser
	fmt.Println(Encode(*peerConnection.LocalDescription()))

	// Block forever
	select {}
}

func playTrack(ch <-chan []byte){
	//cmd := exec.Command("ffmpeg", "-i", "pipe:0", "-f", "alsa", "default")
	cmd:= exec.Command("ffmpeg", "-i", "pipe:0", "-c:a", "copy", "-sample_fmt", "s16p", "-ssrc", "1", "-payload_type", "111",  "-b", "96k", "-f", "alsa", "default")

    cmd.Stderr = os.Stderr // bind log stream to stderr
    //cmd.Stdout = resultBuffer // stdout result will be written here

    stdin, err := cmd.StdinPipe() // Open stdin pipe
    check(err)

    err = cmd.Start() // Start a process on another goroutine
    check(err)

	for {
    	_, err = stdin.Write(<-ch) // pump audio data to stdin pipe
    	check(err)
	}

    err = stdin.Close() // close the stdin, or ffmpeg will wait forever
    check(err)

    err = cmd.Wait() // wait until ffmpeg finish
    check(err)
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions