Skip to content

Instantly share code, notes, and snippets.

@atauenis
Last active December 12, 2019 16:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save atauenis/bdb542b95b87d1434007dfc50d5eac6f to your computer and use it in GitHub Desktop.
Save atauenis/bdb542b95b87d1434007dfc50d5eac6f to your computer and use it in GitHub Desktop.
URL generator for WebOne & avconv video converting
<html>
<body>
<p>
<b>Video options</b><br>
Source: <input type='text' id='avcVideoUrl' value='http://example.com/video.mkv' size='100' />
</p>
<div style="width: 400px; color: white; background-color: black; padding: 5px;">
<p style="margin: 4px">
<input type='checkbox' id='avcUseProxy' title='Use WebOne proxy server' onchange='SetAvcControls()'/>WebOne:
<input type='text' id='avcWebOneHost' title='Proxy URL' value='ProxyHost' size='10' />
<select id='avcContainer' title='Container'>
<option value=' -f mp4'>MP4</option>
<option value=' -f mpegts'>MTS</option>
<option value=' -f avi'>AVI</option>
<option value=' -f asf'>ASF</option>
<option value=' -f asf_stream'>ASF*</option>
</select>
</p>
<p style="margin: 4px" id='avcControls'>
<select id='avcVCodec' title='Video codec'>
<option value=' -vcodec copy'>Orig.</option>
<option value=' -vcodec h264'>h264</option>
<option value=' -vcodec mpeg1video'>MP1</option>
<option value=' -vcodec mpeg2video'>MP2</option>
<option value=' -vcodec mpeg4' >MP4</option>
<option value=' -vcodec msmpeg4'>MP4*</option>
<option value=' -vcodec wmv1'>WMV7</option>
<option value=' -vcodec wmv2'>WMV8</option>
<option value=' -vcodec wmv3'>WMV9</option>
</select>
<select id='avcVSize' title='Size'>
<option value=''>Orig.</option>
<option value=' -s 128x96'>96</option>
<option value=' -s 256x144'>144</option>
<option value=' -s 320x240'>240</option>
<option value=' -s 480x360'>360</option>
<option value=' -s 640x480'>480</option>
<option value=' -s 1280x720'>720</option>
<option value=' -s 1920x1080'>1080</option>
</select>
<input type='text' id='avcVBitrate' title='Video bitrate' value='auto' size='2' />
/
<select id='avcACodec' title='Audio codec'>
<option value=' -acodec copy'>Original</option>
<option value=' -acodec mp2'>MP2</option>
<option value=' -acodec mp3' >MP3</option>
<option value=' -acodec aac'>AAC</option>
<option value=' -acodec ac3'>AC-3</option>
<option value=' -acodec wmav1'>WMA1</option>
<option value=' -acodec wmav2'>WMA2</option>
<option value=' -acodec vorbis'>Vorbis</option>
</select>
<select id='avcAChannels' title='Channels'>
<option value=''>Original</option>
<option value=' -ac 1'>Mono</option>
<option value=' -ac 2'>Stereo</option>
<option value=' -ac 4'>Quadro</option>
</select>
<input type='text' id='avcABitrate' title='Audio bitrate' value='auto' size='2' />
</p>
</div>
<p><input type='button' onclick='GetAvcURL()' value='Get URL' /><br>
URL: <input type='text' id='avcPlayer' size='255' /></p>
<p>
This should work with full version of <a href='https://github.com/atauenis/webone/releases/'>WebOne proxy server</a>.
</p>
<script>
function GetAvcURL(){
//check if proxy should be used
if(!document.getElementById('avcUseProxy').checked)
{ document.getElementById('avcPlayer').value = document.getElementById('avcVideoUrl').value; return; }
var avcSrcUrl = document.getElementById('avcVideoUrl').value.replace('http://','https://'); //if browser uses WebOne as default proxy for pages, video link will be always HTTP
//check for DVL mode
if (avcSrcUrl.indexOf('https://www.youtube.com/watch') != -1)
{ document.getElementById('avcPlayer').value = avcSrcUrl; return; }
//make proxy and source URL
var avcUrl = 'http://' + document.getElementById('avcWebOneHost').value + '/!convert?url=';
avcUrl += encodeURIComponent(avcSrcUrl) + '&util=avconv&arg=';
//make parameters
var avcArgs = document.getElementById('avcVCodec').value
+ document.getElementById('avcVSize').value
+ document.getElementById('avcACodec').value
+ document.getElementById('avcAChannels').value
+ document.getElementById('avcContainer').value;
var avcVBitrate = document.getElementById('avcVBitrate').value;
if (avcVBitrate != '' && avcVBitrate != 'auto') { avcVBitrate = ' -b:v ' + avcVBitrate; }
else avcVBitrate = '';
avcArgs += avcVBitrate;
var avcABitrate = document.getElementById('avcABitrate').value;
if (avcABitrate != '' && avcABitrate != 'auto') { avcABitrate = ' -b:a ' + avcABitrate; }
else avcABitrate = '';
avcArgs += avcABitrate;
//glue parameters to url
avcUrl += encodeURIComponent(avcArgs);
avcUrl += "&type=video/avi"; //don't important but otherwise proxy will return MIME-type of XBM that may confuse some players/browsers
document.getElementById('avcPlayer').value = avcUrl;
}
function SetAvcControls(){
//show or hide A/V converter control box
document.getElementById('avcControls').style.display = document.getElementById('avcUseProxy').checked ? 'block' : 'none';
}
SetAvcControls();
</script>
</body>
</html>
@sebaro
Copy link

