Greasy Fork

stream4chan

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

目前为 2016-10-19 提交的版本。查看 最新版本

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


//Settings Header
countStep = 1;
modalSettings_auto = '<li class="SFC-li"><input id="stream4chan-auto?" class="SFC-input" type="checkbox" checked> Play Automatically</li>';
modalSettings_webms = '<li class="SFC-li"><input id="stream4chan-webms?" class="SFC-input" type="checkbox" checked> Play Webms</li>';
modalSettings_gifs = '<li class="SFC-li"><input id="stream4chan-gifs?" class="SFC-input" type="checkbox" checked> Play Gifs</li>';
modalSettings_loopAll = '<li class="SFC-li"><input id="stream4chan-loopAll?" class="SFC-input" type="checkbox" checked> Loop whole thread</li>';
modalSettings_shuffle = '<li class="SFC-li" style="display: none;"><input id="stream4chan-shuffle?" class="SFC-input" type="checkbox"> Randomize</li>';
modalSettings_duration = '<li class="SFC-li"><input id="stream4chan-duration?" class="SFC-input" type="number" min="' + countStep + '" max="60" value="3" step="' + countStep + '"> Gif Duration (Seconds)</li>';
    modalSettings = '<ul id="stream4chan-settings" class="SFC-settings">' + modalSettings_auto + modalSettings_webms + modalSettings_gifs + modalSettings_loopAll + modalSettings_shuffle + modalSettings_duration + '</ul>';

//Content Table
modalContent = '<div id="stream4chan-content" class="SFC-content"></div>';
modalContent_Left = '<th id="stream4chan-prev" class="SFC_th_left SFC_arrow"></th>';
modalContent_Right = '<th id="stream4chan-next" class="SFC_th_right SFC_arrow"></th>';
modalContent_Mid = '<th class="SFC_th_mid">' + modalSettings + modalContent + '</th>';
    modalTable = '<table id="stream4chan-table" class="SFC_table"><tr class="SFC_table_row">' + modalContent_Left + modalContent_Mid + modalContent_Right + '</tr></table>';

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

//CSS
settingsCSS = '.SFC-settings { opacity: 0.35; display: inline-block; list-style-type: none; width:100%; top: 0; height: 25px; margin: 0em; padding: 0em } .SFC-settings:hover { opacity: 1; }';
settingsLiCSS = '.SFC-li { display: inline-block; padding-left: 1em; color:#9d9393;}';
settingsInputCSS = '.SFC-input { margin: 0em; padding: 0em; padding-top: 0.3em; width: auto;  }';
AllSettingsCSS = settingsCSS + settingsLiCSS + settingsInputCSS;

//table
tableCSS = '.SFC_table { max-height: 100vh; min-height: 100vh; max-width: 100vw; min-width: 100vw; } ';
tableRowCSS = '.SFC_table_row { vertical-align: top; }';
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; }';
leftCSS = '.SFC_th_left { transform: rotate(180deg); }' + '.SFC_th_left:hover { background-color:rgba(255, 255, 255, 0.6); }';
rightCSS = '.SFC_th_right {  }' + '.SFC_th_right:hover { background-color:rgba(255, 255, 255, 0.6); }';
midCSS = '.SFC_th_mid { height: 100vh;  }';
allTableCSS = tableCSS + tableRowCSS + arrowCSS + leftCSS + rightCSS + midCSS;

mediaCSS = '.SFC-media { width: 100%; }';
contentCSS = '.SFC-content { display: block; color: white; }';
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);}';
allModalCSS = mediaCSS + contentCSS + modalCSS;

allCSS = '<style>' + allModalCSS + allTableCSS + AllSettingsCSS + '</style>';

//Media Elements
gifDiv = '<img id="stream4chan-gif" class="SFC-media" src="" alt="Stream4chan - Gif not loaded!">';
webmDiv = '<video id="stream4chan-webm" class="SFC-media" src="" controls autoplay></video>';



