UNPKG

avcon-sdk-srs

Version:

Avcon SRS SDK

239 lines (238 loc) 8.79 kB
var g = Object.defineProperty; var P = (t, e, i) => e in t ? g(t, e, { enumerable: !0, configurable: !0, writable: !0, value: i }) : t[e] = i; var a = (t, e, i) => P(t, typeof e != "symbol" ? e + "" : e, i); const k = { code: -1, message: "Invalid JSON response" }; function m(t) { if (!t.ok) throw t; return t.json().then((e) => { if (e.code) throw e; return e; }); } function f(t, e) { return fetch(t.apiUrl, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ api: t.apiUrl, tid: t.tid, streamurl: t.streamUrl, sdp: e.sdp, clientip: null }) }).then(m).catch((i) => { if (i instanceof SyntaxError) return k; throw i; }); } function w(t, e) { const { schema: i, httpApiPort: r, httpsApiPort: o } = h.getConfig(), n = new URL(t.replace(/^(rtmp|webrtc|rtc)/, i)), c = n.port || n.protocol === "https" ? o : r, T = e.endsWith("/") ? e : e + "/"; return { apiUrl: `${n.protocol}//${n.hostname}:${c}${T}`, streamUrl: t, tid: ((/* @__PURE__ */ new Date()).getTime() * Math.random() * 100).toString(16).slice(0, 7) }; } class d extends Error { constructor(e, i) { super(), this.name = e, this.message = i, this.stack = new Error().stack; } } var C = /* @__PURE__ */ ((t) => (t.Normal = "normal", t.Screen = "screen", t))(C || {}); async function l(t = { audio: !0, video: !0 }, e = "normal") { if (!navigator.mediaDevices && window.location.protocol === "http:" && window.location.hostname !== "localhost") throw new d( "HttpsRequiredError", "Please use HTTPS or localhost to publish, read https://github.com/ossrs/srs/issues/2762#issuecomment-983147576" ); const i = e === "normal" ? await navigator.mediaDevices.getUserMedia(t) : await navigator.mediaDevices.getDisplayMedia(t), r = i.getAudioTracks()[0], o = i.getVideoTracks()[0]; return { audioTrack: r, videoTrack: o, stream: i }; } var s = /* @__PURE__ */ ((t) => (t[t.Pendding = 1] = "Pendding", t[t.Connecting = 2] = "Connecting", t[t.Connected = 3] = "Connected", t[t.Disconnected = 4] = "Disconnected", t))(s || {}); class u { constructor(e) { a(this, "constraints"); a(this, "status", s.Pendding); a(this, "RTCPeerConnection", new RTCPeerConnection()); a(this, "stream", new MediaStream()); a(this, "audioSender", null); a(this, "videoSender", null); this.constraints = e || { audio: !0, video: !0 }; } init() { this.status = s.Pendding, this.stream = new MediaStream(), this.RTCPeerConnection = new RTCPeerConnection(), this.audioSender = null, this.videoSender = null; } close() { this.status = s.Disconnected, this.stream.getTracks().forEach((e) => e.stop()), this.RTCPeerConnection && this.RTCPeerConnection.close(), this.RTCPeerConnection = null, this.audioSender = null, this.videoSender = null; } setConstraints(e) { this.constraints = e; } async getWebRTCStats(e) { if (this.RTCPeerConnection) try { return await this.RTCPeerConnection.getStats(e); } catch (i) { console.error("获取WebRTC数据统计失败:", i); } } getConstraints() { return this.constraints; } getStatus() { return this.status; } setVideoContentHind(e, i) { return "contentHint" in e ? (e.contentHint = i, e.contentHint !== i ? (console.warn("设置contentHint失败", i), !1) : !0) : (console.warn("浏览器不支持contentHint,不设置contentHint"), !1); } async setRTCDescription(e, i) { if (this.RTCPeerConnection) { this.status = s.Connecting; const r = await this.RTCPeerConnection.createOffer(); await this.RTCPeerConnection.setLocalDescription(r); const o = w(e, i); try { const n = await f(o, r); return await this.RTCPeerConnection.setRemoteDescription({ type: "answer", sdp: n.sdp }), this.status = s.Connected, n; } catch { throw new d( "Avcon SRS Sdk Publish Error", "信令获取失败" ); } } } } class v extends u { constructor(e) { super(e); } async publish(e, i, r = "detail") { if (!(this.status === s.Pendding || this.status === s.Disconnected)) throw new d( "Avcon SRS Sdk Error", "当前SrsPublisher实例处于连接状态,请先调用close()方法关闭连接,再重新调用publish()方法" ); i && this.setConstraints(i), this.RTCPeerConnection || this.init(); const { stream: o, audioTrack: n, videoTrack: c } = await l(this.constraints); return c && (this.RTCPeerConnection.addTransceiver("video", { direction: "sendonly" }), this.setVideoContentHind(c, r), this.stream.addTrack(c), this.videoSender = this.RTCPeerConnection.addTrack(c, this.stream)), n && (this.RTCPeerConnection.addTransceiver("audio", { direction: "sendonly" }), this.stream.addTrack(n), this.audioSender = this.RTCPeerConnection.addTrack(n, this.stream)), await this.setRTCDescription(e, h.getConfig().publishApi), o; } closeAudio() { this.stream.getAudioTracks()[0] && (this.stream.getAudioTracks()[0].enabled = !1); } closeVideo() { this.stream.getVideoTracks()[0] && (this.stream.getVideoTracks()[0].enabled = !1); } openAudio() { this.stream.getAudioTracks()[0] && (this.stream.getAudioTracks()[0].enabled = !0); } openVideo() { this.stream.getVideoTracks()[0] && (this.stream.getVideoTracks()[0].enabled = !0); } async changeAudioTrack(e) { const i = this.stream.getAudioTracks()[0]; i && (i.stop(), this.stream.removeTrack(i)), this.stream.addTrack(e), this.audioSender && await this.audioSender.replaceTrack(e); } async changeVideoTrack(e) { const i = this.stream.getVideoTracks()[0]; i && (i.stop(), this.stream.removeTrack(i)), this.stream.addTrack(e), this.videoSender && await this.videoSender.replaceTrack(e); } async rePublishVideo() { const { videoTrack: e } = await l(this.constraints); this.changeVideoTrack(e); } } class S extends u { constructor(e = { video: { displaySurface: "browser" }, audio: { // @ts-ignore // https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSettings/suppressLocalAudioPlayback suppressLocalAudioPlayback: !1 // 是否 禁止本地音频播放 }, preferCurrentTab: !1 // 是否 首选(且只能选)当前页签 }) { super(e); } async publish(e, i) { if (!(this.status === s.Pendding || this.status === s.Disconnected)) throw new d( "Avcon SRS Sdk Error", "当前SrsPublisher实例处于连接状态,请先调用close()方法关闭连接,再重新调用publish()方法" ); i && this.setConstraints(i), this.RTCPeerConnection || this.init(), this.RTCPeerConnection.addTransceiver("audio", { direction: "sendonly" }), this.RTCPeerConnection.addTransceiver("video", { direction: "sendonly" }); const { videoTrack: r, stream: o, audioTrack: n } = await l(this.constraints, C.Screen); return this.stream = o, this.RTCPeerConnection.addTrack(r), n && this.RTCPeerConnection.addTrack(n), await this.setRTCDescription(e, h.getConfig().publishApi), o; } } class y extends u { constructor() { super(), this.RTCPeerConnection.ontrack = (e) => { this.stream.addTrack(e.track); }; } async play(e) { if (!(this.status === s.Pendding || this.status === s.Disconnected)) throw new d( "Avcon SRS Sdk Error", "当前SrsPlayer实例处于连接状态,请先调用close()方法关闭连接,再重新调用play()方法" ); return this.RTCPeerConnection || (this.init(), this.RTCPeerConnection.ontrack = (i) => { this.stream.addTrack(i.track); }), this.status = s.Connecting, this.RTCPeerConnection.addTransceiver("audio", { direction: "recvonly" }), this.RTCPeerConnection.addTransceiver("video", { direction: "recvonly" }), await this.setRTCDescription(e, h.getConfig().playApi); } } const p = { schema: "https", httpApiPort: 1985, httpsApiPort: 1990, publishApi: "/rtc/v1/publish/", playApi: "/rtc/v1/play/" }; var R = /* @__PURE__ */ ((t) => (t[t.Pendding = 1] = "Pendding", t[t.Connecting = 2] = "Connecting", t[t.Connected = 3] = "Connected", t[t.Disconnected = 4] = "Disconnected", t))(R || {}); class b { constructor(e) { a(this, "sdkConfig"); this.sdkConfig = e; } setConfig(e) { this.sdkConfig = { ...p, ...e }; } getConfig() { return this.sdkConfig; } createPublisher(e) { return new v(e); } createScreenPublisher(e) { return new S(e); } createPlayer() { return new y(); } } const h = new b(p); export { b as AcvconSrsSdk, R as RTCInstanceStatus, h as default };