sebaro commented Dec 2, 2019

Add 'Proxy' or other name here:

var option = {... 'proxy_container': '', 'proxy_codec_audio': '', ...};
var embedtypes = ['Video', 'Object', 'Embed', 'Protocol', 'Proxy'];

Create the proxy options object:

var proxyobject = {
   'containers': {'MP4': 'mp4', 'MTS': 'mpegts'},
   'codecs': {
      'audio': {'Orig': 'copy', 'MP3': 'mp3'},
      'video': {'Orig': 'copy', 'H264': 'h264'}
   },
   'sizes': {},
   'channels': {}
};

Create the options:

function createMyOptions() {
...
    /* Proxy Containers */
    var proxycontainers = proxyobject['containers'];
    entryOption = createMyElement('div');
    styleMyElement(entryOption, {display: 'block', padding: '20px 0px 20px 0px'});
    appendMyElement(player['optionsContent'], entryOption);
    var containerOption = createMyElement('div');
    styleMyElement(containerOption, {display: 'inline-block'});
    var containerOptionLabel = createMyElement('div', 'Container');
    styleMyElement(containerOptionLabel, {display: 'inline-block', color: '#CCCCCC', marginRight: '10px'});
    var containerOptionMenu = createMyElement('select', '', change, '', 'proxy_container');
    styleMyElement(containerOptionMenu, {display: 'inline-block', color: '#CCCCCC', backgroundColor: '#000000', border: '1px solid #777777', fontSize: '14px', fontWeight: 'bold', marginRight: '10px'});
    appendMyElement(containerOption, containerOptionLabel);
    appendMyElement(containerOption, containerOptionMenu);
    appendMyElement(entryOption, containerOption);
    var containerOptionMenuItem;
    for (var container in proxycontainers) {
      containerOptionMenuItem = createMyElement('option', container);
      containerOptionMenuItem.value = proxycontainers[container];
      styleMyElement(containerOptionMenuItem, {fontSize: '14px', fontWeight: 'bold', cursor: 'pointer'});
      appendMyElement(containerOptionMenu, containerOptionMenuItem);
    }
    containerOptionMenu.value = option['proxy_container'];

    /* Codecs */
    var proxycodecsaudio = proxyobject['codecs']['audio'];
    var proxycodecsvideo = proxyobject['codecs']['video'];
    entryOption = createMyElement('div');
    styleMyElement(entryOption, {display: 'block', padding: '20px 0px 20px 0px'});
    appendMyElement(player['optionsContent'], entryOption);
    ...

    /* Sizes */
    var proxysizes= proxyobject['sizes'];
    entryOption = createMyElement('div');
    styleMyElement(entryOption, {display: 'block', padding: '20px 0px 20px 0px'});
    appendMyElement(player['optionsContent'], entryOption);
    ...

    /* Channels */
    var proxychannels= proxyobject['channels'];
    entryOption = createMyElement('div');
    styleMyElement(entryOption, {display: 'block', padding: '20px 0px 20px 0px'});
    appendMyElement(player['optionsContent'], entryOption);
    ...

Change events:

function createMyElement
...
if (event == 'change') {
...
    else if (target == 'proxy_container') {
      obj.addEventListener('change', function() {
	option['proxy_container'] = this.value;
	setMyOptions('proxy_container', option['proxy_container']);
      }, false);
    }
    else if (target == 'proxy_codec_audio') {
    ...

Change playback link:

function playMyVideo
...
// player['contentVideo'] = createMyElement(option['embed'].toLowerCase(), player['videoList'][player['videoPlay']]);
if (option['embed'] == 'Proxy') {
  var avconvargs = &util=avconv&arg=-s%20'  + option['proxy_size'] + '%20-vcodec%20' + option['proxy_codec_video'] + '%20-acodec%20' + option['proxy_codec_audio'] + '%20-f%20' + otion['proxy_container'] + '&type=video/avi';
  var proxylink = 'http://ProxyHost/!convert/?url=' + encodeURIComponent(player['videoList'][player['videoPlay']]) + avconvargs;
  player['contentVideo'] = createMyElement(option['embed'].toLowerCase(), proxylink);
}
else {
  player['contentVideo'] = createMyElement(option['embed'].toLowerCase(), player['videoList'][player['videoPlay']]);
}

@atauenis
Copy link
Author

atauenis commented Dec 5, 2019

Thanks, but this is not what I need. The proxy options tab should contain textboxes like in example (server name and bitrates) and work with all: video/object/embed/protocol if checkbox is checked. So it's why I want to play with userscript code, which as I see don't know anything other than semi-unscripted div, select, option and video tags.

Most likely I'll go out from current widget addition code and simply embed the HTML with scripts onto options window, then add saving to cookie (via setMyOptions(key, value), getMyOptions()) and then patch playMyVideo(play) (by adding player['videoList'][player['videoPlay']] = GetAvcURL();).

@sebaro
Copy link

sebaro commented Dec 5, 2019

OK, then add 'Proxy' also as an option, then if it's 'on', modify player['videoList'][player['videoPlay']] link before embeding/playing with one of the 4 options.
option = {... 'proxy': true/false, 'proxy_container': ''...}

@sebaro
Copy link

sebaro commented Dec 11, 2019

With the new changes you can create the proxy options like this:

var option = {..., 'proxy': true, 'proxy_codec_video': 'h264', 'proxy_codec_audio': ...}
...
// Proxy Options
var pselect, poption;
// Proxy Toggle
var pselect = createMyElements('select', '', 'change', function() {
   option['proxy'] = (this.value == 'On') ? true : false;
   setMyOptions('proxy', option['proxy']);
});
appendMyElement(player['optionsContent'], pselect);
for (var i = 0; i < ['On', 'Off'].length; i++) {
   poption = createMyElement('option', {value: ['On', 'Off'][i], textContent: ['On', 'Off'][i]});
   appendMyElement(pselect, poption);
}
if (option['proxy']) pselect.value = 'On';
else pselect.value = 'Off';
// Proxy Codecs Video
var codecs_video = {'Original': 'copy', 'h264': 'H.264'}
var pselect = createMyElements('select', '', 'change', function() {
   option['proxy_codec_video'] = this.value;
   setMyOptions('proxy_codec_video', option['proxy_codec_video']);
});
appendMyElement(player['optionsContent'], pselect);
for (var key in codecs_video) {
   poption = createMyElement('option', {value: key, textContent: codecs_video[key]});
   appendMyElement(pselect, poption);
}
pselect.value = option['proxy_codec_video'];
// repeat the above for each transcoding option.
...

// playMyVideo
...
// var videoProperties, videoType;
var videoProperties, videoType, videoSource;
if (option['proxy']) {
  var avconvargs = &util=avconv&arg=-s%20'  + option['proxy_size'] + '%20-vcodec%20' + option['proxy_codec_video'] + '%20-acodec%20' + option['proxy_codec_audio'] + '%20-f%20' + option['proxy_container'] + '&type=video/avi';
  var videoSource = 'http://ProxyHost/!convert/?url=' + encodeURIComponent(player['videoList'][player['videoPlay']]) + avconvargs;
}
else {
   videoSource = player['videoList'][player['videoPlay']];
}
// replace player['videoList'][player['videoPlay']] with videoSource in the next lines.

@atauenis
Copy link
Author

Thanks for help. Implemented the fork from v2019.12.05.
https://github.com/atauenis/webone/blob/master/viewtube/viewtube-webone.user.js
https://github.com/atauenis/webone/blob/master/viewtube/Readme-userscript.txt

And successfully used it to found few bugs in my proxy. :)

@sebaro
Copy link

sebaro commented Dec 12, 2019

I've made some changes to reduce the code for options window:
http://sebaro.pro/viewtube/files/viewtubetest.user.js

This takes the option entry from an object:
option: [label, options, new line, change video]
eg:
'avcContainer': ['Proxy container', Object.keys(proxyobject['containers']), false, false]

Incompatibilities with your code:
1 different proxy keys vs option keys, 'containers' vs 'avcContainer'
2 same value/textContent, if you use the same key on the first issue, you can replace value: options[o][1][i] with value: proxyobject[o][options[o][1][i]]
3 no support for input, so you have to check 'options' type, if it's an object create a select, else create an input:

if (typeof options[o][1] === 'object') {
   optionMenu = createMyElement('select', {id: o}, 'change', function() {
   ...
}
else {
   optionInput= createMyElement('input', {id: o, type: 'text', size: '10'}, 'blur', function() {
   ...
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment