UNPKG

kod-temp

Version:

Workano Communications SDK

105 lines (104 loc) 4.09 kB
import sdpParser from 'sdp-transform'; export const getCandidates = (rawSdp) => { if (!rawSdp) { return []; } const sdp = sdpParser.parse(rawSdp); if (!sdp || !sdp.media) { return []; } // @ts-ignore: Type 'undefined' is not assignable to type 'Candidate' return sdp.media.map((media) => media.candidates).flat().filter((candidate) => !!candidate); }; export const parseCandidate = (candidate) => { if (!candidate) { return null; } const result = sdpParser.parse(candidate.indexOf('a=') === 0 ? candidate : `a=${candidate}`); // @ts-ignore: heads up -- Property 'candidates' does not exist on type 'SessionDescription' return result.candidates ? result.candidates[0] : null; }; const getSrflxOrRelay = (candidates) => candidates.filter(candidate => candidate && (candidate.type === 'srflx' || candidate.type === 'relay')); export const areCandidateValid = (candidates) => (candidates ? getSrflxOrRelay(candidates).length > 0 : false); export const isSdpValid = (sdp) => { const candidates = getCandidates(sdp); return areCandidateValid(candidates); }; export const fixBundle = (sdp) => { const parsedSdp = sdpParser.parse(sdp); const bundleIndex = parsedSdp.groups?.findIndex((group) => group.type === 'BUNDLE'); if (bundleIndex !== -1) { // @ts-ignore parsedSdp.groups[bundleIndex].mids = parsedSdp.media.map((media, index) => ('mid' in media ? media.mid : index)).join(' '); } return sdpParser.write(parsedSdp); }; export const toggleVideoDirection = (sdp, direction) => { const parsedSdp = sdpParser.parse(sdp); // @ts-ignore: heads up -- odd rewriting of sdp.media parsedSdp.media = parsedSdp.media.map(media => ({ ...media, ...(media.type === 'video' ? { direction, } : {}), })); return sdpParser.write(parsedSdp); }; export const getVideoDirection = (sdp) => { const parsedSdp = sdpParser.parse(sdp); const videoMedia = parsedSdp.media.find(media => media.type === 'video'); if (!videoMedia) { return null; } return videoMedia.direction; }; export const deactivateVideoModifier = (rawDescription) => { const description = rawDescription; description.sdp = toggleVideoDirection(description.sdp, 'inactive'); return Promise.resolve(description); }; export const activateVideoModifier = (rawDescription) => { const description = rawDescription; description.sdp = toggleVideoDirection(description.sdp, 'sendrecv'); return Promise.resolve(description); }; export const hasAnActiveVideo = (sdp) => { if (!sdp) { return false; } const parsedSdp = sdpParser.parse(sdp); return !!parsedSdp.media.find(media => media.type === 'video' && media.port > 10 && (!media.direction || media.direction !== 'inactive')); }; export const fixSdp = (sdp, candidates, forcePort = true) => { const parsedSdp = sdpParser.parse(sdp); const mainCandidate = getSrflxOrRelay(candidates)[0]; const ip = mainCandidate ? mainCandidate.ip : null; if (ip) { // @ts-ignore parsedSdp.origin.address = ip; } parsedSdp.media = parsedSdp.media.map((media) => { const port = forcePort ? mainCandidate ? mainCandidate.port : media.port : media.port; return { ...media, port, candidates: (media.candidates || []).concat(candidates), direction: port < 10 ? 'inactive' : media.direction, }; }); let fixed = sdpParser.write(parsedSdp); if (ip) { fixed = fixed.replace(/IN IP4 0.0.0.0/g, `IN IP4 ${ip}`); } return fixed; }; export const addIcesInAllBundles = (sdp) => { const parsedSdp = sdpParser.parse(sdp); const mediaWithCandidate = parsedSdp.media.find(media => !!media.candidates); if (!mediaWithCandidate) { return sdp; } const { candidates, } = mediaWithCandidate; parsedSdp.media = parsedSdp.media.map(media => ({ ...media, candidates: media.candidates || candidates, })); return sdpParser.write(parsedSdp); };