使用webRtc的音视频通话srs.sdk.ts代码
import axios from 'axios'
export function SrsRtcPublisherAsync() {
const self = {} as any
self.constraints = {
audio: true,
video: { facingMode: 'user', width: 3840, height: 2160, frameRate: { ideal: 60, max: 60 } }
}
self.publish = async function (url: any) {
// console.log(1)
var conf = self.__internal.prepareUrl(url)
self.pc.addTransceiver('audio', { direction: 'sendonly' })
self.pc.addTransceiver('video', { direction: 'sendonly' })
// console.log(2)
var stream = await navigator.mediaDevices.getUserMedia(self.constraints)
stream.getTracks().forEach(function (track) {
self.pc.addTrack(track)
self.ontrack && self.ontrack({ track: track })
})
// console.log(3)
var offer = await self.pc.createOffer()
await self.pc.setLocalDescription(offer)
// console.log(4)
var session: any = await new Promise(function (resolve, reject) {
const params = {
api: conf.apiUrl,
tid: conf.tid,
streamurl: conf.streamUrl,
clientip: null,
sdp: offer.sdp
}
// console.log(4.1)
// console.log(conf.apiUrl)
axios
.post(conf.apiUrl, params)
.then(res => {
const resData = res.data
if (resData.code) {
reject(resData)
return
}
// console.log(4.3)
// console.log('resData', resData)
resolve(resData)
})
.catch(err => {
reject(err)
})
// console.log(4.2)
})
// console.log(5)
await self.pc.setRemoteDescription(new RTCSessionDescription({ type: 'answer', sdp: session.sdp }))
session.simulator = conf.schema + '//' + conf.urlObject.server + ':' + conf.port + '/rtc/v1/nack/'
// console.log('推流over', session)
return session
}
// Close the publisher.
self.close = function () {
if (self.stream) {
self.stream.getTracks().map((i: any) => {
i.stop()
})
self.stream = null
}
self.pc && self.pc.close()
self.pc = null
}
// The callback when got local stream.
// @see https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addStream#Migrating_to_addTrack
self.ontrack = function (event: any) {
// Add track to stream of SDK.
self.stream.addTrack(event.track)
}
// Internal APIs.
self.__internal = {
defaultPath: '/rtc/v1/publish/',
prepareUrl: function (webrtcUrl: any) {
var urlObject = self.__internal.parse(webrtcUrl)
// If user specifies the schema, use it as API schema.
var schema = urlObject.user_query.schema
schema = schema ? schema + ':' : window.location.protocol
var port = urlObject.port || 1985
if (schema === 'https:') {
port = urlObject.port || 443
}
// @see https://github.com/rtcdn/rtcdn-draft
var api = urlObject.user_query.play || self.__internal.defaultPath
if (api.lastIndexOf('/') !== api.length - 1) {
api += '/'
}
apiUrl = schema + '//' + urlObject.server + ':' + port + api
for (var key in urlObject.user_query) {
if (key !== 'api' && key !== 'play') {
apiUrl += '&' + key + '=' + urlObject.user_query[key]
}
}
// Replace /rtc/v1/play/&k=v to /rtc/v1/play/?k=v
var apiUrl: any = apiUrl.replace(api + '&', api + '?')
var streamUrl = urlObject.url
return {
apiUrl: apiUrl,
streamUrl: streamUrl,
schema: schema,
urlObject: urlObject,
port: port,
tid: Number(parseInt((new Date().getTime() * Math.random() * 100).toString()))
.toString(16)
.slice(0, 7)
}
},
parse: function (url: any) {
// @see: http://stackoverflow.com/questions/10469575/how-to-use-location-object-to-parse-url-without-redirecting-the-page-in-javascri
var a = document.createElement('a')
a.href = url.replace('rtmp://', 'http://').replace('webrtc://', 'http://').replace('rtc://', 'http://')
var vhost = a.hostname
var app = a.pathname.substring(1, a.pathname.lastIndexOf('/'))
var stream = a.pathname.slice(a.pathname.lastIndexOf('/') + 1)
// parse the vhost in the params of app, that srs supports.
app = app.replace('...vhost...', '?vhost=')
if (app.indexOf('?') >= 0) {
var params = app.slice(app.indexOf('?'))
app = app.slice(0, app.indexOf('?'))
if (params.indexOf('vhost=') > 0) {
vhost = params.slice(params.indexOf('vhost=') + 'vhost='.length)
if (vhost.indexOf('&') > 0) {
vhost = vhost.slice(0, vhost.indexOf('&'))
}
}
}
// when vhost equals to server, and server is ip,
// the vhost is __defaultVhost__
if (a.hostname === vhost) {
var re = /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
if (re.test(a.hostname)) {
vhost = '__defaultVhost__'
}
}
// parse the schema
var schema = 'rtmp'
if (url.indexOf('://') > 0) {
schema = url.slice(0, url.indexOf('://'))
}
var port: any = a.port
if (!port) {
if (schema === 'http') {
port = 80
} else if (schema === 'https') {
port = 443
} else if (schema === 'rtmp') {
port = 1935
}
}
var ret: any = {
url: url,
schema: schema,
server: a.hostname,
port: port,
vhost: vhost,
app: app,
stream: stream
}
self.__internal.fill_query(a.search, ret)
// For webrtc API, we use 443 if page is https, or schema specified it.
if (!ret.port) {
if (schema === 'webrtc' || schema === 'rtc') {
if (ret.user_query.schema === 'https') {
ret.port = 443
} else if (window.location.href.indexOf('https://') === 0) {
ret.port = 443
} else {
// For WebRTC, SRS use 1985 as default API port.
ret.port = 1985
}
}
}
return ret
},
fill_query: function (query_string: any, obj: any) {
// pure user query object.
obj.user_query = {}
if (query_string.length === 0) {
return
}
// split again for angularjs.
if (query_string.indexOf('?') >= 0) {
query_string = query_string.split('?')[1]
}
var queries = query_string.split('&')
for (var i = 0; i < queries.length; i++) {
var elem = queries[i]
var query = elem.split('=')
obj[query[0]] = query[1]
obj.user_query[query[0]] = query[1]
}
// alias domain for vhost.
if (obj.domain) {
obj.vhost = obj.domain
}
}
}
self.pc = new RTCPeerConnection(undefined)
self.stream = new MediaStream()
self.adjustSound = function (flag: boolean) {
self.stream.getAudioTracks()[0].enabled = flag
}
self.adjustVideo = function (flag: boolean) {
self.stream.getVideoTracks()[0].enabled = flag
}
return self
}
// Depends on adapter-7.4.0.min.js from https://github.com/webrtc/adapter
// Async-await-promise based SRS RTC Player.
export function SrsRtcPlayerAsync() {
var self = {} as any
self.play = async function (url: any) {
var conf = self.__internal.prepareUrl(url)
self.pc.addTransceiver('audio', { direction: 'recvonly' })
self.pc.addTransceiver('video', { direction: 'recvonly' })
var offer = await self.pc.createOffer()
await self.pc.setLocalDescription(offer)
var session: any = await new Promise(function (resolve, reject) {
var params = {
api: conf.apiUrl,
tid: conf.tid,
streamurl: conf.streamUrl,
clientip: null,
sdp: offer.sdp
}
// console.log('Generated offer: ', params)
axios
.post(conf.apiUrl, params)
.then(res => {
const resData = res.data
// console.log('Got answer: ', resData)
if (resData.code) {
reject(resData)
return
}
resolve(resData)
})
.catch(err => {
reject(err)
})
})
await self.pc.setRemoteDescription(new RTCSessionDescription({ type: 'answer', sdp: session.sdp }))
session.simulator = conf.schema + '//' + conf.urlObject.server + ':' + conf.port + '/rtc/v1/nack/'
// console.log('拉流', session)
return session
}
// Close the player.
self.close = function () {
self.pc && self.pc.close()
self.pc = null
}
// The callback when got remote track.
// Note that the onaddstream is deprecated, @see https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/onaddstream
self.ontrack = function (event: any) {
// https://webrtc.org/getting-started/remote-streams
self.stream.addTrack(event.track)
}
// Internal APIs.
self.__internal = {
defaultPath: '/rtc/v1/play/',
prepareUrl: function (webrtcUrl: any) {
var urlObject = self.__internal.parse(webrtcUrl)
// If user specifies the schema, use it as API schema.
var schema = urlObject.user_query.schema
schema = schema ? schema + ':' : window.location.protocol
var port = urlObject.port || 1985
if (schema === 'https:') {
port = urlObject.port || 443
}
// @see https://github.com/rtcdn/rtcdn-draft
var api = urlObject.user_query.play || self.__internal.defaultPath
if (api.lastIndexOf('/') !== api.length - 1) {
api += '/'
}
apiUrl = schema + '//' + urlObject.server + ':' + port + api
for (var key in urlObject.user_query) {
if (key !== 'api' && key !== 'play') {
apiUrl += '&' + key + '=' + urlObject.user_query[key]
}
}
// Replace /rtc/v1/play/&k=v to /rtc/v1/play/?k=v
var apiUrl: any = apiUrl.replace(api + '&', api + '?')
var streamUrl = urlObject.url
return {
apiUrl: apiUrl,
streamUrl: streamUrl,
schema: schema,
urlObject: urlObject,
port: port,
tid: Number(parseInt((new Date().getTime() * Math.random() * 100).toString()))
.toString(16)
.slice(0, 7)
}
},
parse: function (url: any) {
// @see: http://stackoverflow.com/questions/10469575/how-to-use-location-object-to-parse-url-without-redirecting-the-page-in-javascri
var a = document.createElement('a')
a.href = url.replace('rtmp://', 'http://').replace('webrtc://', 'http://').replace('rtc://', 'http://')
var vhost = a.hostname
var app = a.pathname.substring(1, a.pathname.lastIndexOf('/'))
var stream = a.pathname.slice(a.pathname.lastIndexOf('/') + 1)
// parse the vhost in the params of app, that srs supports.
app = app.replace('...vhost...', '?vhost=')
if (app.indexOf('?') >= 0) {
var params = app.slice(app.indexOf('?'))
app = app.slice(0, app.indexOf('?'))
if (params.indexOf('vhost=') > 0) {
vhost = params.slice(params.indexOf('vhost=') + 'vhost='.length)
if (vhost.indexOf('&') > 0) {
vhost = vhost.slice(0, vhost.indexOf('&'))
}
}
}
// when vhost equals to server, and server is ip,
// the vhost is __defaultVhost__
if (a.hostname === vhost) {
var re = /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
if (re.test(a.hostname)) {
vhost = '__defaultVhost__'
}
}
// parse the schema
var schema = 'rtmp'
if (url.indexOf('://') > 0) {
schema = url.slice(0, url.indexOf('://'))
}
var port: any = a.port
if (!port) {
if (schema === 'http') {
port = 80
} else if (schema === 'https') {
port = 443
} else if (schema === 'rtmp') {
port = 1935
}
}
var ret: any = {
url: url,
schema: schema,
server: a.hostname,
port: port,
vhost: vhost,
app: app,
stream: stream
}
self.__internal.fill_query(a.search, ret)
// For webrtc API, we use 443 if page is https, or schema specified it.
if (!ret.port) {
if (schema === 'webrtc' || schema === 'rtc') {
if (ret.user_query.schema === 'https') {
ret.port = 443
} else if (window.location.href.indexOf('https://') === 0) {
ret.port = 443
} else {
// For WebRTC, SRS use 1985 as default API port.
ret.port = 1985
}
}
}
return ret
},
fill_query: function (query_string: any, obj: any) {
// pure user query object.
obj.user_query = {}
if (query_string.length === 0) {
return
}
// split again for angularjs.
if (query_string.indexOf('?') >= 0) {
query_string = query_string.split('?')[1]
}
var queries = query_string.split('&')
for (var i = 0; i < queries.length; i++) {
var elem = queries[i]
var query = elem.split('=')
obj[query[0]] = query[1]
obj.user_query[query[0]] = query[1]
}
// alias domain for vhost.
if (obj.domain) {
obj.vhost = obj.domain
}
}
}
self.pc = new RTCPeerConnection(undefined)
// Create a stream to add track to the stream, @see https://webrtc.org/getting-started/remote-streams
self.stream = new MediaStream()
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/ontrack
self.pc.ontrack = function (event: any) {
if (self.ontrack) {
self.ontrack(event)
}
}
return self
}
// Format the codec of RTCRtpSender, kind(audio/video) is optional filter.
// https://developer.mozilla.org/en-US/docs/Web/Media/Formats/WebRTC_codecs#getting_the_supported_codecs
export function SrsRtcFormatSenders(senders: any, kind: any) {
var codecs = [] as any
senders.forEach(function (sender: any) {
var params = sender.getParameters()
params &&
params.codecs &&
params.codecs.forEach(function (c: any) {
if (kind && sender.track.kind !== kind) {
return
}
if (
c.mimeType.indexOf('/red') > 0 ||
c.mimeType.indexOf('/rtx') > 0 ||
c.mimeType.indexOf('/fec') > 0
) {
return
}
var s = ''
s += c.mimeType.replace('audio/', '').replace('video/', '')
s += ', ' + c.clockRate + 'HZ'
if (sender.track.kind === 'audio') {
s += ', channels: ' + c.channels
}
s += ', pt: ' + c.payloadType
codecs.push(s)
})
})
return codecs.join(', ')
}
更多推荐
所有评论(0)