// ==UserScript==
// @name ZXDL
// @namespace http://zoox18.com/
// @version 1.4.1
// @description View and download private videos from ZX18.
// @author Low
// @match http*://*.zoox18.com/*
// @grant GM_download
// @require http://code.jquery.com/jquery-3.4.1.min.js
// @require https://cdn.plyr.io/3.5.6/plyr.js
// @license MIT
// ==/UserScript==
// This code is open source and can be modified as such to meet working standards of "the site" this script is being used on.
// You may release your own fixes as such
// Inject
var downloading = false;
var found = false;
var isPrivateWindow = false;
var id = window.location.pathname.split("/")[2];
var vidUrl = '';
var uploader = 'Unknown';
var title = 'Unknown';
$('.navbar').after('<div class="container" id="rip-div" style="width: 560px;"></div>')
$('.top-menu > .pull-left').append('<li>ZXDL 1.4.1</li>');
// Remove annoyances
document.querySelectorAll('.img-private').forEach(elm => elm.style.filter = 'brightness(1)');
document.querySelectorAll('.label-private').forEach(elm => elm.style.filter = 'opacity(0.5)');
// Functions
function formatBytes(a,b=2) {
if (0===a) return "0 bytes";
const c=0>b?0:b,d = Math.floor(Math.log(a) / Math.log(1024));
return parseFloat((a / Math.pow(1024, d)).toFixed(c)) + " " +["bytes","KB","MB","GB"][d];
}
function dl_progress(res) {
if (res.lengthComputable === false) return;
$('#dl-data').html(formatBytes(res.done) +' / '+ formatBytes(res.total));
$('#dl-bar').attr("aria-valuenow", Math.floor(res.done / res.total * 100));
$('#dl-bar').css("width", Math.floor(res.done / res.total * 100) + "%");
$('#dl-bar').html(Math.floor(res.done / res.total * 100) + "%");
}
function dl_load(res) {
if (res.lengthComputable === false) return;
$('#dl-data').html("Complete!");
$('#dl-bar').addClass("progress-bar-success");
}
function dl_error(res) {
if (res.lengthComputable === false) return;
$('#dl-data').html("Oops, there was an error. Refresh page to try again");
$('#dl-bar').addClass("progress-bar-danger");
}
// Path list
var key0 = "hB6avf7v"; //media
var key1 = "Xy7asa5q"; //media1
var key2 = "80vNaj"; //media2
var paths = ['https://media.zoox18.com/'+key0+'/media/videos/h264/'+id+'_SD.mp4', 'https://media1.zoox18.com/'+key1+'/media/videos/h264/'+id+'_SD.mp4', 'https://media2.zoox18.com/'+key2+'/media/videos/iphone/'+id+'.mp4', 'https://media2.zoox18.com/'+key2+'/media/videos/h264/'+id+'_SD.mp4'];
function scan(url) {
if (found == false){
var v = document.createElement('VIDEO');
v.addEventListener('loadeddata', function () { // If video found
console.log('ZXDL: Video found! ' + url);
found = true;
vidUrl = url;
if (isPrivateWindow){
$('#rip-div').html('<h1>'+title+'</h1><p>Uploaded by <a href="https://zoox18.com/user/'+uploader+'">'+uploader+'</a></p><link rel="stylesheet" href="https://cdn.plyr.io/3.5.6/plyr.css" /><video style="width: 100%; height: 100%;" poster="https://www.zoox18.com/media/videos/tmb1/'+id+'/default.jpg" id="rippedvid" playsinline controls><source src="'+vidUrl+'" type="video/mp4" /></video><div><hr><button id="zxdl_favorite" class="btn btn-primary"><i class="glyphicon glyphicon-heart"></i> Favorite</button> <button id="zxdl_download" class="btn btn-primary"><i class="glyphicon glyphicon-download"></i> Download (beta)</button><p id="status"></p><div id="dl-progress" class="well" style="display: none"></div></div>');
var controls = ['play-large', 'play', 'progress', 'current-time', 'mute', 'volume', 'settings', 'fullscreen'];
var player = new Plyr('#rippedvid', { controls });
$('#zxdl_favorite').click(function() { // Favorite button for private videos
$('#status').html('Please wait...');
var http = new XMLHttpRequest();
var url = 'https://www.zoox18.com/ajax/favorite_video';
var form = 'video_id='+ id;
http.open('POST', url, true);
http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
const response = http.responseText
if (response.includes('alert-danger')) {
$('#status').html('Couldn\'t favorite video. Are you logged in? Is this video already in your favorites?');
} else if (response.includes('alert-success')) {
$('#status').html('<span style="color:#77b300">Added to favorites!</span>');
} else {
$('#status').html('The site returned unknown data.');
}
}
}
http.send(form);
});
} else {
// Replace download button on public videos
$('div#share_video').append('<button id="zxdl_download" class="btn btn-primary m-l-5"><i class="glyphicon glyphicon-download"></i></button><p id="status"></p>');
$('#response_message').after('<div id="dl-progress" class="well" style="display: none"></div>');
$('button.btn.btn-default.dropdown-toggle').remove();
}
$('#zxdl_download').click(function() {
if (downloading === false){
downloading = true;
$('#dl-progress').css('display','block');
$('#dl-progress').html('This feature is still being worked on! Not all videos or browsers may support this method.<hr><h4>Progress</h4><span id="dl-data">Loading...</span> <div class="progress"><div id="dl-bar" class="progress-bar progress-bar-striped" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%"></div></div>');
GM_download({
url: url,
name: id + ".mp4",
onprogress: dl_progress,
onload: dl_load,
onerror: dl_error
});
} else {
alert('You\'ve already initiated a download. Refresh the page to try again.');
}
});
});
v.src = url;
}
}
// On load
function init() {
if ($('#wrapper .container .row .col-xs-12').length > 0) { // If private video page active
isPrivateWindow = true;
uploader = $('.text-danger a').text();
title = $("meta[property='og:title']").attr("content");
if (window.location.pathname.split("/")[1] == "video") {
$('.well.well-sm').remove(); // Remove notice
$('.well.ad-body').remove(); // Remove sponsor block for non-ad-blockers
$('#rip-div').html('<h1>Scanning for video '+id+'...</h1><p>This can take up to a minute. If it takes longer, please check your browser\'s console for errors.</p>');
paths.forEach(scan);
}
}
else if($('#wrapper .container .row .col-md-8 .vcontainer ').length > 0) { // If public video page active
paths.forEach(scan);
}
};
window.addEventListener('load', init, false);
Donate for the site OpenUserJS
Are you sure you want to go to an external site to donate a monetary value?
WARNING: Some countries laws may supersede the payment processors policy such as the GDPR and PayPal. While it is highly appreciated to donate, please check with your countries privacy and identity laws regarding privacy of information first. Use at your utmost discretion.