stream4chan

Click the button to stream all webms in a 4chan thread

Stan na 24-10-2016. Zobacz najnowsza wersja.

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Greasemonkey lub Violentmonkey.

You will need to install an extension such as Tampermonkey to install this script.

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Violentmonkey.

Aby zainstalować ten skrypt, wymagana będzie instalacja rozszerzenia Tampermonkey lub Userscripts.

You will need to install an extension such as Tampermonkey to install this script.

Aby zainstalować ten skrypt, musisz zainstalować rozszerzenie menedżera skryptów użytkownika.

(Mam już menedżera skryptów użytkownika, pozwól mi to zainstalować!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Musisz zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

(Mam już menedżera stylów użytkownika, pozwól mi to zainstalować!)

// ==UserScript==
// @name         stream4chan
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Click the button to stream all webms in a 4chan thread
// @author       Lauchlan105
// @match        http://boards.4chan.org/*/thread/*
// @grant        none
// ==/UserScript==

//Main
(function() {
    createElements();
    initElements();
    startEvents();
})();

function createElements(){
    //Script Settings
    countStep = 1; //Duration step
    debugOn = false;
    hiddenPrints = [];
    var checked = 'checked';
    var notChecked = '';
    var autoPlayDefault = checked;
    var playWebmsDefault = checked;
    var playGifsDefault = checked;
    var loopThreadDefault = checked;
    var randomDefault = notChecked;
    var durationDefault = '3'; //seconds



    //Settings Header
    var modalSettings_auto = '<input id="stream4chan-auto?" class="SFC-input" type="checkbox" ' + autoPlayDefault + '> Play Automatically';
    var modalSettings_webms = '<input id="stream4chan-webms?" class="SFC-input" type="checkbox" ' + playWebmsDefault + '> Play Webms';
    var modalSettings_gifs = '<input id="stream4chan-gifs?" class="SFC-input" type="checkbox" ' + playGifsDefault + '> Play Gifs';
    var modalSettings_loopAll = '<input id="stream4chan-loopAll?" class="SFC-input" type="checkbox" ' + loopThreadDefault + '> Loop whole thread';
    var modalSettings_shuffle = '<input id="stream4chan-shuffle?" class="SFC-input" type="button" value=" shuffle ">';
    var modalSettings_random = '<input id="stream4chan-random?" class="SFC-input" type="checkbox" ' + randomDefault + '> Random';
    var modalSettings_duration = '<input id="stream4chan-duration?" class="SFC-input" type="number" min="' + countStep + '" max="60" value="' + durationDefault + '" step="' + countStep + '"> Gif Duration (Seconds)';
    var modalSettings_exit = '<div id="SFC-exit" class="SFC-li SFC-exit"></div>';
    var modalSettings = '<div id="stream4chan-settings" class="SFC-settings">' + modalSettings_auto + modalSettings_webms + modalSettings_gifs + modalSettings_loopAll + modalSettings_shuffle + modalSettings_random + modalSettings_duration + modalSettings_exit + '</div>';

/*
    var modalSettings_auto = '<li class="SFC-li"><input id="stream4chan-auto?" class="SFC-input" type="checkbox" ' + autoPlayDefault + '> Play Automatically</li>';
    var modalSettings_webms = '<li class="SFC-li"><input id="stream4chan-webms?" class="SFC-input" type="checkbox" ' + playWebmsDefault + '> Play Webms</li>';
    var modalSettings_gifs = '<li class="SFC-li"><input id="stream4chan-gifs?" class="SFC-input" type="checkbox" ' + playGifsDefault + '> Play Gifs</li>';
    var modalSettings_loopAll = '<li class="SFC-li"><input id="stream4chan-loopAll?" class="SFC-input" type="checkbox" ' + loopThreadDefault + '> Loop whole thread</li>';
    var modalSettings_shuffle = '<li class="SFC-li"><input id="stream4chan-shuffle?" class="SFC-input" type="button" value=" shuffle "></li>';
    var modalSettings_random = '<li class="SFC-li"><input id="stream4chan-random?" class="SFC-input" type="checkbox" ' + randomDefault + '> Random</li>';
    var modalSettings_exit = '<li class="SFC-li SFC-exit"></li>';
    var modalSettings_duration = '<li class="SFC-li"><input id="stream4chan-duration?" class="SFC-input" type="number" min="' + countStep + '" max="60" value="' + durationDefault + '" step="' + countStep + '"> Gif Duration (Seconds)</li>';
    var modalSettings = '<ul id="stream4chan-settings" class="SFC-settings">' + modalSettings_auto + modalSettings_webms + modalSettings_gifs + modalSettings_loopAll + modalSettings_shuffle + modalSettings_random + modalSettings_duration + modalSettings_exit + '</ul>';
*/
    //Content Table
    var modalContent = '<div id="stream4chan-content" class="SFC-content"></div>';
    var modalContent_Left = '<th id="stream4chan-prev" class="SFC_th_left SFC_arrow"></th>';
    var modalContent_Right = '<th id="stream4chan-next" class="SFC_th_right SFC_arrow"></th>';
    var modalContent_Mid = '<th class="SFC_th_mid">' + modalSettings + modalContent + '</th>';
    var modalTable = '<table id="stream4chan-table" class="SFC_table"><tr class="SFC_table_row">' + modalContent_Left + modalContent_Mid + modalContent_Right + '</tr></table>';

    //Main Div
    var startBtn = '<input id="stream4chan-start" style="margin-left:1em;" type="button" value="Run Slideshow" >';
    var resumeBtn = '<input id="stream4chan-resume" style="margin-left:1em;" type="button" value="Resume Slideshow" >';
    var modalMain = '<div id="stream4chan-modal" class="SFC-modal">' + modalTable + '</div>';

    //CSS
    var settingsCSS = '.SFC-settings { opacity: 0.35; display: inline-block; list-style-type: none; width:100%; top: 0; height: auto; margin: 0em; padding-top: 0.5em; color:#9d9393; }';
    var hoverCSS = '.SFC-settings:hover { opacity: 1; } .SFC-settings:last-child:hover { opacity: 0; }';
    var settingsInputCSS = '.SFC-input { margin: 0em 0em 0em 1.5em; padding: 0em;  }';
    var settingsExitCSS = '.SFC-exit { float: right; height: 28px; width: 28px; background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/7/72/VisualEditor_-_Icon_-_Close_-_white.svg/2000px-VisualEditor_-_Icon_-_Close_-_white.svg.png"); background-size: contain; }';
    var AllSettingsCSS = settingsCSS + hoverCSS + settingsInputCSS + settingsExitCSS;

    //table
    var tableCSS = '.SFC_table { max-height: 100vh; min-height: 100vh; max-width: 100vw; min-width: 100vw; } ';
    var tableRowCSS = '.SFC_table_row { vertical-align: top; }';
    var arrowCSS = '.SFC_arrow { width: 15px; padding: 15px; height: 100%; background-image: url("http://www.dsetechnology.co.uk/images/disclose-arrow.png"); background-repeat: no-repeat; background-position: center; background-color: rgba(255, 255, 255, 0); background-size: contain; }';
    var leftCSS = '.SFC_th_left { transform: rotate(180deg); }' + '.SFC_th_left:hover { background-color:rgba(255, 255, 255, 0.6); }';
    var rightCSS = '.SFC_th_right {  }' + '.SFC_th_right:hover { background-color:rgba(255, 255, 255, 0.6); }';
    var midCSS = '.SFC_th_mid { height: 100vh;  }';
    var allTableCSS = tableCSS + tableRowCSS + arrowCSS + leftCSS + rightCSS + midCSS;

    var mediaCSS = '.SFC-media { width: 100%; }';
    var contentCSS = '.SFC-content { display: block; color: white; }';
    var modalCSS = ' .SFC-modal { display: none; height: 100vh; width: 100vw; position: fixed; z-index: 1; left: 0; top: 0; background-color: rgba(0,0,0,0.75); -webkit-box-shadow: inset 0px 0px 71px 41px rgba(0,0,0,0.75); -moz-box-shadow: inset 0px 0px 71px 41px rgba(0,0,0,0.75); box-shadow: inset 0px 0px 71px 41px rgba(0,0,0,0.75);}';
    var allModalCSS = mediaCSS + contentCSS + modalCSS;
    var allCSS = '<style>' + allModalCSS + allTableCSS + AllSettingsCSS + '</style>';


    //Add start and resume buttons
    var nav = document.getElementsByClassName('navLinks desktop');
    for(var i = 0; i < nav.length; i++){
        debug('adding button to nav ' + i);

        var span = document.createElement('span');

        span.innerHTML = startBtn + resumeBtn;
        span.className = 'stream4chan-start';
        span.style.display = nav[i].style.display;

        nav[i].parentNode.insertBefore(span, nav[i]);
        nav[i].parentNode.insertBefore(document.getElementById('op'), nav[i]);
    }

    //add the modal to start of thread
    var target = document.getElementsByClassName('thread');
    for(i = 0; i < target.length; i++){
        target[i].innerHTML = (modalMain + allCSS) + target[i].innerHTML;
    }
}

function initElements(){
    modal = document.getElementById('stream4chan-modal');
    if(!modal){ debug('Modal not found!'); }

    table = document.getElementById('stream4chan-table');
    if(!table){ debug('Table not found!'); }

    settings = document.getElementById('stream4chan-settings');
    if(!settings){ debug('Settings not found!'); }

    content = document.getElementById('stream4chan-content');
    if(!content){ debug('Content not found!'); }

    //Interactable Elements
    prevButton = document.getElementById('stream4chan-prev');
    if(!prevButton){ debug('Previous Button not found!'); }

    nextButton = document.getElementById('stream4chan-next');
    if(!nextButton){ debug('Next Button not found!'); }

    startButton = document.getElementById('stream4chan-start');
    if(!startButton){ debug('Start Button could not be found!');}

    resumeButton = document.getElementById('stream4chan-resume');
    if(!resumeButton){ debug('Resume Button could not be found!');}

    autoplay = document.getElementById('stream4chan-auto?');
    if(!autoplay){ debug('Autoplay checkbox not found!');}

    playWebms = document.getElementById('stream4chan-webms?');
    if(!playWebms){ debug('Player Webms input not found!');}

    playGifs = document.getElementById('stream4chan-gifs?');
    if(!playGifs){ debug('Player Gifs input not found!');}

    loop = document.getElementById('stream4chan-loopAll?');
    if(!loop){ debug('"loopAll" could not be found!'); }

    random = document.getElementById('stream4chan-random?');
    if(!random){ debug('"random" could not be found!'); }

    shuffle = document.getElementById('stream4chan-shuffle?');
    if(!shuffle){ debug('"shuffle" could not be found!'); }

    duration = document.getElementById('stream4chan-duration?');
    if(!duration){ debug('Gif duration input not found!');}

    exit = document.getElementById('SFC-exit');
    if(!exit){ debug('Exit not found!');}

    currentVideo = 'start';
    currentTime = 0;
    currentTimeout = setTimeout(0);
    modalOn = false;
    shuffled = false;

    //hrefs = document.getElementsByClassName('fileThumb');
    hrefs = [];
    backup = [];
    preload(hrefs);
}

function startEvents(){

    window.onresize = function(){ setDimensions(contentExists()); };
    window.onclick = function(event){if (event.target.id == 'stream4chan-content'){ stop(); }};
    window.onkeydown = function(event){
        event.target.blur();
        if(!toggleDebug(event)){
            //up arrow
            if(event.keyCode == 38 && modalOn){
                val = parseInt(duration.value, 10);
                max = parseInt(duration.max, 10);
                val += countStep;
                if(val > max){ val = max; }
                duration.value = val;
            }

            //Down arrow
            if(event.keyCode == 40 && modalOn){
                val = parseInt(duration.value, 10);
                min = parseInt(duration.min, 10);
                val -= countStep;
                if(val < min){ val = min; }
                duration.value = val;
            }
        }
    };
    window.onkeyup = function(event){
        event.target.blur();
        if(modalOn){
            //left arrow
            if(event.keyCode == 37){
                previousVideo();
            }

            //right arrow
            if(event.keyCode == 39){
                nextVideo();
            }

            //Escape key
            if(event.keyCode == 27){
                stop();
            }

            //W key
            if(event.keyCode == 87){
                playWebms.checked = !playWebms.checked;
            }

            //G key
            if(event.keyCode == 71){
                playGifs.checked = !playGifs.checked;
            }

            //A key
            if(event.keyCode == 65){
                autoplay.checked = !autoplay.checked;
                applyAutoplay();
            }

            //L key
            if(event.keyCode == 76){
                loopAll.checked = !loopAll.checked;
            }

            //R key
            if(event.keyCode == 82){
                random.checked = !random.checked;
                if(random.checked){
                    shuffleArr();
                }else{
                    unshuffleArr();
                }
            }

            //S key
            if(event.keyCode == 83){
                if(shuffle.value === ' shuffle '){
                    shuffleArr();
                }else{
                    unshuffleArr();
                }
            }

            //Space key
            if(event.keyCode == 32){
                if(contentExists('webm')){
                    if(hrefs[currentVideo].paused){
                        hrefs[currentVideo].play();
                    }else{
                        hrefs[currentVideo].pause();
                    }
                }
            }
        }
    };

    exit.onclick = function(){ stop(); };
    startButton.onclick = function(){ start(); };
    resumeButton.onclick = function(){ start(currentVideo, currentTime); };
    autoplay.onclick = function(){ applyAutoplay(); };
    random.onclick = function(){
        if(random.checked){
            shuffleArr();
        }else{
            unshuffleArr();
        }
    };
    prevButton.onclick = function(){ previousVideo(); };
    nextButton.onclick = function(){ nextVideo(); };
    shuffle.onclick = function(){
        if(shuffle.value === ' unshuffle '){
            unshuffleArr();
        }else{
            shuffleArr();
        }
    };

}

function displayModal(state){
    var body = document.getElementsByTagName('body');
    if(state === true){
        debug('Show Modal');
        modalOn = state;
        modal.style.display = 'block';

        //removes scoll bar
        for(i = 0; i < body.length; i++){
            if(body[i]){ body[i].style.overflow = "hidden"; }
        }
    }else if(state === false){
        debug('Hide Modal');
        modalOn = state;
        modal.style.display = 'none';

        //removes scoll bar
        for(i = 0; i < body.length; i++){
            if(body[i]){ body[i].style.overflow = "scroll"; }
        }
    }else{
        if(modalOn){
            debug('Hide Modal');
            modal.style.display = 'none';

            //removes scoll bar
            for(i = 0; i < body.length; i++){
                if(body[i]){ body[i].style.overflow = "scroll"; }
            }
        }else{
            debug('Show Modal');
            modal.style.display = 'block';

            //removes scoll bar
            for(i = 0; i < body.length; i++){
                if(body[i]){ body[i].style.overflow = "hidden"; }
            }
        }
        modalOn = !modalOn;
    }
}

function start(crntVid, crntTime){
    var newStart = (!crntVid && (crntVid !== 0));
    currentVideo = !newStart ? crntVid-1 : 'start';
    currentTime = crntTime ? crntTime : 0;

    //resume if starting from the beginning
    if(newStart){ unshuffleArr(); }

    displayModal(true);
    nextVideo();
}

function stop(){
    if(contentExists()){
        currentTime = contentExists('webm') ? contentExists('webm').currentTime : 0;
        pauseContent();
    }
    content.innerHTML = '';
    displayModal(false);
}

function nextVideo(){

    pauseContent();
    if(currentVideo === 'start'){ currentVideo = -1; }

    //While the href can't be played
    do{
        currentVideo++;
        if(loop.checked){
            currentVideo = currentVideo % hrefs.length;
        }

        var temp = noContentToDisplay();
        if(temp){
            stop();
            displayModal(true);
            content.innerHTML = temp;
            return;
        }
    }while(!canPlay(hrefs[currentVideo]));

    playContent(hrefs[currentVideo]);

    //add events for next video
    applyAutoplay();
}

function previousVideo(){
    debug('Function: previousVideo');

    pauseContent();
    if(currentVideo === 'start'){ currentVideo = 0; }

    //While the href can't be played
    do{
        currentVideo--;
        if(loop.checked){
            if(currentVideo === -1){ currentVideo = hrefs.length -1;}
        }

        var temp = noContentToDisplay();
        if(temp){
            stop();
            displayModal(true);
            content.innerHTML = temp;
            return;
        }
    }while(!canPlay(hrefs[currentVideo]));

    playContent(hrefs[currentVideo]);

    //add events for next video
    applyAutoplay();
}

function playContent(currentContent){
    debug('Function: playContent');
    content.innerHTML = '';
    if(random.checked){ shuffleArr(); }
    content.appendChild(currentContent);
    setDimensions(contentExists());
    if(contentExists('webm')){
        contentExists('webm').currentTime = currentTime;
        currentTime = 0;
        contentExists('webm').play();
    }
    //if(contentExists('gif')){ setTimeout(function(){}, duration.value); }
}

function pauseContent(){
    debug('Function: pauseContent');
    var x = contentExists('webm');
    if(x){
        x.removeEventListener('ended', nextVideo, false);
        x.loop = true;
        x.pause();
    }
    clearTimeout(currentTimeout);
    content.innerHTML = 'Paused';
}

function canPlay(currentContent){
    return ( (playGifs.checked && (getFileExt(currentContent.src) === 'gif')) || (playWebms.checked && (getFileExt(currentContent.src) === 'webm')) );
}

function getFileExt(input){
    temp = input.toString();
    return temp.substr(temp.lastIndexOf('.') + 1);
}

function preload(arr){
    debug('Function: preload');
    var temp = document.getElementsByClassName('fileThumb');
    var x = null;
    for (i = 0; i < temp.length; i++){
        debug('    intitializing element: ' + temp[i]);
        if(getFileExt(temp[i]) == 'gif'){
            x = document.createElement('img');
            x.setAttribute("id", "stream4chan-gif");
        }else if (getFileExt(temp[i]) == 'webm'){
            x = document.createElement('video');
            x.setAttribute("id", "stream4chan-webm");
            x.setAttribute("controls","");

            x.setAttribute("loop","");
            x.loop = true;

            x.setAttribute("autoplay","");
            x.autoplay = false;

            x.setAttribute("ended","");
            x.ended = false;
        }
        x.setAttribute("src",temp[i]);
        x.setAttribute("style", "height: 100%; width: auto;");
        arr.push(x);
        backup.push(x);
    }
}

function debug(text){
    if(debugOn){
        console.log(text);
    }else{
        hiddenPrints.push(text);
    }
}

function toggleDebug(e) {
    var evtobj = window.event? event : e;
    if (!e || evtobj.keyCode == 68 && evtobj.ctrlKey && evtobj.altKey && evtobj.shiftKey){
        debug('Function: toggleDebug');
        if(debugOn){
            console.log('##Debug Off##');
            debugOn = false;
        }else{
            console.log('##Debug On##');
            debugOn = true;
            for(var i = 0; i < hiddenPrints.length; i++){
                debug(hiddenPrints[i]);
            }
            hiddenPrints = [];
        }
        return true;
    }
    return false;
}

function setDimensions(e){
    debug('Function: setDimensions');
    content.style.height = window.innerHeight - (settings.offsetHeight*2) + 'px';
    if(e){
        if(e.offsetHeight > (window.innerHeight - settings.offsetHeight*2)){
            debug('    Content was taller');
            e.style.height = '100%';
            e.style.width =  'auto';
        }

        if(e.offsetWidth > (window.innerWidth - (prevButton.offsetWidth + nextButton.offsetWidth))){
            debug('    Content was wider');
            e.style.height = 'auto';
            e.style.width =  '100%';
        }

        if(content.offsetHeight > e.offsetHeight){
            e.style.marginTop = ((content.offsetHeight - e.offsetHeight)/2) + 'px';
            e.style.marginBottom = ((content.offsetHeight - e.offsetHeight)/2) + 'px';
        }else{
            e.style.marginTop = '0px';
            e.style.marginBottom = '0px';
        }
    }
}

function contentExists(type){
    debug('Function: contentExists');
    if(type){
        return document.getElementById('stream4chan-' + type);
    }else{
        var div = document.getElementById('stream4chan-webm');
        if(!div){ div = document.getElementById('stream4chan-gif'); }
        return div;
    }
}

function thereAre(type){
    debug('Function: thereAre');
    if(type){
        for(i = 0; i < hrefs.length; i++){
            if(getFileExt(hrefs[i].src) === type){
                return true;
            }
        }
    }
    debug('    Error: argument not passed to function');
    return false;
}

function noContentToDisplay(){
    debug('Function: noContentToDisplay');
    var text = false;

    //End and display modal if nothing can play
    if(!playGifs.checked && !playWebms.checked){
        text = 'Nothing selected to play';
    }

    //End and display modal if nothing can play
    if(!thereAre('gif') && (playGifs.checked && !playWebms.checked)){
        text = 'No gifs!';
    }

    //End and display modal if nothing can play
    if(!thereAre('webm') && (!playGifs.checked && playWebms.checked)){
        text = 'No Webms!';
    }

    //End and display modal if nothing can play
    if(!thereAre('gif') && !thereAre('webm')){
        text = 'No Gifs or Webs';
    }

    //End and display modal if out of range
    if( 0 > currentVideo || currentVideo > hrefs.length-1){
        text = 'End of Thread';
        if(currentVideo < 0){ text = 'Start of thread'; }
    }
    if(text){ debug('    Returning: '+ text); }
    return text;
}

function applyAutoplay(){
    debug('Function: applyAutoplay');

    var x = contentExists();
    debug('    ' + getFileExt(x.src) + ' event listener is ' + autoplay.checked);
    clearTimeout();

    if(getFileExt(x.src) === 'webm'){
        x.loop = !autoplay.checked;
        x.removeEventListener('ended', nextVideo, false);
        if(autoplay.checked){
            x.addEventListener('ended', nextVideo, false);
        }
    }

    if(getFileExt(x.src) === 'gif' && autoplay.checked){
        currentTimeout = setTimeout(nextVideo, duration.value*1000);
    }
}

function shuffleArr() {
    debug('Function: shuffleArr');
    var j, x, i;
    for (i = hrefs.length; i; i--) {
        j = Math.floor(Math.random() * i);
        x = hrefs[i - 1];
        hrefs[i - 1] = hrefs[j];
        hrefs[j] = x;
    }
    shuffled = true;
    shuffle.value = ' unshuffle ';
}

function unshuffleArr() {
    debug('Function: unshuffleArr');
    hrefs = backup.slice();
    if(contentExists()){
        for(var i = 0; i < hrefs.length; i++){
            if(hrefs[i].src === contentExists().src){
                currentVideo = i;
                break;
            }
        }
    }
    shuffled = false;
    shuffle.value = ' shuffle ';
}