mirror of
https://github.com/pion/webrtc.git
synced 2025-10-01 05:22:14 +08:00
Fix all golint errors
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
*.ivf
|
*.ivf
|
||||||
|
tags
|
||||||
|
@@ -11,24 +11,27 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Pipeline is a wrapper for a GStreamer Pipeline
|
||||||
type Pipeline struct {
|
type Pipeline struct {
|
||||||
Pipeline *C.GstElement
|
Pipeline *C.GstElement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreatePipeline creates a GStreamer Pipeline
|
||||||
func CreatePipeline() *Pipeline {
|
func CreatePipeline() *Pipeline {
|
||||||
p := &Pipeline{}
|
return &Pipeline{Pipeline: C.gst_create_pipeline()}
|
||||||
p.Pipeline = C.gst_create_pipeline()
|
|
||||||
return p
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start starts the GStreamer Pipeline
|
||||||
func (p *Pipeline) Start() {
|
func (p *Pipeline) Start() {
|
||||||
C.gst_start_pipeline(p.Pipeline)
|
C.gst_start_pipeline(p.Pipeline)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stop stops the GStreamer Pipeline
|
||||||
func (p *Pipeline) Stop() {
|
func (p *Pipeline) Stop() {
|
||||||
C.gst_stop_pipeline(p.Pipeline)
|
C.gst_stop_pipeline(p.Pipeline)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Push pushes a buffer on the appsrc of the GStreamer Pipeline
|
||||||
func (p *Pipeline) Push(buffer []byte) {
|
func (p *Pipeline) Push(buffer []byte) {
|
||||||
b := C.CBytes(buffer)
|
b := C.CBytes(buffer)
|
||||||
defer C.free(unsafe.Pointer(b))
|
defer C.free(unsafe.Pointer(b))
|
||||||
|
@@ -9,7 +9,7 @@ import (
|
|||||||
"github.com/pions/webrtc/pkg/rtp/codecs"
|
"github.com/pions/webrtc/pkg/rtp/codecs"
|
||||||
)
|
)
|
||||||
|
|
||||||
type IVFWriter struct {
|
type ivfWriter struct {
|
||||||
fd *os.File
|
fd *os.File
|
||||||
count uint64
|
count uint64
|
||||||
currentFrame []byte
|
currentFrame []byte
|
||||||
@@ -21,7 +21,7 @@ func panicWrite(fd *os.File, data []byte) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIVFWriter(fileName string) (*IVFWriter, error) {
|
func newIVFWriter(fileName string) (*ivfWriter, error) {
|
||||||
f, err := os.Create(fileName)
|
f, err := os.Create(fileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -41,11 +41,11 @@ func NewIVFWriter(fileName string) (*IVFWriter, error) {
|
|||||||
|
|
||||||
panicWrite(f, header)
|
panicWrite(f, header)
|
||||||
|
|
||||||
i := &IVFWriter{fd: f}
|
i := &ivfWriter{fd: f}
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IVFWriter) AddPacket(packet *rtp.Packet) {
|
func (i *ivfWriter) addPacket(packet *rtp.Packet) {
|
||||||
|
|
||||||
vp8Packet := codecs.VP8Packet{}
|
vp8Packet := codecs.VP8Packet{}
|
||||||
err := vp8Packet.Unmarshal(packet)
|
err := vp8Packet.Unmarshal(packet)
|
||||||
@@ -66,14 +66,10 @@ func (i *IVFWriter) AddPacket(packet *rtp.Packet) {
|
|||||||
binary.LittleEndian.PutUint32(frameHeader[0:], uint32(len(i.currentFrame))) // Frame length
|
binary.LittleEndian.PutUint32(frameHeader[0:], uint32(len(i.currentFrame))) // Frame length
|
||||||
binary.LittleEndian.PutUint64(frameHeader[4:], i.count) // PTS
|
binary.LittleEndian.PutUint64(frameHeader[4:], i.count) // PTS
|
||||||
|
|
||||||
i.count += 1
|
i.count++
|
||||||
|
|
||||||
panicWrite(i.fd, frameHeader)
|
panicWrite(i.fd, frameHeader)
|
||||||
panicWrite(i.fd, i.currentFrame)
|
panicWrite(i.fd, i.currentFrame)
|
||||||
|
|
||||||
i.currentFrame = nil
|
i.currentFrame = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IVFWriter) Close() error {
|
|
||||||
return i.fd.Close()
|
|
||||||
}
|
|
||||||
|
@@ -41,12 +41,12 @@ func main() {
|
|||||||
track := atomic.AddUint64(&trackCount, 1)
|
track := atomic.AddUint64(&trackCount, 1)
|
||||||
fmt.Printf("Track %d has started \n", track)
|
fmt.Printf("Track %d has started \n", track)
|
||||||
|
|
||||||
i, err := NewIVFWriter(fmt.Sprintf("output-%d.ivf", track))
|
i, err := newIVFWriter(fmt.Sprintf("output-%d.ivf", track))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
i.AddPacket(<-packets)
|
i.addPacket(<-packets)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
@@ -24,7 +24,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var listenerMap map[string]*ipv4.PacketConn = make(map[string]*ipv4.PacketConn)
|
var listenerMap = make(map[string]*ipv4.PacketConn)
|
||||||
var listenerMapLock = &sync.Mutex{}
|
var listenerMapLock = &sync.Mutex{}
|
||||||
|
|
||||||
//export go_handle_sendto
|
//export go_handle_sendto
|
||||||
@@ -37,7 +37,7 @@ func go_handle_sendto(rawSrc *C.char, rawDst *C.char, rawBuf *C.char, rawBufLen
|
|||||||
listenerMapLock.Lock()
|
listenerMapLock.Lock()
|
||||||
defer listenerMapLock.Unlock()
|
defer listenerMapLock.Unlock()
|
||||||
if conn, ok := listenerMap[src]; ok {
|
if conn, ok := listenerMap[src]; ok {
|
||||||
strIp, strPort, err := net.SplitHostPort(dst)
|
strIP, strPort, err := net.SplitHostPort(dst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return
|
return
|
||||||
@@ -47,7 +47,7 @@ func go_handle_sendto(rawSrc *C.char, rawDst *C.char, rawBuf *C.char, rawBufLen
|
|||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, err = conn.WriteTo(buf, nil, &net.UDPAddr{IP: net.ParseIP(strIp), Port: port})
|
_, err = conn.WriteTo(buf, nil, &net.UDPAddr{IP: net.ParseIP(strIP), Port: port})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
@@ -56,69 +56,78 @@ func go_handle_sendto(rawSrc *C.char, rawDst *C.char, rawBuf *C.char, rawBufLen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TLSCfg holds the Certificate/PrivateKey used for a single RTCPeerConnection
|
||||||
type TLSCfg struct {
|
type TLSCfg struct {
|
||||||
tlscfg *_Ctype_struct_tlscfg
|
tlscfg *_Ctype_struct_tlscfg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewTLSCfg creates a new TLSCfg
|
||||||
func NewTLSCfg() *TLSCfg {
|
func NewTLSCfg() *TLSCfg {
|
||||||
return &TLSCfg{
|
return &TLSCfg{
|
||||||
tlscfg: C.dtls_build_tlscfg(),
|
tlscfg: C.dtls_build_tlscfg(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fingerprint generates a SHA-256 fingerprint of the certificate
|
||||||
func (t *TLSCfg) Fingerprint() string {
|
func (t *TLSCfg) Fingerprint() string {
|
||||||
rawFingerprint := C.dtls_tlscfg_fingerprint(t.tlscfg)
|
rawFingerprint := C.dtls_tlscfg_fingerprint(t.tlscfg)
|
||||||
defer C.free(unsafe.Pointer(rawFingerprint))
|
defer C.free(unsafe.Pointer(rawFingerprint))
|
||||||
return C.GoString(rawFingerprint)
|
return C.GoString(rawFingerprint)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close cleans up the associated OpenSSL resources
|
||||||
func (t *TLSCfg) Close() {
|
func (t *TLSCfg) Close() {
|
||||||
C.dtls_tlscfg_cleanup(t.tlscfg)
|
C.dtls_tlscfg_cleanup(t.tlscfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
type DTLSState struct {
|
// State represents all the state needed for a DTLS session
|
||||||
|
type State struct {
|
||||||
*TLSCfg
|
*TLSCfg
|
||||||
sslctx *_Ctype_struct_ssl_ctx_st
|
sslctx *_Ctype_struct_ssl_ctx_st
|
||||||
dtls_session *_Ctype_struct_dtls_sess
|
dtlsSession *_Ctype_struct_dtls_sess
|
||||||
rawSrc, rawDst *_Ctype_char
|
rawSrc, rawDst *_Ctype_char
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDTLSState(tlscfg *TLSCfg, isClient bool, src, dst string) (d *DTLSState, err error) {
|
// NewState creates a new DTLS session
|
||||||
|
func NewState(tlscfg *TLSCfg, isClient bool, src, dst string) (d *State, err error) {
|
||||||
if tlscfg == nil || tlscfg.tlscfg == nil {
|
if tlscfg == nil || tlscfg.tlscfg == nil {
|
||||||
return d, errors.Errorf("TLSCfg must not be nil")
|
return d, errors.Errorf("TLSCfg must not be nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
d = &DTLSState{
|
d = &State{
|
||||||
TLSCfg: tlscfg,
|
TLSCfg: tlscfg,
|
||||||
rawSrc: C.CString(src),
|
rawSrc: C.CString(src),
|
||||||
rawDst: C.CString(dst),
|
rawDst: C.CString(dst),
|
||||||
}
|
}
|
||||||
|
|
||||||
d.sslctx = C.dtls_build_sslctx(d.tlscfg)
|
d.sslctx = C.dtls_build_sslctx(d.tlscfg)
|
||||||
d.dtls_session = C.dtls_build_session(d.sslctx, C.bool(!isClient))
|
d.dtlsSession = C.dtls_build_session(d.sslctx, C.bool(!isClient))
|
||||||
|
|
||||||
return d, err
|
return d, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DTLSState) Close() {
|
// Close cleans up the associated OpenSSL resources
|
||||||
|
func (d *State) Close() {
|
||||||
C.free(unsafe.Pointer(d.rawSrc))
|
C.free(unsafe.Pointer(d.rawSrc))
|
||||||
C.free(unsafe.Pointer(d.rawDst))
|
C.free(unsafe.Pointer(d.rawDst))
|
||||||
C.dtls_session_cleanup(d.sslctx, d.dtls_session)
|
C.dtls_session_cleanup(d.sslctx, d.dtlsSession)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CertPair is the client+server key and profile extracted for SRTP
|
||||||
type CertPair struct {
|
type CertPair struct {
|
||||||
ClientWriteKey []byte
|
ClientWriteKey []byte
|
||||||
ServerWriteKey []byte
|
ServerWriteKey []byte
|
||||||
Profile string
|
Profile string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DTLSState) MaybeHandleDTLSPacket(packet []byte, size int) (isDTLSPacket bool, certPair *CertPair) {
|
// MaybeHandleDTLSPacket checks if the packet is a DTLS packet, and if it is passes to the DTLS session
|
||||||
|
func (d *State) MaybeHandleDTLSPacket(packet []byte, size int) (isDTLSPacket bool, certPair *CertPair) {
|
||||||
if packet[0] >= 20 && packet[0] <= 64 {
|
if packet[0] >= 20 && packet[0] <= 64 {
|
||||||
isDTLSPacket = true
|
isDTLSPacket = true
|
||||||
packetRaw := C.CBytes(packet)
|
packetRaw := C.CBytes(packet)
|
||||||
defer C.free(unsafe.Pointer(packetRaw))
|
defer C.free(unsafe.Pointer(packetRaw))
|
||||||
|
|
||||||
if ret := C.dtls_handle_incoming(d.dtls_session, d.rawSrc, d.rawDst, packetRaw, C.int(size)); ret != nil {
|
if ret := C.dtls_handle_incoming(d.dtlsSession, d.rawSrc, d.rawDst, packetRaw, C.int(size)); ret != nil {
|
||||||
certPair = &CertPair{
|
certPair = &CertPair{
|
||||||
ClientWriteKey: []byte(C.GoStringN(&ret.client_write_key[0], ret.key_length)),
|
ClientWriteKey: []byte(C.GoStringN(&ret.client_write_key[0], ret.key_length)),
|
||||||
ServerWriteKey: []byte(C.GoStringN(&ret.server_write_key[0], ret.key_length)),
|
ServerWriteKey: []byte(C.GoStringN(&ret.server_write_key[0], ret.key_length)),
|
||||||
@@ -133,15 +142,20 @@ func (d *DTLSState) MaybeHandleDTLSPacket(packet []byte, size int) (isDTLSPacket
|
|||||||
return isDTLSPacket, certPair
|
return isDTLSPacket, certPair
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DTLSState) DoHandshake() {
|
// DoHandshake sends the DTLS handshake it the remote peer
|
||||||
C.dtls_do_handshake(d.dtls_session, d.rawSrc, d.rawDst)
|
func (d *State) DoHandshake() {
|
||||||
|
C.dtls_do_handshake(d.dtlsSession, d.rawSrc, d.rawDst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddListener adds the socket to a map that can be accessed by OpenSSL for sending
|
||||||
|
// This only needed until DTLS is rewritten in native Go
|
||||||
func AddListener(src string, conn *ipv4.PacketConn) {
|
func AddListener(src string, conn *ipv4.PacketConn) {
|
||||||
listenerMapLock.Lock()
|
listenerMapLock.Lock()
|
||||||
listenerMap[src] = conn
|
listenerMap[src] = conn
|
||||||
listenerMapLock.Unlock()
|
listenerMapLock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveListener removes the socket from a map that can be accessed by OpenSSL for sending
|
||||||
|
// This only needed until DTLS is rewritten in native Go
|
||||||
func RemoveListener(src string) {
|
func RemoveListener(src string) {
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ package ice
|
|||||||
|
|
||||||
import "net"
|
import "net"
|
||||||
|
|
||||||
|
// HostInterfaces generates a slice of all the IPs associated with interfaces
|
||||||
func HostInterfaces() (ips []string) {
|
func HostInterfaces() (ips []string) {
|
||||||
ifaces, err := net.Interfaces()
|
ifaces, err := net.Interfaces()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -16,7 +16,7 @@ func packetHandler(conn *ipv4.PacketConn, srcString string, remoteKey []byte, tl
|
|||||||
const MTU = 8192
|
const MTU = 8192
|
||||||
buffer := make([]byte, MTU)
|
buffer := make([]byte, MTU)
|
||||||
|
|
||||||
dtlsStates := make(map[string]*dtls.DTLSState)
|
dtlsStates := make(map[string]*dtls.State)
|
||||||
bufferTransports := make(map[uint32]chan<- *rtp.Packet)
|
bufferTransports := make(map[uint32]chan<- *rtp.Packet)
|
||||||
|
|
||||||
var srtpSession *srtp.Session
|
var srtpSession *srtp.Session
|
||||||
@@ -83,7 +83,7 @@ func packetHandler(conn *ipv4.PacketConn, srcString string, remoteKey []byte, tl
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !haveHandshaked {
|
if !haveHandshaked {
|
||||||
d, err := dtls.NewDTLSState(tlscfg, true, srcString, rawDstAddr.String())
|
d, err := dtls.NewState(tlscfg, true, srcString, rawDstAddr.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
continue
|
continue
|
||||||
@@ -95,9 +95,12 @@ func packetHandler(conn *ipv4.PacketConn, srcString string, remoteKey []byte, tl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BufferTransportGenerator generates a new channel for the associated SSRC
|
||||||
|
// This channel is used to send RTP packets to users of pion-WebRTC
|
||||||
type BufferTransportGenerator func(uint32) chan<- *rtp.Packet
|
type BufferTransportGenerator func(uint32) chan<- *rtp.Packet
|
||||||
|
|
||||||
func UdpListener(ip string, remoteKey []byte, tlscfg *dtls.TLSCfg, b BufferTransportGenerator) (int, error) {
|
// UDPListener starts a new UDPListener, and will send the DTLS handshake if we are the client
|
||||||
|
func UDPListener(ip string, remoteKey []byte, tlscfg *dtls.TLSCfg, b BufferTransportGenerator) (int, error) {
|
||||||
listener, err := net.ListenPacket("udp4", ip+":0")
|
listener, err := net.ListenPacket("udp4", ip+":0")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@@ -1,5 +1,9 @@
|
|||||||
package sdp
|
package sdp
|
||||||
|
|
||||||
|
// MediaDescription represents a edia type. Currently defined media are "audio",
|
||||||
|
// "video", "text", "application", and "message", although this list
|
||||||
|
// may be extended in the future
|
||||||
|
// https://tools.ietf.org/html/rfc4566#section-5.14
|
||||||
type MediaDescription struct {
|
type MediaDescription struct {
|
||||||
// MediaName is m=<media> <port> <proto> <fmt>
|
// MediaName is m=<media> <port> <proto> <fmt>
|
||||||
// <media> is the media type
|
// <media> is the media type
|
||||||
|
@@ -82,6 +82,7 @@ type SessionDescription struct {
|
|||||||
MediaDescriptions []*MediaDescription
|
MediaDescriptions []*MediaDescription
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset cleans the SessionDescription, and sets all fields back to their default values
|
||||||
func (s *SessionDescription) Reset() {
|
func (s *SessionDescription) Reset() {
|
||||||
s.ProtocolVersion = 0
|
s.ProtocolVersion = 0
|
||||||
s.Origin = ""
|
s.Origin = ""
|
||||||
|
@@ -5,6 +5,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// VP8OnlyDescription generates a default SDP response that is ice-lite, initiates the DTLS session and only supports VP8
|
||||||
func VP8OnlyDescription(iceUsername, icePassword, fingerprint string, candidates []string) *SessionDescription {
|
func VP8OnlyDescription(iceUsername, icePassword, fingerprint string, candidates []string) *SessionDescription {
|
||||||
videoMediaDescription := &MediaDescription{
|
videoMediaDescription := &MediaDescription{
|
||||||
MediaName: "video 7 RTP/SAVPF 96 97",
|
MediaName: "video 7 RTP/SAVPF 96 97",
|
||||||
@@ -36,10 +37,10 @@ func VP8OnlyDescription(iceUsername, icePassword, fingerprint string, candidates
|
|||||||
|
|
||||||
// Generate only UDP host candidates for ICE
|
// Generate only UDP host candidates for ICE
|
||||||
|
|
||||||
sessionId := strconv.FormatUint(uint64(rand.Uint32())<<32+uint64(rand.Uint32()), 10)
|
sessionID := strconv.FormatUint(uint64(rand.Uint32())<<32+uint64(rand.Uint32()), 10)
|
||||||
return &SessionDescription{
|
return &SessionDescription{
|
||||||
ProtocolVersion: 0,
|
ProtocolVersion: 0,
|
||||||
Origin: "pion-webrtc " + sessionId + " 2 IN IP4 0.0.0.0",
|
Origin: "pion-webrtc " + sessionID + " 2 IN IP4 0.0.0.0",
|
||||||
SessionName: "-",
|
SessionName: "-",
|
||||||
Timing: []string{"0 0"},
|
Timing: []string{"0 0"},
|
||||||
Attributes: []string{
|
Attributes: []string{
|
||||||
|
@@ -15,10 +15,12 @@ func init() {
|
|||||||
C.srtp_init()
|
C.srtp_init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Session containts the libsrtp state for this SRTP session
|
||||||
type Session struct {
|
type Session struct {
|
||||||
rawSession *_Ctype_srtp_t
|
rawSession *_Ctype_srtp_t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New creates a new SRTP Session
|
||||||
func New(ClientWriteKey, ServerWriteKey []byte, profile string) *Session {
|
func New(ClientWriteKey, ServerWriteKey []byte, profile string) *Session {
|
||||||
rawClientWriteKey := C.CBytes(ClientWriteKey)
|
rawClientWriteKey := C.CBytes(ClientWriteKey)
|
||||||
rawServerWriteKey := C.CBytes(ServerWriteKey)
|
rawServerWriteKey := C.CBytes(ServerWriteKey)
|
||||||
@@ -38,6 +40,7 @@ func New(ClientWriteKey, ServerWriteKey []byte, profile string) *Session {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DecryptPacket decrypts a SRTP packet
|
||||||
func (s *Session) DecryptPacket(encryted []byte) (ok bool, unencryted []byte) {
|
func (s *Session) DecryptPacket(encryted []byte) (ok bool, unencryted []byte) {
|
||||||
rawIn := C.CBytes(encryted)
|
rawIn := C.CBytes(encryted)
|
||||||
defer C.free(unsafe.Pointer(rawIn))
|
defer C.free(unsafe.Pointer(rawIn))
|
||||||
|
@@ -2,6 +2,7 @@ package codecs
|
|||||||
|
|
||||||
import "github.com/pions/webrtc/pkg/rtp"
|
import "github.com/pions/webrtc/pkg/rtp"
|
||||||
|
|
||||||
|
// VP8Packet represents the VP8 header that is stored in the payload of an RTP Packet
|
||||||
type VP8Packet struct {
|
type VP8Packet struct {
|
||||||
// Required Header
|
// Required Header
|
||||||
X uint8 /* extended controlbits present */
|
X uint8 /* extended controlbits present */
|
||||||
@@ -20,6 +21,7 @@ type VP8Packet struct {
|
|||||||
Payload []byte
|
Payload []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unmarshal parses the passed byte slice and stores the result in the VP8Packet this method is called upon
|
||||||
func (p *VP8Packet) Unmarshal(packet *rtp.Packet) error {
|
func (p *VP8Packet) Unmarshal(packet *rtp.Packet) error {
|
||||||
payload := packet.Payload
|
payload := packet.Payload
|
||||||
|
|
||||||
@@ -59,4 +61,4 @@ func (p *VP8Packet) Unmarshal(packet *rtp.Packet) error {
|
|||||||
p.Payload = payload[payloadIndex:]
|
p.Payload = payload[payloadIndex:]
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -6,6 +6,8 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Packet represents an RTP Packet
|
||||||
|
// RTP is a network protocol for delivering audio and video over IP networks.
|
||||||
type Packet struct {
|
type Packet struct {
|
||||||
Raw []byte
|
Raw []byte
|
||||||
Version uint8
|
Version uint8
|
||||||
@@ -44,7 +46,7 @@ const (
|
|||||||
csrcLength = 4
|
csrcLength = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Unmarshal parses the passed byte slice and stores the result in the Packet this method is called upon
|
||||||
func (p *Packet) Unmarshal(rawPacket []byte) error {
|
func (p *Packet) Unmarshal(rawPacket []byte) error {
|
||||||
if len(rawPacket) < headerLength {
|
if len(rawPacket) < headerLength {
|
||||||
return errors.Errorf("RTP header size insufficient; %d < %d", len(rawPacket), headerLength)
|
return errors.Errorf("RTP header size insufficient; %d < %d", len(rawPacket), headerLength)
|
||||||
@@ -101,6 +103,7 @@ func (p *Packet) Unmarshal(rawPacket []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Marshal returns a raw RTP packet for the instance it is called upon
|
||||||
func (p *Packet) Marshal() ([]byte, error) {
|
func (p *Packet) Marshal() ([]byte, error) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -152,7 +155,7 @@ func (p *Packet) Marshal() ([]byte, error) {
|
|||||||
if p.Extension {
|
if p.Extension {
|
||||||
binary.BigEndian.PutUint16(rawPacket[currOffset:], p.ExtensionProfile)
|
binary.BigEndian.PutUint16(rawPacket[currOffset:], p.ExtensionProfile)
|
||||||
currOffset += 2
|
currOffset += 2
|
||||||
binary.BigEndian.PutUint16(rawPacket[currOffset:], uint16(len(p.ExtensionPayload)) / 4)
|
binary.BigEndian.PutUint16(rawPacket[currOffset:], uint16(len(p.ExtensionPayload))/4)
|
||||||
currOffset += 2
|
currOffset += 2
|
||||||
copy(rawPacket[currOffset:], p.ExtensionPayload)
|
copy(rawPacket[currOffset:], p.ExtensionPayload)
|
||||||
}
|
}
|
||||||
|
@@ -13,20 +13,27 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ChannelGenerator func(username string, srcAddr *stun.TransportAddr) (password string, ok bool)
|
// MediaType determines the type of media we are sending receiving
|
||||||
|
|
||||||
type MediaType int
|
type MediaType int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// G711 is a MediaType
|
||||||
G711 MediaType = iota
|
G711 MediaType = iota
|
||||||
|
// G722 is a MediaType
|
||||||
G722 MediaType = iota
|
G722 MediaType = iota
|
||||||
|
// ILBC is a MediaType
|
||||||
ILBC MediaType = iota
|
ILBC MediaType = iota
|
||||||
|
// ISAC is a MediaType
|
||||||
ISAC MediaType = iota
|
ISAC MediaType = iota
|
||||||
|
// H264 is a MediaType
|
||||||
H264 MediaType = iota
|
H264 MediaType = iota
|
||||||
VP8 MediaType = iota
|
// VP8 is a MediaType
|
||||||
|
VP8 MediaType = iota
|
||||||
|
// Opus is a MediaType
|
||||||
Opus MediaType = iota
|
Opus MediaType = iota
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// RTCPeerConnection represents a WebRTC connection between itself and a remote peer
|
||||||
type RTCPeerConnection struct {
|
type RTCPeerConnection struct {
|
||||||
Ontrack func(mediaType MediaType, buffers <-chan *rtp.Packet)
|
Ontrack func(mediaType MediaType, buffers <-chan *rtp.Packet)
|
||||||
LocalDescription *sdp.SessionDescription
|
LocalDescription *sdp.SessionDescription
|
||||||
@@ -39,10 +46,14 @@ type RTCPeerConnection struct {
|
|||||||
|
|
||||||
// Public
|
// Public
|
||||||
|
|
||||||
|
// SetRemoteDescription sets the SessionDescription of the remote peer
|
||||||
func (r *RTCPeerConnection) SetRemoteDescription(string) error {
|
func (r *RTCPeerConnection) SetRemoteDescription(string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateOffer starts the RTCPeerConnection and generates the localDescription
|
||||||
|
// The order of CreateOffer/SetRemoteDescription determines if we are the offerer or the answerer
|
||||||
|
// Once the RemoteDescription has been set network activity will start
|
||||||
func (r *RTCPeerConnection) CreateOffer() error {
|
func (r *RTCPeerConnection) CreateOffer() error {
|
||||||
if r.tlscfg != nil {
|
if r.tlscfg != nil {
|
||||||
return errors.Errorf("tlscfg is already defined, CreateOffer can only be called once")
|
return errors.Errorf("tlscfg is already defined, CreateOffer can only be called once")
|
||||||
@@ -54,7 +65,7 @@ func (r *RTCPeerConnection) CreateOffer() error {
|
|||||||
candidates := []string{}
|
candidates := []string{}
|
||||||
basePriority := uint16(rand.Uint32() & (1<<16 - 1))
|
basePriority := uint16(rand.Uint32() & (1<<16 - 1))
|
||||||
for id, c := range ice.HostInterfaces() {
|
for id, c := range ice.HostInterfaces() {
|
||||||
dstPort, err := network.UdpListener(c, []byte(r.icePassword), r.tlscfg, r.generateChannel)
|
dstPort, err := network.UDPListener(c, []byte(r.icePassword), r.tlscfg, r.generateChannel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -67,6 +78,9 @@ func (r *RTCPeerConnection) CreateOffer() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddStream adds a new media to the RTCPeerConnection
|
||||||
|
// This function returns a channel to push buffers on, and an error if the channel can't be added
|
||||||
|
// Closing the channel ends this stream
|
||||||
func (r *RTCPeerConnection) AddStream(mediaType MediaType) (buffers chan<- []byte, err error) {
|
func (r *RTCPeerConnection) AddStream(mediaType MediaType) (buffers chan<- []byte, err error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user