//Main
(function() {
    injectNewElements();
    initVars();

    currentVideo = 0;
    window.onclick = function(event){if (event.target.id == 'stream4chan-content') { end(); }};
    window.onresize = function(){  };

    //event for key strokes
    document.onkeyup = function(event){

        //left arrow
        if(event.keyCode == 37 && document.getElementById('stream4chan-modal').style.display == 'block'){
            console.log(document.getElementById('stream4chan-modal').style.display);
            previousVideo();

        //right arrow
        }else if(event.keyCode == 39 && document.getElementById('stream4chan-modal').style.display == 'block'){
            console.log(document.getElementById('stream4chan-modal').style.display);
            nextVideo();

        //Escape key
        }else if(event.keyCode == 27 && document.getElementById('stream4chan-modal').style.display == 'block'){
            end();

        //W key
        }else if(event.keyCode == 87 && document.getElementById('stream4chan-modal').style.display == 'block'){
            playWebms.checked = !playWebms.checked;

        //G key
        }else if(event.keyCode == 71 && document.getElementById('stream4chan-modal').style.display == 'block'){
            playGifs.checked = !playGifs.checked;

        //A key
        }else if(event.keyCode == 65 && document.getElementById('stream4chan-modal').style.display == 'block'){
            autoplay.checked = !autoplay.checked;

        //L key
        }else if(event.keyCode == 76 && document.getElementById('stream4chan-modal').style.display == 'block'){
            loopAll.checked = !loopAll.checked;

        //R key
        }else if(event.keyCode == 82 && document.getElementById('stream4chan-modal').style.display == 'block'){
            random.checked = !random.checked;
        }else{
            //console.log(event.keyCode);
        }
    };
    document.onkeydown = function(event){
        //up arrow
        if(event.keyCode == 38 && document.getElementById('stream4chan-modal').style.display == 'block'){
            val = parseInt(duration.value, 10);
            max = parseInt(duration.max, 10);
            val += countStep;
            if(val > max){ val = max; }
            duration.value = val;

        //Down arrow
        }else if(event.keyCode == 40 && document.getElementById('stream4chan-modal').style.display == 'block'){
            val = parseInt(duration.value, 10);
            min = parseInt(duration.min, 10);
            val -= countStep;
            if(val < min){ val = min; }
            duration.value = val;
        }
    };
    
    startButton.onclick = function(){ start(); };
    resumeButton.onclick = function(){ initVars(); start(currentVideo, media.time); };
    autoplay.onclick = function(){ updateAutoplay(); };
    shuffle.onclick = function(){ initVars(); };
    prevBtn.onclick = function(){ previousVideo(); };
    nextBtn.onclick = function(){ nextVideo(); };
})();

