/* * Copyright (C) 2012-2018 Doubango Telecom <http://www.doubango.org> * License: BSD * This file is part of Open Source sipML5 solution <http://www.sipml5.org> */ var tsdp_path = DispatchLibPath+"tinySDP/" function tsdp_api_add_js_scripts(s_elt) { var tag_hdr = document.getElementsByTagName(s_elt)[0]; for (var i = 1; i < arguments.length; ++i) { var tag_script = document.createElement('script'); tag_script.setAttribute('type', 'text/javascript'); tag_script.setAttribute('src', arguments[i]); tag_hdr.appendChild(tag_script); } }; // add tinySAK API tsdp_api_add_js_scripts('head', tsdp_path + 'tsk/tsk_api.js'); tsdp_api_add_js_scripts('head', tsdp_path + 'headers/tsdp_header.js', // tsdp_path + 'headers/tsdp_header_A.js', #include_in<tsdp_header.js> // tsdp_path + 'headers/tsdp_header_B.js', #include_in<tsdp_header.js> // tsdp_path + 'headers/tsdp_header_C.js', #include_in<tsdp_header.js> // tsdp_path + 'headers/tsdp_header_Dummy.js', #include_in<tsdp_header.js> // tsdp_path + 'headers/tsdp_header_E.js', #see<tsdp_header_Str.js> // tsdp_path + 'headers/tsdp_header_I.js', #see<tsdp_header_Str.js> // tsdp_path + 'headers/tsdp_header_K.js', #see<tsdp_header_Str.js> // tsdp_path + 'headers/tsdp_header_M.js', #include_in<tsdp_header.js> // tsdp_path + 'headers/tsdp_header_O.js', #include_in<tsdp_header.js> // tsdp_path + 'headers/tsdp_header_P.js', #see<tsdp_header_Str.js> // tsdp_path + 'headers/tsdp_header_R.js', #include_in<tsdp_header.js> // tsdp_path + 'headers/tsdp_header_S.js', #see<tsdp_header_Str.js> // tsdp_path + 'headers/tsdp_header_Str.js', #include_in<tsdp_header.js> // tsdp_path + 'headers/tsdp_header_T.js', #include_in<tsdp_header.js> // tsdp_path + 'headers/tsdp_header_U.js', #include_in<tsdp_header.js> // tsdp_path + 'headers/tsdp_header_V.js', #include_in<tsdp_header.js> // tsdp_path + 'headers/tsdp_header_Z.js' #include_in<tsdp_header.js> tsdp_path + 'tsdp_message.js' //'src/tinySDP/src/tsdp_parser_message.js' #include_in<tsdp_message.js> ); var changesdp = function(peersdp, videocandidates, audiocandidates){ var sdp = peersdp; var tsdp = tsdp_message.prototype.Parse(sdp); for (var i = 0; i < tsdp.ao_headers.length; ++i){ if (tsdp.ao_headers[i] && tsdp.ao_headers[i].e_type.c_name == "s") { tsdp.ao_headers[i].s_value = "webrtc"; break; } } var opus_pt = 0; var m_audio = tsdp.get_header_m_by_name("audio"); if (m_audio) { for (var i = 0; i < m_audio.ao_hdr_A.length; ++i){ if (m_audio.ao_hdr_A[i] && m_audio.ao_hdr_A[i].s_field == "rtpmap") { var substr_array = m_audio.ao_hdr_A[i].s_value.split(" "); if (substr_array && substr_array[1] && substr_array[1].indexOf("opus") == 0) { opus_pt = substr_array[0]; break; } } } console.log('opus_pt ' + opus_pt); m_audio.as_fmt = new Array(); m_audio.as_fmt[0] = opus_pt.toString(); for (var i = 0; i < m_audio.ao_hdr_A.length; ++i){ if (m_audio.ao_hdr_A[i] && (m_audio.ao_hdr_A[i].s_field == "rtpmap" || m_audio.ao_hdr_A[i].s_field == "fmtp" || m_audio.ao_hdr_A[i].s_field == "rtcp-fb" || m_audio.ao_hdr_A[i].s_field == "extmap")) { var substr_array = m_audio.ao_hdr_A[i].s_value.split(" "); if (!(substr_array && substr_array[0] == opus_pt)) { m_audio.ao_hdr_A[i] = null; } } } //m_audio.s_proto = "RTP/AVP"; for (var i = 0; i < audiocandidates.length; ++i){ var a = tsdp_header_A.prototype.Parse(audiocandidates[i]); m_audio.ao_hdr_A.push(a); } } //video var h264_pt_array = new Array; var h264_pt = 0; var m_video = tsdp.get_header_m_by_name("video"); if (m_video) { for (var i = 0; i < m_video.ao_hdr_A.length; ++i){ if (m_video.ao_hdr_A[i] && m_video.ao_hdr_A[i].s_field == "rtpmap") { var substr_array = m_video.ao_hdr_A[i].s_value.split(" "); if (substr_array && substr_array[1] && substr_array[1].indexOf("H264") == 0) { h264_pt_array.push(substr_array[0]); } } } //"level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f" for (var i = 0; i < m_video.ao_hdr_A.length; ++i){ if (m_video.ao_hdr_A[i] && m_video.ao_hdr_A[i].s_field == "fmtp") { var substr_array = m_video.ao_hdr_A[i].s_value.split(" "); if (substr_array && substr_array[0] && substr_array[1]) { for (var j = 0; j < h264_pt_array.length; ++j) { if (substr_array[0] == h264_pt_array[j] && substr_array[1].indexOf("packetization-mode=1") != -1 && substr_array[1].indexOf("profile-level-id=42e0") != -1) { //优先Baseline h264_pt = substr_array[0]; break; } } } } if (h264_pt) { break; } } if (h264_pt == 0) { h264_pt = h264_pt_array[0]; } console.log('h264_pt ' + h264_pt); m_video.as_fmt = new Array(); m_video.as_fmt[0] = h264_pt.toString(); for (var i = 0; i < m_video.ao_hdr_A.length; ++i){ if (m_video.ao_hdr_A[i] && (m_video.ao_hdr_A[i].s_field == "rtpmap" || m_video.ao_hdr_A[i].s_field == "fmtp" || m_video.ao_hdr_A[i].s_field == "rtcp-fb" || m_video.ao_hdr_A[i].s_field == "extmap")) { var substr_array = m_video.ao_hdr_A[i].s_value.split(" "); if (!(substr_array && substr_array[0] == h264_pt)) { m_video.ao_hdr_A[i] = null; } } } //m_video.s_proto = "RTP/AVP"; for (var i = 0; i < videocandidates.length; ++i){ var a = tsdp_header_A.prototype.Parse(videocandidates[i]); m_video.ao_hdr_A.push(a); } } return tsdp.toString(); } var changesdp_local = function(localsdp){ var sdp = localsdp; var tsdp = tsdp_message.prototype.Parse(sdp); for (var i = 0; i < tsdp.ao_headers.length; ++i){ if (tsdp.ao_headers[i] && tsdp.ao_headers[i].e_type.c_name == "s") { tsdp.ao_headers[i].s_value = "webrtc"; break; } } var opus_pt = 0; var m_audio = tsdp.get_header_m_by_name("audio"); if (m_audio) { for (var i = 0; i < m_audio.ao_hdr_A.length; ++i){ if (m_audio.ao_hdr_A[i] && m_audio.ao_hdr_A[i].s_field == "rtpmap") { var substr_array = m_audio.ao_hdr_A[i].s_value.split(" "); if (substr_array && substr_array[1] && substr_array[1].indexOf("opus") == 0) { opus_pt = substr_array[0]; break; } } } console.log('opus_pt ' + opus_pt); m_audio.as_fmt = new Array(); m_audio.as_fmt[0] = opus_pt.toString(); for (var i = 0; i < m_audio.ao_hdr_A.length; ++i){ if (m_audio.ao_hdr_A[i] && (m_audio.ao_hdr_A[i].s_field == "rtpmap" || m_audio.ao_hdr_A[i].s_field == "fmtp" || m_audio.ao_hdr_A[i].s_field == "rtcp-fb" || m_audio.ao_hdr_A[i].s_field == "extmap")) { var substr_array = m_audio.ao_hdr_A[i].s_value.split(" "); if (!(substr_array && substr_array[0] == opus_pt)) { m_audio.ao_hdr_A[i] = null; } } } } //video var h264_pt_array = new Array; var h264_pt = 0; var m_video = tsdp.get_header_m_by_name("video"); if (m_video) { for (var i = 0; i < m_video.ao_hdr_A.length; ++i){ if (m_video.ao_hdr_A[i] && m_video.ao_hdr_A[i].s_field == "rtpmap") { var substr_array = m_video.ao_hdr_A[i].s_value.split(" "); if (substr_array && substr_array[1] && substr_array[1].indexOf("H264") == 0) { h264_pt_array.push(substr_array[0]); } } } //"level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f" for (var i = 0; i < m_video.ao_hdr_A.length; ++i){ if (m_video.ao_hdr_A[i] && m_video.ao_hdr_A[i].s_field == "fmtp") { var substr_array = m_video.ao_hdr_A[i].s_value.split(" "); if (substr_array && substr_array[0] && substr_array[1]) { for (var j = 0; j < h264_pt_array.length; ++j) { if (substr_array[0] == h264_pt_array[j] && substr_array[1].indexOf("packetization-mode=1") != -1 && substr_array[1].indexOf("profile-level-id=42e0") != -1) { //优先Baseline h264_pt = substr_array[0]; break; } } } } if (h264_pt) { break; } } if (h264_pt == 0) { h264_pt = h264_pt_array[0]; } console.log('h264_pt ' + h264_pt); m_video.as_fmt = new Array(); m_video.as_fmt[0] = h264_pt.toString(); for (var i = 0; i < m_video.ao_hdr_A.length; ++i){ if (m_video.ao_hdr_A[i] && (m_video.ao_hdr_A[i].s_field == "rtpmap" || m_video.ao_hdr_A[i].s_field == "fmtp" || m_video.ao_hdr_A[i].s_field == "rtcp-fb" || m_video.ao_hdr_A[i].s_field == "extmap")) { var substr_array = m_video.ao_hdr_A[i].s_value.split(" "); if (!(substr_array && substr_array[0] == h264_pt)) { m_video.ao_hdr_A[i] = null; } } } } return tsdp.toString(); } var compressLocalSdp = function(peersdp, videocandidates, audiocandidates){ var sdp = peersdp; var tsdp = tsdp_message.prototype.Parse(sdp); var msid_semantic_index = -1; for (var i = 0; i < tsdp.ao_headers.length; ++i){ if (tsdp.ao_headers[i]) { if (tsdp.ao_headers[i].e_type.c_name == "s") { tsdp.ao_headers[i].s_value = "webrtc-dc"; } else if (tsdp.ao_headers[i].e_type.c_name == "a" && tsdp.ao_headers[i].s_field == "msid-semantic") { tsdp.ao_headers[i] = null; msid_semantic_index = i; } } } var ice_ufrag = null; //ice-ufrag var ice_pwd = null; //ice-pwd var ice_options = null; //ice-options var fingerprint = null; //fingerprint var setup = null; //setup var opus_pt = 0; var m_audio = tsdp.get_header_m_by_name("audio"); if (m_audio) { m_audio.o_hdr_C = null; for (var i = 0; i < m_audio.ao_hdr_A.length; ++i){ if (m_audio.ao_hdr_A[i] && m_audio.ao_hdr_A[i].s_field == "rtpmap") { var substr_array = m_audio.ao_hdr_A[i].s_value.split(" "); if (substr_array && substr_array[1] && substr_array[1].indexOf("opus") == 0) { opus_pt = substr_array[0]; break; } } } console.log('opus_pt ' + opus_pt); m_audio.as_fmt = new Array(); m_audio.as_fmt[0] = opus_pt.toString(); for (var i = 0; i < m_audio.ao_hdr_A.length; ++i) { if (m_audio.ao_hdr_A[i]) { if (m_audio.ao_hdr_A[i].s_field == "rtcp" || m_audio.ao_hdr_A[i].s_field == "rtcp-mux" || m_audio.ao_hdr_A[i].s_field == "rtcp-rsize" || m_audio.ao_hdr_A[i].s_field == "rtcp-fb" || m_audio.ao_hdr_A[i].s_field == "fmtp" || m_audio.ao_hdr_A[i].s_field == "extmap") { m_audio.ao_hdr_A[i] = null; } else if (m_audio.ao_hdr_A[i].s_field == "rtpmap") { var substr_array = m_audio.ao_hdr_A[i].s_value.split(" "); if (!(substr_array && substr_array[0] == opus_pt)) { m_audio.ao_hdr_A[i] = null; } } else if (m_audio.ao_hdr_A[i].s_field == "ice-ufrag") { ice_ufrag = m_audio.ao_hdr_A[i]; m_audio.ao_hdr_A[i] = null; } else if (m_audio.ao_hdr_A[i].s_field == "ice-pwd") { ice_pwd = m_audio.ao_hdr_A[i]; m_audio.ao_hdr_A[i] = null; } else if (m_audio.ao_hdr_A[i].s_field == "ice-options") { ice_options = m_audio.ao_hdr_A[i]; m_audio.ao_hdr_A[i] = null; } else if (m_audio.ao_hdr_A[i].s_field == "fingerprint") { fingerprint = m_audio.ao_hdr_A[i]; m_audio.ao_hdr_A[i] = null; } else if (m_audio.ao_hdr_A[i].s_field == "setup") { setup = m_audio.ao_hdr_A[i]; m_audio.ao_hdr_A[i] = null; } } } for (var i = 0; i < audiocandidates.length; ++i){ var a = tsdp_header_A.prototype.Parse(audiocandidates[i]); m_audio.ao_hdr_A.push(a); } } //video var h264_pt_array = new Array; var h264_pt = 0; var m_video = tsdp.get_header_m_by_name("video"); if (m_video) { m_video.o_hdr_C = null; for (var i = 0; i < m_video.ao_hdr_A.length; ++i){ if (m_video.ao_hdr_A[i] && m_video.ao_hdr_A[i].s_field == "rtpmap") { var substr_array = m_video.ao_hdr_A[i].s_value.split(" "); if (substr_array && substr_array[1] && substr_array[1].indexOf("H264") == 0) { h264_pt_array.push(substr_array[0]); } } } //"level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f" for (var i = 0; i < m_video.ao_hdr_A.length; ++i){ if (m_video.ao_hdr_A[i] && m_video.ao_hdr_A[i].s_field == "fmtp") { var substr_array = m_video.ao_hdr_A[i].s_value.split(" "); if (substr_array && substr_array[0] && substr_array[1]) { for (var j = 0; j < h264_pt_array.length; ++j) { if (substr_array[0] == h264_pt_array[j] && substr_array[1].indexOf("packetization-mode=1") != -1 && substr_array[1].indexOf("profile-level-id=42e0") != -1) //substr_array[1].indexOf("profile-level-id=6400") != -1) { //优先Baseline h264_pt = substr_array[0]; break; } } } } if (h264_pt) { break; } } if (h264_pt == 0) { h264_pt = h264_pt_array[0]; } console.log('h264_pt ' + h264_pt); m_video.as_fmt = new Array(); m_video.as_fmt[0] = h264_pt.toString(); for (var i = 0; i < m_video.ao_hdr_A.length; ++i) { if (m_video.ao_hdr_A[i]) { if (m_video.ao_hdr_A[i].s_field == "rtcp" || m_video.ao_hdr_A[i].s_field == "rtcp-mux" || m_video.ao_hdr_A[i].s_field == "rtcp-rsize" || m_video.ao_hdr_A[i].s_field == "rtcp-fb" || m_video.ao_hdr_A[i].s_field == "fmtp" || m_video.ao_hdr_A[i].s_field == "extmap" ) { m_video.ao_hdr_A[i] = null; } else if (m_video.ao_hdr_A[i].s_field == "rtpmap") { var substr_array = m_video.ao_hdr_A[i].s_value.split(" "); if (!(substr_array && substr_array[0] == h264_pt)) { m_video.ao_hdr_A[i] = null; } } else if (m_video.ao_hdr_A[i].s_field == "ice-ufrag") { ice_ufrag = m_video.ao_hdr_A[i]; m_video.ao_hdr_A[i] = null; } else if (m_video.ao_hdr_A[i].s_field == "ice-pwd") { ice_pwd = m_video.ao_hdr_A[i]; m_video.ao_hdr_A[i] = null; } else if (m_video.ao_hdr_A[i].s_field == "ice-options") { ice_options = m_video.ao_hdr_A[i]; m_video.ao_hdr_A[i] = null; } else if (m_video.ao_hdr_A[i].s_field == "fingerprint") { fingerprint = m_video.ao_hdr_A[i]; m_video.ao_hdr_A[i] = null; } else if (m_video.ao_hdr_A[i].s_field == "setup") { setup = m_video.ao_hdr_A[i]; m_video.ao_hdr_A[i] = null; } } } for (var i = 0; i < videocandidates.length; ++i){ var a = tsdp_header_A.prototype.Parse(videocandidates[i]); m_video.ao_hdr_A.push(a); } } tsdp.ao_headers.splice(msid_semantic_index, 0, ice_ufrag); msid_semantic_index++; tsdp.ao_headers.splice(msid_semantic_index, 0, ice_pwd); msid_semantic_index++; tsdp.ao_headers.splice(msid_semantic_index, 0, ice_options); msid_semantic_index++; tsdp.ao_headers.splice(msid_semantic_index, 0, fingerprint); msid_semantic_index++; tsdp.ao_headers.splice(msid_semantic_index, 0, setup); msid_semantic_index++; return tsdp.toString(); } var decompressRemoteSdp = function(localsdp) { var sdp = localsdp; var tsdp = tsdp_message.prototype.Parse(sdp); var ice_ufrag = null; //ice-ufrag var ice_pwd = null; //ice-pwd var fingerprint = null; //fingerprint var setup = null; //setup var candidates = new Array; for (var i = 0; i < tsdp.ao_headers.length; ++i) { if (tsdp.ao_headers[i]) { if (tsdp.ao_headers[i].e_type.c_name == "s") { tsdp.ao_headers[i].s_value = "webrtc"; } else if (tsdp.ao_headers[i].e_type.c_name == "a") { if (tsdp.ao_headers[i].s_field == "ice-ufrag") { ice_ufrag = tsdp.ao_headers[i]; tsdp.ao_headers[i] = null; } else if (tsdp.ao_headers[i].s_field == "ice-pwd") { ice_pwd = tsdp.ao_headers[i]; tsdp.ao_headers[i] = null; } else if (tsdp.ao_headers[i].s_field == "fingerprint") { fingerprint = tsdp.ao_headers[i]; tsdp.ao_headers[i] = null; } else if (tsdp.ao_headers[i].s_field == "setup") { setup = tsdp.ao_headers[i]; tsdp.ao_headers[i] = null; } else if (tsdp.ao_headers[i].s_field == "candidate") { candidates.push(tsdp.ao_headers[i]); tsdp.ao_headers[i] = null; } } } } var opus_pt = 0; var m_audio = tsdp.get_header_m_by_name("audio"); if (m_audio) { for (var i = 0; i < m_audio.ao_hdr_A.length; ++i) { if (m_audio.ao_hdr_A[i] && m_audio.ao_hdr_A[i].s_field == "rtpmap") { var substr_array = m_audio.ao_hdr_A[i].s_value.split(" "); if (substr_array && substr_array[1] && substr_array[1].indexOf("opus") == 0) { var rtcp = new tsdp_header_A("rtcp", "9 IN IP4 0.0.0.0"); m_audio.ao_hdr_A.splice(i, 0, rtcp); var rtcp_mux = new tsdp_header_A("rtcp-mux", null); m_audio.ao_hdr_A.splice(i, 0, rtcp_mux); opus_pt = substr_array[0]; var fmtp = new tsdp_header_A("fmtp", opus_pt +" minptime=10;useinbandfec=1"); m_audio.ao_hdr_A.splice(i+3, 0, fmtp); m_audio.ao_hdr_A.splice(i+4, 0, ice_ufrag); m_audio.ao_hdr_A.splice(i+5, 0, ice_pwd); m_audio.ao_hdr_A.splice(i+6, 0, fingerprint); m_audio.ao_hdr_A.splice(i+7, 0, setup); break; } } } for (var i = 0; i < m_audio.ao_hdr_A.length; ++i) { if (m_audio.ao_hdr_A[i] && m_audio.ao_hdr_A[i].s_field == "ssrc") { for (var j = 0; j < candidates.length; ++j) { m_audio.ao_hdr_A.splice(i+1+j, 0, candidates[j]); } } } } var h264_pt = 0; var m_video = tsdp.get_header_m_by_name("video"); if (m_video) { for (var i = 0; i < m_video.ao_hdr_A.length; ++i) { if (m_video.ao_hdr_A[i] && m_video.ao_hdr_A[i].s_field == "rtpmap") { var substr_array = m_video.ao_hdr_A[i].s_value.split(" "); if (substr_array && substr_array[1] && substr_array[1].indexOf("H264") == 0) { var rtcp = new tsdp_header_A("rtcp", "9 IN IP4 0.0.0.0"); m_video.ao_hdr_A.splice(i, 0, rtcp); var rtcp_mux = new tsdp_header_A("rtcp-mux", null); m_video.ao_hdr_A.splice(i, 0, rtcp_mux); h264_pt = substr_array[0]; m_video.ao_hdr_A.splice(i+3, 0, new tsdp_header_A("rtcp-fb", h264_pt +" goog-remb")); m_video.ao_hdr_A.splice(i+4, 0, new tsdp_header_A("rtcp-fb", h264_pt +" ccm fir")); m_video.ao_hdr_A.splice(i+5, 0, new tsdp_header_A("rtcp-fb", h264_pt +" nack")); m_video.ao_hdr_A.splice(i+6, 0, new tsdp_header_A("rtcp-fb", h264_pt +" nack pli")); var fmtp = new tsdp_header_A("fmtp", h264_pt +" level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f"); //var fmtp = new tsdp_header_A("fmtp", h264_pt +" level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=64001f"); m_video.ao_hdr_A.splice(i+7, 0, fmtp); m_video.ao_hdr_A.splice(i+8, 0, ice_ufrag); m_video.ao_hdr_A.splice(i+9, 0, ice_pwd); m_video.ao_hdr_A.splice(i+10, 0, fingerprint); m_video.ao_hdr_A.splice(i+11, 0, setup); break; } } } for (var i = 0; i < m_video.ao_hdr_A.length; ++i) { if (m_video.ao_hdr_A[i] && m_video.ao_hdr_A[i].s_field == "ssrc") { for (var j = 0; j < candidates.length; ++j) { m_video.ao_hdr_A.splice(i+1+j, 0, candidates[j]); } } } } return tsdp.toString(); }