mirror of
https://github.com/eliasstepanik/vdo.ninja.git
synced 2026-01-11 13:48:38 +00:00
BETA Version -- bug fixes + main.js editable again
&view should work in the previous version, but tested again in this version &view=xx,yy,zz should work &codec=vp9 issue fixed in codec handler numerous other fixes.
This commit is contained in:
parent
7300421a19
commit
aa50333dc9
116
animations.js
116
animations.js
@ -1 +1,115 @@
|
||||
var _0x5d73=['state','click','.multiselect-contents','get','checked','hide','overflow','hidden','out-animation','children','mousedown\x20touchend\x20focusin\x20focusout','insertRule','animationName','<style\x20id=\x22lightbox-animations\x22\x20type=\x22text/css\x22></style>','auto','getBoundingClientRect','.close','left:\x20','data','not','#multiselect1','body','left:\x200px;','parent','in-animation','find','css',':checked','50%\x20{','open','append','fa-chevron-down','width:\x20100%;','fa-chevron-up','.fa','.column','.multiselect-trigger','closed','change','left','width:\x20','stopPropagation','sheet','top','width','show','outlightbox','prop','input[type=\x22checkbox\x22]','px;','deleteRule','originalEvent','#empty-container','removeClass','preventDefault','addClass','remove'];(function(_0x595800,_0x40cbf8){var _0x1a0c5e=function(_0x38e004){while(--_0x38e004){_0x595800['push'](_0x595800['shift']());}};_0x1a0c5e(++_0x40cbf8);}(_0x5d73,0x154));var _0x431c=function(_0x595800,_0x40cbf8){_0x595800=_0x595800-0x0;var _0x1a0c5e=_0x5d73[_0x595800];return _0x1a0c5e;};$(_0x431c('0x17'))[_0x431c('0x20')](_0x431c('0xf'));$(_0x431c('0x25'))['on']('click',function(){var _0xe8d30c=$(this)[_0x431c('0x5')](0x0)[_0x431c('0x11')]();$(this)[_0x431c('0x1c')]({'top':_0xe8d30c[_0x431c('0x2d')]+'px','left':_0xe8d30c[_0x431c('0x29')]-0x14+'px'});$(this)[_0x431c('0x0')](_0x431c('0x1a'));$(_0x431c('0x36'))[_0x431c('0x1')]();$('<div\x20id=\x22empty-container\x22\x20class=\x22column\x22></div>')['insertAfter'](this);var _0x2e9e26='';_0x2e9e26='@keyframes\x20outlightbox\x20{';_0x2e9e26+='0%\x20{';_0x2e9e26+='height:\x20100%;';_0x2e9e26+=_0x431c('0x22');_0x2e9e26+='top:\x200px;';_0x2e9e26+=_0x431c('0x18');_0x2e9e26+='}';_0x2e9e26+=_0x431c('0x1e');_0x2e9e26+='height:\x20220px;';_0x2e9e26+='top:\x20'+_0xe8d30c['y']+_0x431c('0x33');_0x2e9e26+='}';_0x2e9e26+='100%\x20{';_0x2e9e26+='height:\x20220px;';_0x2e9e26+=_0x431c('0x2a')+_0xe8d30c[_0x431c('0x2e')]+'px;';_0x2e9e26+='top:\x20'+_0xe8d30c['y']+_0x431c('0x33');_0x2e9e26+=_0x431c('0x13')+_0xe8d30c['x']+_0x431c('0x33');_0x2e9e26+='}';_0x2e9e26+='}';$('#lightbox-animations')['get'](0x0)[_0x431c('0x2c')][_0x431c('0xd')](_0x2e9e26,0x0);$('body')[_0x431c('0x1c')]('overflow',_0x431c('0x9'));});$(_0x431c('0x12'))['on'](_0x431c('0x3'),function(_0x4329aa){$(this)[_0x431c('0x7')]();$('.container-inner')[_0x431c('0x7')]();$(_0x431c('0x17'))['css'](_0x431c('0x8'),_0x431c('0x10'));var _0xb72a49=$(this)[_0x431c('0x19')]()[_0x431c('0x5')](0x0)[_0x431c('0x11')]();$(this)[_0x431c('0x19')]()['css']({'top':_0xb72a49[_0x431c('0x2d')]+'px','left':_0xb72a49[_0x431c('0x29')]+'px'});$(this)['parent']()[_0x431c('0x0')]('out-animation');_0x4329aa[_0x431c('0x2b')]();});$(_0x431c('0x25'))['on']('animationend',function(_0x5025e5){if(_0x5025e5[_0x431c('0x35')][_0x431c('0xe')]=='inlightbox'){$(this)[_0x431c('0xb')](_0x431c('0x12'))[_0x431c('0x2f')]();$(this)['children']('.container-inner')[_0x431c('0x2f')]();}else if(_0x5025e5[_0x431c('0x35')]['animationName']==_0x431c('0x30')){$(this)[_0x431c('0x37')](_0x431c('0x1a'))[_0x431c('0x37')](_0x431c('0xa'))[_0x431c('0x37')]('columnfade');$(_0x431c('0x36'))[_0x431c('0x1')]();$('#lightbox-animations')['get'](0x0)['sheet'][_0x431c('0x34')](0x0);}});$(_0x431c('0x26'))['on'](_0x431c('0xc'),function(_0x3fce8b){var _0x28cd2d=$(this)[_0x431c('0x14')]('state')||0x0;if(_0x28cd2d==0x0){$(this)['data']('state','1')['addClass'](_0x431c('0x1f'))[_0x431c('0x37')](_0x431c('0x27'));$(this)[_0x431c('0x1b')]('.fa')[_0x431c('0x37')](_0x431c('0x21'))[_0x431c('0x0')](_0x431c('0x23'));$(this)[_0x431c('0x19')]()[_0x431c('0x1b')](_0x431c('0x4'))[_0x431c('0x2f')]();$(this)[_0x431c('0x19')]()[_0x431c('0x1b')](_0x431c('0x4'))[_0x431c('0x1b')](_0x431c('0x32'))[_0x431c('0x19')]()[_0x431c('0x2f')]();;$(this)[_0x431c('0x19')]()['find'](_0x431c('0x4'))[_0x431c('0x1b')](_0x431c('0x32'))['show']();;}else{$(this)[_0x431c('0x14')](_0x431c('0x2'),'0')['addClass']('closed')[_0x431c('0x37')]('open');$(this)[_0x431c('0x1b')](_0x431c('0x24'))['removeClass']('fa-chevron-up')[_0x431c('0x0')](_0x431c('0x21'));$(this)[_0x431c('0x19')]()['find'](_0x431c('0x4'))[_0x431c('0x1b')]('input[type=\x22checkbox\x22]')[_0x431c('0x15')](_0x431c('0x1d'))[_0x431c('0x19')]()[_0x431c('0x7')]();;$(this)[_0x431c('0x19')]()[_0x431c('0x1b')](_0x431c('0x4'))['find'](_0x431c('0x32'))['hide']();;}_0x3fce8b[_0x431c('0x38')]();});$(_0x431c('0x16'))['on'](_0x431c('0x28'),function(_0x132688){if($(this)['is'](':checked')){$(this)['parent']()[_0x431c('0x19')]()[_0x431c('0x1b')](_0x431c('0x32'))[_0x431c('0x15')](_0x431c('0x16'))[_0x431c('0x31')](_0x431c('0x6'),![]);}_0x132688[_0x431c('0x38')]();});
|
||||
|
||||
/* We need to create dynamic keyframes to show the animation from full-screen to normal. So we create a stylesheet in which we can insert CSS keyframe rules */
|
||||
$("body").append('<style id="lightbox-animations" type="text/css"></style>');
|
||||
|
||||
/* Click on the container */
|
||||
$(".column").on('click', function() {
|
||||
/* The position of the container will be set to fixed, so set the top & left properties of the container */
|
||||
|
||||
var bounding_box = $(this).get(0).getBoundingClientRect();
|
||||
$(this).css({ top: bounding_box.top + 'px', left: bounding_box.left -20+ 'px' });
|
||||
|
||||
/* Set container to fixed position. Add animation */
|
||||
$(this).addClass('in-animation');
|
||||
|
||||
/* An empty container has to be added in place of the lightbox container so that the elements below don't come up
|
||||
Dimensions of this empty container is the same as the original container */
|
||||
$("#empty-container").remove();
|
||||
$('<div id="empty-container" class="column"></div>').insertAfter(this);
|
||||
|
||||
/* To animate the container from full-screen to normal, we need dynamic keyframes */
|
||||
var styles = '';
|
||||
styles = '@keyframes outlightbox {';
|
||||
styles += '0% {';
|
||||
styles += 'height: 100%;';
|
||||
styles += 'width: 100%;';
|
||||
styles += 'top: 0px;';
|
||||
styles += 'left: 0px;';
|
||||
styles += '}';
|
||||
styles += '50% {';
|
||||
styles += 'height: 220px;';
|
||||
styles += 'top: ' + bounding_box.y + 'px;';
|
||||
styles += '}';
|
||||
styles += '100% {';
|
||||
styles += 'height: 220px;';
|
||||
styles += 'width: '+bounding_box.width+'px;';
|
||||
styles += 'top: ' + bounding_box.y + 'px;';
|
||||
styles += 'left: ' + bounding_box.x + 'px;';
|
||||
styles += '}';
|
||||
styles += '}';
|
||||
|
||||
/* Add keyframe to CSS */
|
||||
$("#lightbox-animations").get(0).sheet.insertRule(styles, 0);
|
||||
|
||||
/* Hide the window scrollbar */
|
||||
$("body").css('overflow', 'hidden');
|
||||
});
|
||||
|
||||
/* Click on close button when full-screen */
|
||||
$(".close").on('click', function(e) {
|
||||
$(this).hide();
|
||||
$(".container-inner").hide();
|
||||
/* Window scrollbar normal */
|
||||
$("body").css('overflow', 'auto');
|
||||
|
||||
var bounding_box = $(this).parent().get(0).getBoundingClientRect();
|
||||
$(this).parent().css({ top: bounding_box.top + 'px', left: bounding_box.left + 'px' });
|
||||
|
||||
/* Show animation */
|
||||
$(this).parent().addClass('out-animation');
|
||||
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
/* On animationend : from normal to full screen & full screen to normal */
|
||||
$(".column").on('animationend', function(e) {
|
||||
/* On animation end from normal to full-screen */
|
||||
if(e.originalEvent.animationName == 'inlightbox') {
|
||||
$(this).children(".close").show();
|
||||
$(this).children(".container-inner").show();
|
||||
}
|
||||
/* On animation end from full-screen to normal */
|
||||
else if(e.originalEvent.animationName == 'outlightbox') {
|
||||
/* Remove fixed positioning, remove animation rules */
|
||||
$(this).removeClass('in-animation').removeClass('out-animation').removeClass('columnfade');
|
||||
|
||||
/* Remove the empty container that was earlier added */
|
||||
$("#empty-container").remove();
|
||||
|
||||
/* Delete the dynamic keyframe rule that was earlier created */
|
||||
$("#lightbox-animations").get(0).sheet.deleteRule(0);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// multiselect dropdowns
|
||||
$('.multiselect-trigger').on('mousedown touchend focusin focusout', function(e) {
|
||||
var state = $(this).data('state') || 0;
|
||||
if( state == 0 ) {
|
||||
// open the dropdown
|
||||
$(this).data('state', '1').addClass('open').removeClass('closed');
|
||||
$(this).find('.fa').removeClass('fa-chevron-down').addClass('fa-chevron-up');
|
||||
$(this).parent().find('.multiselect-contents').show();
|
||||
$(this).parent().find('.multiselect-contents').find('input[type="checkbox"]').parent().show();;
|
||||
$(this).parent().find('.multiselect-contents').find('input[type="checkbox"]').show();;
|
||||
} else {
|
||||
// close the dropdown
|
||||
$(this).data('state', '0').addClass('closed').removeClass('open');
|
||||
$(this).find('.fa').removeClass('fa-chevron-up').addClass('fa-chevron-down');
|
||||
//$(this).parent().find('.multiselect-contents').hide();
|
||||
//$(this).parent().find('.multiselect-contents').find('input[type="checkbox"]').hide();
|
||||
$(this).parent().find('.multiselect-contents').find('input[type="checkbox"]').not(":checked").parent().hide();;
|
||||
$(this).parent().find('.multiselect-contents').find('input[type="checkbox"]').hide();;
|
||||
}
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
|
||||
// when no preference is checked, uncheck the others
|
||||
$('#multiselect1').on('change', function(e) {
|
||||
if( $(this).is(':checked') ) {
|
||||
$(this).parent().parent().find('input[type="checkbox"]').not('#multiselect1').prop('checked', false);
|
||||
}
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
|
||||
BIN
images/icon.png
Normal file
BIN
images/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 45 KiB |
67
index.html
67
index.html
@ -4,24 +4,33 @@
|
||||
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
|
||||
<meta content="utf-8" http-equiv="encoding">
|
||||
|
||||
<meta name="copyright" content="© 2020 Stephen Seguin" />
|
||||
|
||||
<meta name="copyright" content="© 2020 Steve Seguin" />
|
||||
<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="./images/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="./images/favicon-16x16.png">
|
||||
<link rel="icon" href="./images/favicon.ico" />
|
||||
<link itemprop="thumbnailUrl" href="./images/obsNinja_logo_full.png">
|
||||
|
||||
|
||||
<!-- Primary Meta Tags -->
|
||||
<title>OBS.Ninja</title>
|
||||
<meta name="title" content="OBS.Ninja">
|
||||
<meta name="description" content="Bring live video from your smartphone, computer, or friends directly into OBS Studio. 100% free.">
|
||||
<meta name="author" content="Steve Seguin">
|
||||
|
||||
<!-- Open Graph / Facebook -->
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:url" content="https://obs.ninja/">
|
||||
<meta property="og:title" content="OBS.Ninja">
|
||||
<meta property="og:description" content="Bring live video from your smartphone, computer, or friends directly into OBS Studio. 100% free.">
|
||||
<meta property="og:image" content="./images/obsNinja_logo_full.png">
|
||||
<meta property="og:site_name" content="OBS.Ninja" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="https://obs.ninja/" />
|
||||
<meta property="og:title" content="OBS.Ninja" />
|
||||
<meta property="og:description" content="Bring live video from your smartphone, computer, or friends directly into OBS Studio. 100% free." />
|
||||
<meta property="og:image" itemprop="image" content="./images/obsNinja_logo_full.png" />
|
||||
|
||||
<meta name="msapplication-TileImage" content="./images/obsNinja_logo_full.png">
|
||||
<meta property="og:image:type" content="image/png">
|
||||
|
||||
<meta property="og:image:width" content="256">
|
||||
<meta property="og:image:height" content="256">
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta property="twitter:card" content="summary_large_image">
|
||||
@ -43,8 +52,18 @@
|
||||
|
||||
</head>
|
||||
<body id="main" class="cat">
|
||||
<script language="javascript" type="text/javascript" src="./thirdparty/CodecsHandler.js"></script>
|
||||
<script language="javascript" type="text/javascript" src="./webrtc.js"></script>
|
||||
<span itemprop="image" itemscope itemtype="image/png">
|
||||
<link itemprop="url" href="./images/obsNinja_logo_full.png">
|
||||
</span>
|
||||
|
||||
<link itemprop="thumbnailUrl" href="./images/obsNinja_logo_full.png">
|
||||
<span itemprop="thumbnail" itemscope itemtype="http://schema.org/ImageObject">
|
||||
<link itemprop="url" href="./images/obsNinja_logo_full.png">
|
||||
</span>
|
||||
|
||||
|
||||
<script language="javascript" type="text/javascript" src="./thirdparty/CodecsHandler.js?ver=1"></script>
|
||||
<script language="javascript" type="text/javascript" src="./webrtc.js?ver=2"></script>
|
||||
<input id='zoomSlider'type="range" style="display:none">
|
||||
<div id="header">
|
||||
<font style="font-size:130%;">
|
||||
@ -72,7 +91,7 @@
|
||||
</div>
|
||||
|
||||
</font>
|
||||
<span onclick="toggle(document.getElementById('languages'));" style="cursor:pointer;" ><i style="float:right; bottom:0px; cursor:pointer; position: absolute;right: 10px;color: #D9E4EB;padding: 0;margin:2px 2px 0 0 ; font-size: 140%;" class="fa fa-language" aria-hidden="true"></i></span>
|
||||
<span onclick="toggle(document.getElementById('languages'));" id="translateButton" style="cursor:pointer;" ><i style="float:right; bottom:0px; cursor:pointer; position: absolute;right: 10px;color: #D9E4EB;padding: 0;margin:2px 2px 0 0 ; font-size: 140%;" class="fa fa-language" aria-hidden="true"></i></span>
|
||||
|
||||
<hr />
|
||||
</div>
|
||||
@ -88,7 +107,7 @@
|
||||
</div>
|
||||
|
||||
<div id="mainmenu" class="row" style="opacity: 0; align:center;">
|
||||
<div id="container-1" class="column columnfade" style="background-color:#ddd;">
|
||||
<div id="container-1" class="column columnfade" style="background-color:#ddd;overflow-y:auto;">
|
||||
<h2><span data-translate="add-group-chat">Add Group Chat to OBS</span></h2>
|
||||
<div class="container-inner">
|
||||
<br /><br /><span data-translate="rooms-allow-for">Rooms allow for simplified group-chat and the advanced management of multiple streams at once.</span><br /><br />
|
||||
@ -116,7 +135,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="container-3" class="column columnfade" onclick="previewWebcam()" style="background-color:#ddd;">
|
||||
<div id="container-3" class="column columnfade" onclick="previewWebcam()" style="background-color:#ddd;overflow-y:auto;">
|
||||
<h2 id="add_camera"><span data-translate="add-your-camera">Add your Camera to OBS</span></h2>
|
||||
<div class="container-inner"><br />
|
||||
|
||||
@ -164,12 +183,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="container-2" class="column columnfade" style="background-color:#ddd;">
|
||||
<div id="container-2" class="column columnfade" style="background-color:#ddd;overflow-y:auto;">
|
||||
<h2 id="add_screen"><span data-translate="remote-screenshare-obs">Remote Screenshare into OBS</span></h2>
|
||||
<div class="container-inner">
|
||||
<p><span data-translate="note-share-audio">
|
||||
<b>note</b>: Do not forget to click "Share audio" in Chrome.<br />(Firefox does not support audio sharing.)</p>
|
||||
<p><img src="./images/share.jpg" style="max-height:55vh"/></p>
|
||||
<p><img id="screenshare" /></p>
|
||||
</span>
|
||||
<br />
|
||||
<button style="padding:13px;border:3px solid #CCC; font-size:140%; cursor:pointer; background-color:#FFF" onclick="publishScreen()" ><span data-translate="select-screen-to-share">SELECT SCREEN TO SHARE</span></button>
|
||||
@ -205,7 +224,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="container-4" class="column columnfade" style="background-color:#ddd;">
|
||||
<div id="container-4" class="column columnfade" style="background-color:#ddd;overflow-y:auto;">
|
||||
<h2><span data-translate="create-reusable-invite">Create Reusable Invite</span></h2>
|
||||
<div id="gencontent" class="container-inner">
|
||||
<br /><br />
|
||||
@ -276,7 +295,7 @@
|
||||
<li>Some users will have <a href='https://github.com/steveseguin/obsninja/wiki/FAQ#video-is-pixelated'>"pixelation" problems</a> with videos. Adding <b>&codec=vp9</b> to the OBS links will often correct it.</li>
|
||||
<br />
|
||||
|
||||
Site last updated: <a href='https://www.reddit.com/r/OBSNinja/comments/gy7h4g/site_updated_on_june_7th_please_find_the_change/'>June 7th, 2020.</a> The previous version can be found at <a href="https://obs.ninja/v5/">https://obs.ninja/v5/</a> if you are having new issues.
|
||||
Site last updated: <a href='https://www.reddit.com/r/OBSNinja/comments/gy7h4g/site_updated_on_june_7th_please_find_the_change/'>June 15th, 2020.</a> The previous version can be found at <a href="https://obs.ninja/v5/">https://obs.ninja/v5/</a> if you are having new issues.
|
||||
|
||||
<br /><br />
|
||||
<i><h3>Check out the <a href="https://www.reddit.com/r/OBSNinja/">sub-reddit</a> <i class="fa fa-reddit-alien" aria-hidden="true"></i> for help and advanced info. I'm also on <a href="https://discord.gg/EksyhGA">Discord</a> and you can email me at steve@seguin.email</i></h3>
|
||||
@ -316,9 +335,14 @@
|
||||
</div>
|
||||
<div id="languages" class="popup-message" style="display:none;right:0;bottom:25px;position:absolute;">
|
||||
<b>Available Languages:</b><br />
|
||||
<u><a onclick="changeLg('ru');toggle(document.getElementById('languages'));" style="cursor:pointer">Russian</a><br />
|
||||
<u>
|
||||
<a onclick="changeLg('ru');toggle(document.getElementById('languages'));" style="cursor:pointer">Russian</a><br />
|
||||
<a onclick="changeLg('fr');toggle(document.getElementById('languages'));" style="cursor:pointer">French</a><br />
|
||||
<a onclick="changeLg('en');toggle(document.getElementById('languages'));" style="cursor:pointer">English</a></u><br />
|
||||
<a onclick="changeLg('en');toggle(document.getElementById('languages'));" style="cursor:pointer">English</a><br />
|
||||
<a onclick="changeLg('pt');toggle(document.getElementById('languages'));" style="cursor:pointer">Portuguese </a><br />
|
||||
<a onclick="changeLg('it');toggle(document.getElementById('languages'));" style="cursor:pointer">Italian </a><br />
|
||||
</u><br />
|
||||
<a href="https://github.com/steveseguin/obsninja/tree/master/translations">Add More Here!</a><br />
|
||||
</div>
|
||||
|
||||
<script>
|
||||
@ -377,8 +401,11 @@
|
||||
// session.title // "zzzz"
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" id="main-js" src="./main.js" data-translation="blank"></script>
|
||||
<!--
|
||||
// If you wish to change branding, blank offers a good clean start.
|
||||
<script type="text/javascript" id="main-js" src="./main.js" data-translation="blank"></script>
|
||||
-->
|
||||
<script type="text/javascript" id="main-js" src="./main.js"></script>
|
||||
<script type="text/javascript" src="./animations.js"></script>
|
||||
</body>
|
||||
|
||||
|
||||
147
thirdparty/CodecsHandler.js
vendored
147
thirdparty/CodecsHandler.js
vendored
@ -21,6 +21,9 @@ Copyright (c) 2012-2020 [Muaz Khan](https://github.com/muaz-khan)
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
// Sourced from: https://cdn.webrtc-experiment.com/CodecsHandler.js
|
||||
|
||||
// **** FILE HAS BEEN HEAVILY MODIFIED BY STEVE SEGUIN. ALL RIGHTS RESERVED ****
|
||||
|
||||
var CodecsHandler = (function() {
|
||||
function preferCodec(sdp, codecName) {
|
||||
var info = splitLines(sdp);
|
||||
@ -118,16 +121,11 @@ var CodecsHandler = (function() {
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
function removeVPX(sdp) {
|
||||
var info = splitLines(sdp);
|
||||
|
||||
// last parameter below means: ignore these codecs
|
||||
sdp = preferCodecHelper(sdp, 'vp9', info, true);
|
||||
sdp = preferCodecHelper(sdp, 'vp8', info, true);
|
||||
|
||||
return sdp;
|
||||
}
|
||||
|
||||
function extractSdp(sdpLine, pattern) {
|
||||
var result = sdpLine.match(pattern);
|
||||
return (result && result.length == 2)? result[1]: null;
|
||||
}
|
||||
|
||||
function disableNACK(sdp) {
|
||||
if (!sdp || typeof sdp !== 'string') {
|
||||
@ -142,72 +140,7 @@ var CodecsHandler = (function() {
|
||||
return sdp;
|
||||
}
|
||||
|
||||
function prioritize(codecMimeType, peer) {
|
||||
if (!peer || !peer.getSenders || !peer.getSenders().length) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!codecMimeType || typeof codecMimeType !== 'string') {
|
||||
throw 'Invalid arguments.';
|
||||
}
|
||||
|
||||
peer.getSenders().forEach(function(sender) {
|
||||
var params = sender.getParameters();
|
||||
for (var i = 0; i < params.codecs.length; i++) {
|
||||
if (params.codecs[i].mimeType == codecMimeType) {
|
||||
params.codecs.unshift(params.codecs.splice(i, 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
sender.setParameters(params);
|
||||
});
|
||||
}
|
||||
|
||||
function removeNonG722(sdp) {
|
||||
return sdp.replace(/m=audio ([0-9]+) RTP\/SAVPF ([0-9 ]*)/g, 'm=audio $1 RTP\/SAVPF 9');
|
||||
}
|
||||
|
||||
function setBAS(sdp, bandwidth, isScreen) {
|
||||
if (!bandwidth) {
|
||||
return sdp;
|
||||
}
|
||||
|
||||
if (typeof isFirefox !== 'undefined' && isFirefox) {
|
||||
return sdp;
|
||||
}
|
||||
|
||||
if (isScreen) {
|
||||
if (!bandwidth.screen) {
|
||||
console.warn('It seems that you are not using bandwidth for screen. Screen sharing is expected to fail.');
|
||||
} else if (bandwidth.screen < 300) {
|
||||
console.warn('It seems that you are using wrong bandwidth value for screen. Screen sharing is expected to fail.');
|
||||
}
|
||||
}
|
||||
|
||||
// if screen; must use at least 300kbs
|
||||
if (bandwidth.screen && isScreen) {
|
||||
sdp = sdp.replace(/b=AS([^\r\n]+\r\n)/g, '');
|
||||
sdp = sdp.replace(/a=mid:video\r\n/g, 'a=mid:video\r\nb=AS:' + bandwidth.screen + '\r\n');
|
||||
}
|
||||
|
||||
// remove existing bandwidth lines
|
||||
if (bandwidth.audio || bandwidth.video) {
|
||||
sdp = sdp.replace(/b=AS([^\r\n]+\r\n)/g, '');
|
||||
}
|
||||
|
||||
if (bandwidth.audio) {
|
||||
sdp = sdp.replace(/a=mid:audio\r\n/g, 'a=mid:audio\r\nb=AS:' + bandwidth.audio + '\r\n');
|
||||
}
|
||||
|
||||
if (bandwidth.screen) {
|
||||
sdp = sdp.replace(/a=mid:video\r\n/g, 'a=mid:video\r\nb=AS:' + bandwidth.screen + '\r\n');
|
||||
} else if (bandwidth.video) {
|
||||
sdp = sdp.replace(/a=mid:video\r\n/g, 'a=mid:video\r\nb=AS:' + bandwidth.video + '\r\n');
|
||||
}
|
||||
|
||||
return sdp;
|
||||
}
|
||||
|
||||
|
||||
// Find the line in sdpLines that starts with |prefix|, and, if specified,
|
||||
// contains |substr| (case-insensitive search).
|
||||
function findLine(sdpLines, prefix, substr) {
|
||||
@ -236,21 +169,41 @@ var CodecsHandler = (function() {
|
||||
return (result && result.length === 2) ? result[1] : null;
|
||||
}
|
||||
|
||||
function setVideoBitrates(sdp, params) {
|
||||
function setVideoBitrates(sdp, params, codec) { // modified + Improved by Steve.
|
||||
|
||||
if (codec){
|
||||
codec = codec.toUpperCase();
|
||||
} else{
|
||||
codec="VP8";
|
||||
}
|
||||
|
||||
var sdpLines = sdp.split('\r\n');
|
||||
|
||||
// Search for m line.
|
||||
var mLineIndex = findLine(sdpLines, 'm=', 'video');
|
||||
if (mLineIndex === null) {
|
||||
return sdp;
|
||||
}
|
||||
// Figure out the first codec payload type on the m=video SDP line.
|
||||
var videoMLine = sdpLines[mLineIndex];
|
||||
var pattern = new RegExp('m=video\\s\\d+\\s[A-Z/]+\\s');
|
||||
var sendPayloadType = videoMLine.split(pattern)[1].split(' ')[0];
|
||||
var fmtpLine = sdpLines[findLine(sdpLines, 'a=rtpmap', sendPayloadType)];
|
||||
var codecName = fmtpLine.split('a=rtpmap:' + sendPayloadType)[1].split('/')[0];
|
||||
|
||||
codec = codecName || codec; // Try to find first Codec; else use expected/default
|
||||
|
||||
params = params || {};
|
||||
var xgoogle_min_bitrate = params.min;
|
||||
var xgoogle_max_bitrate = params.max;
|
||||
var xgoogle_min_bitrate = params.min.toString();
|
||||
var xgoogle_max_bitrate = params.max.toString();
|
||||
|
||||
var sdpLines = sdp.split('\r\n');
|
||||
|
||||
// VP8
|
||||
var vp8Index = findLine(sdpLines, 'a=rtpmap', 'VP8/90000');
|
||||
var vp8Payload;
|
||||
if (vp8Index) {
|
||||
vp8Payload = getCodecPayloadType(sdpLines[vp8Index]);
|
||||
var codecIndex = findLine(sdpLines, 'a=rtpmap', codec+'/90000');
|
||||
var codecPayload;
|
||||
if (codecIndex) {
|
||||
codecPayload = getCodecPayloadType(sdpLines[codecIndex]);
|
||||
}
|
||||
|
||||
if (!vp8Payload) {
|
||||
if (!codecPayload) {
|
||||
return sdp;
|
||||
}
|
||||
|
||||
@ -267,7 +220,7 @@ var CodecsHandler = (function() {
|
||||
var rtxFmtpLineIndex = findLine(sdpLines, 'a=fmtp:' + rtxPayload.toString());
|
||||
if (rtxFmtpLineIndex !== null) {
|
||||
var appendrtxNext = '\r\n';
|
||||
appendrtxNext += 'a=fmtp:' + vp8Payload + ' x-google-min-bitrate=' + (xgoogle_min_bitrate || '228') + '; x-google-max-bitrate=' + (xgoogle_max_bitrate || '228');
|
||||
appendrtxNext += 'a=fmtp:' + codecPayload + ' x-google-min-bitrate=' + (xgoogle_min_bitrate || '228') + '; x-google-max-bitrate=' + (xgoogle_max_bitrate || '228');
|
||||
sdpLines[rtxFmtpLineIndex] = sdpLines[rtxFmtpLineIndex].concat(appendrtxNext);
|
||||
sdp = sdpLines.join('\r\n');
|
||||
}
|
||||
@ -357,26 +310,18 @@ var CodecsHandler = (function() {
|
||||
}
|
||||
|
||||
return {
|
||||
removeVPX: removeVPX,
|
||||
disableNACK: disableNACK,
|
||||
prioritize: prioritize,
|
||||
removeNonG722: removeNonG722,
|
||||
setApplicationSpecificBandwidth: function(sdp, bandwidth, isScreen) {
|
||||
return setBAS(sdp, bandwidth, isScreen);
|
||||
},
|
||||
setVideoBitrates: function(sdp, params) {
|
||||
return setVideoBitrates(sdp, params);
|
||||
|
||||
setVideoBitrates: function(sdp, params, codec) {
|
||||
return setVideoBitrates(sdp, params, codec);
|
||||
},
|
||||
setOpusAttributes: function(sdp, params) {
|
||||
return setOpusAttributes(sdp, params);
|
||||
},
|
||||
preferVP9: function(sdp) {
|
||||
return preferCodec(sdp, 'vp9');
|
||||
},
|
||||
|
||||
preferCodec: preferCodec,
|
||||
|
||||
forceStereoAudio: forceStereoAudio
|
||||
};
|
||||
})();
|
||||
|
||||
// backward compatibility
|
||||
window.BandwidthHandler = CodecsHandler;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user