|
|
|
|
@@ -25,7 +25,6 @@ var (
|
|
|
|
|
CandidateArrays map[string](chan string)
|
|
|
|
|
peerConnectionCount int64
|
|
|
|
|
peerConnections map[string]*pionWebRTC.PeerConnection
|
|
|
|
|
//encoder *ffmpeg.VideoEncoder
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type WebRTC struct {
|
|
|
|
|
@@ -38,24 +37,6 @@ type WebRTC struct {
|
|
|
|
|
PacketsCount chan int
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// No longer used, is for transcoding, might comeback on this!
|
|
|
|
|
/*func init() {
|
|
|
|
|
// Encoder is created for once and for all.
|
|
|
|
|
var err error
|
|
|
|
|
encoder, err = ffmpeg.NewVideoEncoderByCodecType(av.H264)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if encoder == nil {
|
|
|
|
|
err = fmt.Errorf("Video encoder not found")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
encoder.SetFramerate(30, 1)
|
|
|
|
|
encoder.SetPixelFormat(av.I420)
|
|
|
|
|
encoder.SetBitrate(1000000) // 1MB
|
|
|
|
|
encoder.SetGopSize(30 / 1) // 1s
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
func CreateWebRTC(name string, stunServers []string, turnServers []string, turnServersUsername string, turnServersCredential string) *WebRTC {
|
|
|
|
|
return &WebRTC{
|
|
|
|
|
Name: name,
|
|
|
|
|
@@ -64,7 +45,6 @@ func CreateWebRTC(name string, stunServers []string, turnServers []string, turnS
|
|
|
|
|
TurnServersUsername: turnServersUsername,
|
|
|
|
|
TurnServersCredential: turnServersCredential,
|
|
|
|
|
Timer: time.NewTimer(time.Second * 10),
|
|
|
|
|
PacketsCount: make(chan int),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -167,35 +147,37 @@ func InitializeWebRTCConnection(configuration *models.Configuration, communicati
|
|
|
|
|
log.Log.Error("webrtc.main.InitializeWebRTCConnection(): something went wrong while adding audio track: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
peerConnection.OnICEConnectionStateChange(func(connectionState pionWebRTC.ICEConnectionState) {
|
|
|
|
|
if connectionState == pionWebRTC.ICEConnectionStateDisconnected {
|
|
|
|
|
atomic.AddInt64(&peerConnectionCount, -1)
|
|
|
|
|
|
|
|
|
|
peerConnection.OnConnectionStateChange(func(connectionState pionWebRTC.PeerConnectionState) {
|
|
|
|
|
if connectionState == pionWebRTC.PeerConnectionStateDisconnected || connectionState == pionWebRTC.PeerConnectionStateClosed {
|
|
|
|
|
// Set lock
|
|
|
|
|
CandidatesMutex.Lock()
|
|
|
|
|
peerConnections[handshake.SessionID] = nil
|
|
|
|
|
atomic.AddInt64(&peerConnectionCount, -1)
|
|
|
|
|
_, ok := CandidateArrays[sessionKey]
|
|
|
|
|
if ok {
|
|
|
|
|
close(CandidateArrays[sessionKey])
|
|
|
|
|
delete(CandidateArrays, sessionKey)
|
|
|
|
|
}
|
|
|
|
|
CandidatesMutex.Unlock()
|
|
|
|
|
|
|
|
|
|
close(w.PacketsCount)
|
|
|
|
|
if err := peerConnection.Close(); err != nil {
|
|
|
|
|
log.Log.Error("webrtc.main.InitializeWebRTCConnection(): something went wrong while closing peer connection: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
} else if connectionState == pionWebRTC.ICEConnectionStateConnected {
|
|
|
|
|
peerConnections[handshake.SessionID] = nil
|
|
|
|
|
CandidatesMutex.Unlock()
|
|
|
|
|
} else if connectionState == pionWebRTC.PeerConnectionStateConnected {
|
|
|
|
|
CandidatesMutex.Lock()
|
|
|
|
|
atomic.AddInt64(&peerConnectionCount, 1)
|
|
|
|
|
} else if connectionState == pionWebRTC.ICEConnectionStateChecking {
|
|
|
|
|
CandidatesMutex.Unlock()
|
|
|
|
|
} else if connectionState == pionWebRTC.PeerConnectionStateConnecting {
|
|
|
|
|
// Iterate over the candidates and send them to the remote client
|
|
|
|
|
// Non blocking channel
|
|
|
|
|
// Non blocking channe
|
|
|
|
|
for candidate := range CandidateArrays[sessionKey] {
|
|
|
|
|
CandidatesMutex.Lock()
|
|
|
|
|
log.Log.Info("webrtc.main.InitializeWebRTCConnection(): Received candidate from channel: " + candidate)
|
|
|
|
|
if candidateErr := peerConnection.AddICECandidate(pionWebRTC.ICECandidateInit{Candidate: string(candidate)}); candidateErr != nil {
|
|
|
|
|
log.Log.Error("webrtc.main.InitializeWebRTCConnection(): something went wrong while adding candidate: " + candidateErr.Error())
|
|
|
|
|
}
|
|
|
|
|
CandidatesMutex.Unlock()
|
|
|
|
|
}
|
|
|
|
|
} else if connectionState == pionWebRTC.ICEConnectionStateFailed {
|
|
|
|
|
} else if connectionState == pionWebRTC.PeerConnectionStateFailed {
|
|
|
|
|
log.Log.Info("webrtc.main.InitializeWebRTCConnection(): ICEConnectionStateFailed")
|
|
|
|
|
}
|
|
|
|
|
log.Log.Info("webrtc.main.InitializeWebRTCConnection(): connection state changed to: " + connectionState.String())
|
|
|
|
|
@@ -220,11 +202,10 @@ func InitializeWebRTCConnection(configuration *models.Configuration, communicati
|
|
|
|
|
if candidate == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create a config map
|
|
|
|
|
valueMap := make(map[string]interface{})
|
|
|
|
|
candateJSON := candidate.ToJSON()
|
|
|
|
|
sdpmid := "0"
|
|
|
|
|
candateJSON.SDPMid = &sdpmid
|
|
|
|
|
candateBinary, err := json.Marshal(candateJSON)
|
|
|
|
|
if err == nil {
|
|
|
|
|
valueMap["candidate"] = string(candateBinary)
|
|
|
|
|
@@ -341,8 +322,8 @@ func WriteToTrack(livestreamCursor *packets.QueueCursor, configuration *models.C
|
|
|
|
|
|
|
|
|
|
var cursorError error
|
|
|
|
|
var pkt packets.Packet
|
|
|
|
|
//var previousTimeVideo int64
|
|
|
|
|
//var previousTimeAudio int64
|
|
|
|
|
var previousTimeVideo int64
|
|
|
|
|
var previousTimeAudio int64
|
|
|
|
|
|
|
|
|
|
start := false
|
|
|
|
|
receivedKeyFrame := false
|
|
|
|
|
@@ -401,16 +382,17 @@ func WriteToTrack(livestreamCursor *packets.QueueCursor, configuration *models.C
|
|
|
|
|
if pkt.IsVideo {
|
|
|
|
|
|
|
|
|
|
// Calculate the difference
|
|
|
|
|
//bufferDuration := pkt.Time - previousTimeVideo
|
|
|
|
|
//previousTimeVideo = pkt.Time
|
|
|
|
|
bufferDuration := pkt.Time - previousTimeVideo
|
|
|
|
|
previousTimeVideo = pkt.Time
|
|
|
|
|
|
|
|
|
|
// Start at the first keyframe
|
|
|
|
|
if pkt.IsKeyFrame {
|
|
|
|
|
start = true
|
|
|
|
|
}
|
|
|
|
|
if start {
|
|
|
|
|
//bufferDurationCasted := time.Duration(bufferDuration) * time.Millisecond
|
|
|
|
|
sample := pionMedia.Sample{Data: pkt.Data, PacketTimestamp: uint32(pkt.Time)}
|
|
|
|
|
bufferDurationCasted := time.Duration(bufferDuration) * time.Millisecond
|
|
|
|
|
sample := pionMedia.Sample{Data: pkt.Data, Duration: bufferDurationCasted, PacketTimestamp: uint32(pkt.Time)}
|
|
|
|
|
//sample = pionMedia.Sample{Data: pkt.Data, Duration: time.Second}
|
|
|
|
|
if config.Capture.ForwardWebRTC == "true" {
|
|
|
|
|
// We will send the video to a remote peer
|
|
|
|
|
// TODO..
|
|
|
|
|
@@ -430,15 +412,17 @@ func WriteToTrack(livestreamCursor *packets.QueueCursor, configuration *models.C
|
|
|
|
|
// We will transcode the audio
|
|
|
|
|
// TODO..
|
|
|
|
|
//d := fdkaac.NewAacDecoder()
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Calculate the difference
|
|
|
|
|
//bufferDuration := pkt.Time - previousTimeAudio
|
|
|
|
|
//previousTimeAudio = pkt.Time
|
|
|
|
|
bufferDuration := pkt.Time - previousTimeAudio
|
|
|
|
|
previousTimeAudio = pkt.Time
|
|
|
|
|
|
|
|
|
|
// We will send the audio
|
|
|
|
|
//bufferDurationCasted := time.Duration(bufferDuration) * time.Millisecond
|
|
|
|
|
sample := pionMedia.Sample{Data: pkt.Data, PacketTimestamp: uint32(pkt.Time)}
|
|
|
|
|
bufferDurationCasted := time.Duration(bufferDuration) * time.Millisecond
|
|
|
|
|
sample := pionMedia.Sample{Data: pkt.Data, Duration: bufferDurationCasted, PacketTimestamp: uint32(pkt.Time)}
|
|
|
|
|
//sample = pionMedia.Sample{Data: pkt.Data, Duration: time.Second}
|
|
|
|
|
if err := audioTrack.WriteSample(sample); err != nil && err != io.ErrClosedPipe {
|
|
|
|
|
log.Log.Error("webrtc.main.WriteToTrack(): something went wrong while writing sample: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
|