//insert elements to html doc
function injectNewElements(){
    //add start slideshow button to navs
    var nav = document.getElementsByClassName("navLinks desktop");
    var i;
    if(nav){
        for(i = 0; i < nav.length; i++){
            nav[i].innerHTML += startBtn + resumeBtn;
        }
    }

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

//Assign the elemens that don't change to vars
function initVars(){
    modal = document.getElementById('stream4chan-modal');
    //if(!modal){ console.log('modal not found!');}

    startButton = document.getElementById('stream4chan-start');
    //if(!startButton){ console.log('Start button not found!');}

    resumeButton = document.getElementById('stream4chan-continue');
    //if(!resumeButton){ console.log('Resume button not found!');}

    table = document.getElementById('stream4chan-table');
    //if(!table){ console.log('table not found!');}

    prevBtn = document.getElementById('stream4chan-prev');
    //if(!prevBtn){ console.log('"Previous" button not found!');}

    content = document.getElementById('stream4chan-content');
    //if(!content){ console.log('content not found!');}

    nextBtn = document.getElementById('stream4chan-next');
    //if(!nextBtn){ console.log('"Next" button not found!');}

    media = document.getElementById('stream4chan-webm');
    if(!media){ media = document.getElementById('stream4chan-gif'); }
    //if(!media){ console.log('"Media" could not be found!'); }

    //Settings
    settings = document.getElementById('stream4chan-settings');
    //if(!settings){ console.log('"Settings" could not be found!'); }

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

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

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

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

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

    playSelected = document.getElementById('stream4chan-playSelected?');
    //if(!playSelected){ console.log('"play selected" could not be found!'); }

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

    //Misc
    currentTimeout = setTimeout(function(){}, (0));
    contentHrefs = document.getElementsByClassName("fileThumb");
    if(random.selected){ shuffle(contentHrefs); }
}

//start show
function start(position, time) {
    initVars();
    displayModal();

    currentTime = 0;
    currentVideo = 0;
    if(position){ currentVideo = position - 1; }
    if(time){ currentTime = time; }

    nextVideo();
}

//end show
function end() {
    initVars();
    modal.style.display = "none";

    var videoToPause = document.getElementById("stream4chan-webm");

    if(media){ currentTime = media.currentTime; }
    if(videoToPause){ videoToPause.pause(); }
    clearTimeout();

    var body = document.getElementsByTagName('body');
    for(i = 0; i < body.length; i++){
        if(body[i]){ body[i].style.overflow = "scroll"; }
    }
}

//Display the contents
function displayModal(){
    content.innerHTML = '';
    modal.style.display = "block";

    calcHeight();

    content.innerHTML = '<h1>No Video is Playing</h1>';

    var body = document.getElementsByTagName('body');
    for(i = 0; i < body.length; i++){
        if(body[i]){ body[i].style.overflow = "hidden"; }
    }
}

//Loads element based on URL
function displayVideo(href){
    filetype = getFiletype(href);
    media = document.getElementById("stream4chan-" + filetype);
    //create media if it's not there
    if(!media){
        if(filetype == 'gif'){
            content.innerHTML = gifDiv;
        }else if(filetype == 'webm'){
            content.innerHTML = webmDiv;
        }
        media = document.getElementById("stream4chan-" + filetype);
    }

    //change to new source, readjust the heigh, resume from last place
    media.src = href;
    initVars();
    calcHeight();
    if(filetype == 'webm'){
        media.onplay = function(){ calcHeight(); };
        media.currentTime = currentTime;
    }
}

//play next video
function nextVideo(){
    initVars();

    //If out of range
    if(0 > currentVideo || currentVideo > contentHrefs.length - 1){
        if(loopAll.checked){
            if(currentVideo < 0){
                currentVideo = contentHrefs.length - 1;
            }else{
                currentVideo = 0;
            }
        }else{
            console.log('out of range');
            end();
            displayModal();
            return;
        }
    }

    //Get filetype -> If its a gif and gifs are asked not to play -> return
    filetype = getFiletype(contentHrefs[currentVideo]);

    //skip if it can't play the current file
    if(!canPlay(currentVideo)){
       currentVideo++;
       nextVideo();
       return;
    }

    displayVideo(contentHrefs[currentVideo]);
    updateAutoplay();

    // increment the currentVideo
    currentVideo++;
}

//call next video when valid previous video is found
function previousVideo(){
    initVars();

    currentVideo--;
    while(currentVideo > -1){
        if(canPlay(currentVideo--)){ break; }
    }
    nextVideo();
}

//Returns true if current video is gif and gifs are selected etc
function canPlay(arrPosition){
    var currType = getFiletype(contentHrefs[arrPosition]);
    return !((currType == "gif" && !playGifs.checked) || (currType == "webm" && !playWebms.checked));
}

//Update timeouts and listeners to loop media
function updateAutoplay(){
    initVars();
    if(media){
        filename = getFiletype(media.src);

        if(filename == 'gif'){
            if(autoplay.checked){
                clearTimeout();
                currentTimeout = setTimeout(function(){
                    nextVideo();
                }, (duration.value*1000));
            }else{
                clearTimeout();
            }
        }else if(filename == 'webm'){
            media.loop = !autoplay.checked;
            clearTimeout();
            media.removeEventListener('ended', function(){ currentTime = 0; nextVideo();}, false);
            if(autoplay.checked){
                media.addEventListener('ended', function(){ currentTime = 0; nextVideo();}, false);
            }
        }else{
            console.log("Not a valid type! call to update autoplay");
        }
    }
    calcHeight();
}

//Clear Timeout functions to avoid related function calls
function clearTimeout(){
    if(currentTimeout){
        while(currentTimeout > 0){
            currentTimeout--;
            window.clearTimeout(currentTimeout);
        }
    }
}

//Return file extension type
function getFiletype(input){
    href = input.toString();
    return href.substr(href.lastIndexOf('.') + 1);
}

//Recalc height of content div to fit properly
function calcHeight(){
    initVars();
    content.style.height = window.innerHeight - settings.offsetHeight + "px";

    if(media){
        if(media.offsetHeight > (window.innerHeight - settings.offsetHeight)){
            media.style.height = '100%';
            media.style.width = 'auto';
        }

        if(media.offsetWidth > (window.innerWidth - (prevBtn.offsetWidth + nextBtn.offsetWidth))){
            media.style.width = '100%';
            media.style.height = 'auto';
        }
    }
}

//Shuffles the array of hrefs
function shuffle(input) {
    for (var i = input.length-1; i >=0; i--) {
        var randomIndex = Math.floor(Math.random()*(i+1));
        var itemAtIndex = input[randomIndex];

        input[randomIndex] = input[i];
        input[i] = itemAtIndex;
    }
}