| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -11,10 +11,10 @@ import ( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						"time" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						"github.com/Monibuca/engine/v3" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						. "github.com/Monibuca/plugin-rtp" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						"github.com/Monibuca/utils/v3" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						"github.com/Monibuca/utils/v3/codec" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						"github.com/pion/rtcp" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						"github.com/pion/rtp" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						. "github.com/pion/webrtc/v3" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						"github.com/pion/webrtc/v3/pkg/media" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					) | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -52,9 +52,11 @@ var config struct { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// 	conn *net.UDPConn
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// 	port int
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					var playWaitList WaitList | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					var reg_level = regexp.MustCompile("profile-level-id=(4.+f)") | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					var ( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						playWaitList WaitList | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						reg_level    = regexp.MustCompile("profile-level-id=(4.+f)") | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						api          *API | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					type WaitList struct { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						m map[string]*WebRTC | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -84,17 +86,11 @@ func init() { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					type WebRTC struct { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						RTP | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						engine.Publisher | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						*PeerConnection | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						RemoteAddr string | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						audioTrack *TrackLocalStaticSample | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						videoTrack *TrackLocalStaticSample | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						m          MediaEngine | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						s          SettingEngine | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						api        *API | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						payloader  codec.H264 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// codecs.H264Packet
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// *os.File
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					func (rtc *WebRTC) Play(streamPath string) bool { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -102,83 +98,53 @@ func (rtc *WebRTC) Play(streamPath string) bool { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						sub.ID = rtc.RemoteAddr | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						sub.Type = "WebRTC" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						var lastTimeStampV, lastTiimeStampA uint32 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						onVideo := func(pack engine.VideoPack){ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
										var s uint32 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								if lastTimeStampV > 0 { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									s = pack.Timestamp - lastTimeStampV | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								lastTimeStampV = pack.Timestamp | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								if pack.NalType == codec.NALU_IDR_Picture { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									rtc.videoTrack.WriteSample(media.Sample{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
										Data:sub.VideoTracks[0].SPS, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									}) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									rtc.videoTrack.WriteSample(media.Sample{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
										Data:sub.VideoTracks[0].PPS, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									}) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						onVideo := func(pack engine.VideoPack) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							var s uint32 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if lastTimeStampV > 0 { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								s = pack.Timestamp - lastTimeStampV | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							lastTimeStampV = pack.Timestamp | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if pack.NalType == codec.NALU_IDR_Picture { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								rtc.videoTrack.WriteSample(media.Sample{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									Data: sub.VideoTracks[0].SPS, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								}) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								rtc.videoTrack.WriteSample(media.Sample{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									Data: sub.VideoTracks[0].PPS, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								}) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							rtc.videoTrack.WriteSample(media.Sample{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								Data:pack.Payload, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								Duration:time.Millisecond*time.Duration(s), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								Data:     pack.Payload, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								Duration: time.Millisecond * time.Duration(s), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							}) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						onAudio := func(pack engine.AudioPack){ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						onAudio := func(pack engine.AudioPack) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							var s uint32 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								if lastTiimeStampA > 0 { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									s = pack.Timestamp - lastTiimeStampA | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								lastTiimeStampA = pack.Timestamp | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if lastTiimeStampA > 0 { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								s = pack.Timestamp - lastTiimeStampA | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							lastTiimeStampA = pack.Timestamp | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							rtc.audioTrack.WriteSample(media.Sample{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					           Data:pack.Payload,Duration: time.Millisecond*time.Duration(s), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								Data: pack.Payload, Duration: time.Millisecond * time.Duration(s), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							}) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// sub.OnData = func(packet *codec.SendPacket) error {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 	if packet.Type == codec.FLV_TAG_TYPE_AUDIO {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 		var s uint32
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 		if lastTiimeStampA > 0 {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 			s = packet.Timestamp - lastTiimeStampA
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 		}
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 		lastTiimeStampA = packet.Timestamp
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 		rtc.audioTrack.WriteSample(media.Sample{
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 			Data:    packet.Payload[1:],
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 			Samples: s * 8,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 		})
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 		return nil
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 	}
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 	if packet.IsSequence {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 		rtc.payloader.PPS = sub.PPS
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 		rtc.payloader.SPS = sub.SPS
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 	} else {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 		var s uint32
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 		if lastTimeStampV > 0 {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 			s = packet.Timestamp - lastTimeStampV
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 		}
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 		lastTimeStampV = packet.Timestamp
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 		rtc.videoTrack.WriteSample(media.Sample{
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 			Data:    packet.Payload,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 			Samples: s * 90,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 		})
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 	}
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 	return nil
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// go sub.Subscribe(streamPath)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						rtc.OnICEConnectionStateChange(func(connectionState ICEConnectionState) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							utils.Printf("%s Connection State has changed %s ", streamPath, connectionState.String()) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							switch connectionState { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							case ICEConnectionStateDisconnected: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							case ICEConnectionStateDisconnected, ICEConnectionStateFailed: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								sub.Close() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								rtc.Close() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								rtc.PeerConnection.Close() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							case ICEConnectionStateConnected: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								//rtc.videoTrack = rtc.GetSenders()[0].Track()
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								if err := sub.Subscribe(streamPath);err== nil { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									go sub.VideoTracks[0].Play(sub.Context,onVideo) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									go sub.AudioTracks[0].Play(sub.Context,onAudio) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								if err := sub.Subscribe(streamPath); err == nil { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									go sub.VideoTracks[0].Play(sub.Context, onVideo) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									if rtc.audioTrack != nil { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
										go sub.AudioTracks[0].Play(sub.Context, onAudio) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						}) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						return true | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					func (rtc *WebRTC) Publish(streamPath string) bool { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						rtc.m.RegisterDefaultCodecs() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// rtc.m.RegisterCodec(NewRTPCodec(RTPCodecTypeVideo,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 	H264,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 	90000,
 | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -193,19 +159,16 @@ func (rtc *WebRTC) Publish(streamPath string) bool { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 	}, RTPCodecTypeVideo);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						//m.RegisterCodec(NewRTPPCMUCodec(DefaultPayloadTypePCMU, 8000))
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if !strings.HasPrefix(rtc.RemoteAddr, "127.0.0.1") && !strings.HasPrefix(rtc.RemoteAddr, "[::1]") { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							rtc.s.SetNAT1To1IPs(config.PublicIP, ICECandidateTypeHost) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if config.PortMin > 0 && config.PortMax > 0 { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							rtc.s.SetEphemeralUDPPortRange(config.PortMin, config.PortMax) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						rtc.api = NewAPI(WithMediaEngine(&rtc.m), WithSettingEngine(rtc.s)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						peerConnection, err := rtc.api.NewPeerConnection(Configuration{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							ICEServers: []ICEServer{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									URLs: config.ICEServers, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								}, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							}, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// if !strings.HasPrefix(rtc.RemoteAddr, "127.0.0.1") && !strings.HasPrefix(rtc.RemoteAddr, "[::1]") {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// 	rtc.s.SetNAT1To1IPs(config.PublicIP, ICECandidateTypeHost)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						peerConnection, err := api.NewPeerConnection(Configuration{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// ICEServers: []ICEServer{
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 	{
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 		URLs: config.ICEServers,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 	},
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// },
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						}) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if err != nil { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							utils.Println(err) | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -230,7 +193,7 @@ func (rtc *WebRTC) Publish(streamPath string) bool { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						}) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						rtc.PeerConnection = peerConnection | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if rtc.RTP.Publish(streamPath) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if rtc.Publish(streamPath) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							//f, _ := os.OpenFile("resource/live/rtc.h264", os.O_TRUNC|os.O_WRONLY, 0666)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							rtc.Stream.Type = "WebRTC" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							peerConnection.OnTrack(func(track *TrackRemote, receiver *RTPReceiver) { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -246,19 +209,23 @@ func (rtc *WebRTC) Publish(streamPath string) bool { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
										return | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								}() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								pack := &RTPPack{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									Type: RTPType(track.Kind() - 1), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								var etrack engine.Track | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								if track.Kind() == RTPCodecTypeAudio { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									etrack = rtc.AudioTracks[0] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									etrack = rtc.VideoTracks[0] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								for b := make([]byte, 1460); ; rtc.PushPack(pack) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									i,_, err := track.Read(b) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								var pack rtp.Packet | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								b := make([]byte, 1460) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								for { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									i, _, err := track.Read(b) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									if err != nil { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
										return | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									if err = pack.Unmarshal(b[:i]); err != nil { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
										return | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									// rtc.Unmarshal(pack.Payload)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									// f.Write(bytes)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									etrack.Push(pack.Timestamp, pack.Payload) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							}) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} else { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -272,12 +239,13 @@ func (rtc *WebRTC) GetAnswer() ([]byte, error) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if err != nil { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							return nil, err | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						//gatherComplete := webrtc.GatheringCompletePromise(rtc.PeerConnection)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						gatherComplete := GatheringCompletePromise(rtc.PeerConnection) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if err := rtc.SetLocalDescription(answer); err != nil { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							utils.Println(err) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							return nil, err | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if bytes, err := json.Marshal(answer); err != nil { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						<-gatherComplete | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if bytes, err := json.Marshal(rtc.LocalDescription()); err != nil { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							utils.Println(err) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							return bytes, err | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} else { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -286,6 +254,13 @@ func (rtc *WebRTC) GetAnswer() ([]byte, error) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					func run() { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						var m MediaEngine | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						var s SettingEngine | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if config.PortMin > 0 && config.PortMax > 0 { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							s.SetEphemeralUDPPortRange(config.PortMin, config.PortMax) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						m.RegisterDefaultCodecs() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						api = NewAPI(WithMediaEngine(&m), WithSettingEngine(s)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						http.HandleFunc("/webrtc/play", func(w http.ResponseWriter, r *http.Request) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							w.Header().Set("Access-Control-Allow-Credentials", "true") | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							origin := r.Header["Origin"] | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -324,36 +299,8 @@ func run() { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if !strings.Contains(offer.SDP, pli) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								pli = reg_level.FindAllStringSubmatch(offer.SDP, -1)[0][1] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// rtc.m.RegisterCodec(NewRTPCodec(RTPCodecTypeVideo,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 	H264,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 	90000,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 	0,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 	"level-asymmetry-allowed=1;packetization-mode=1;profile-level-id="+pli,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 	DefaultPayloadTypeH264,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 	&rtc.payloader))
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							rtc.m.RegisterDefaultCodecs() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// rtc.m.RegisterCodec(RTPCodecParameters{
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 		RTPCodecCapability: RTPCodecCapability{MimeType: "video/h264", ClockRate: 90000, Channels: 0, SDPFmtpLine: "", RTCPFeedback: nil},
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 		PayloadType:        102,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 	  }, RTPCodecTypeVideo);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// rtc.m.RegisterCodec(NewRTPPCMACodec(DefaultPayloadTypePCMA, 8000))
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// if !strings.HasPrefix(r.RemoteAddr, "127.0.0.1") && !strings.HasPrefix(r.RemoteAddr, "[::1]") {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 	rtc.s.SetNAT1To1IPs(config.PublicIP, ICECandidateTypeHost)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if config.PortMin > 0 && config.PortMax > 0 { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								rtc.s.SetEphemeralUDPPortRange(config.PortMin, config.PortMax) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							rtc.api = NewAPI(WithMediaEngine(&rtc.m), WithSettingEngine(rtc.s)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if rtc.PeerConnection, err = rtc.api.NewPeerConnection(Configuration{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								// ICEServers: []ICEServer{
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								// 	{
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								// 		URLs: config.ICEServers,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								// 	},
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								// },
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							}); err != nil { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if rtc.PeerConnection, err = api.NewPeerConnection(Configuration{}); err != nil { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								return | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							rtc.OnICECandidate(func(ice *ICECandidate) { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -361,35 +308,11 @@ func run() { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									utils.Println(ice.ToJSON().Candidate) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							}) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// if r, err := peerConnection.AddTransceiverFromKind(RTPCodecTypeVideo); err == nil {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 	rtc.videoTrack = r.Sender().Track()
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// } else {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 	Println(err)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							rtc.RemoteAddr = r.RemoteAddr | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if err = rtc.SetRemoteDescription(offer); err != nil { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								return | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// rtc.m.PopulateFromSDP(offer)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// var vpayloadType uint8 = 0
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// for _, videoCodec := range rtc.m.GetCodecsByKind(RTPCodecTypeVideo) {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 	if videoCodec.Name == H264 {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 		vpayloadType = videoCodec.PayloadType
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 		videoCodec.Payloader = &rtc.payloader
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 		Printf("H264 fmtp %v", videoCodec.SDPFmtpLine)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 	}
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// println(vpayloadType)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// if rtc.videoTrack, err = rtc.Track(DefaultPayloadTypeH264, 8, "video", "monibuca"); err != nil {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 	return
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// if rtc.audioTrack, err = rtc.Track(DefaultPayloadTypePCMA, 9, "audio", "monibuca"); err != nil {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// 	return
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							// }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if rtc.videoTrack,err = NewTrackLocalStaticSample(RTPCodecCapability{MimeType:"video/h264",SDPFmtpLine: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id="+pli},"video","m7s");err!=nil{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if rtc.videoTrack, err = NewTrackLocalStaticSample(RTPCodecCapability{MimeType: "video/h264", SDPFmtpLine: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=" + pli}, "video", "m7s"); err != nil { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								return | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if _, err = rtc.AddTrack(rtc.videoTrack); err != nil { | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |