// ==SiteScript==
// @siteName Freecaster.tv (extreme.com)
// @siteUrl http://freecaster.tv/
// @author mayan
// @authorUrl
// @scriptUrl
// @description
// @date 2016/06/17
// @version 0.2.1
// ==/SiteScript==
function CravingSiteScript() {
this._initialize();
}
CravingSiteScript.prototype = {
_xhr: null,
_initialize: function() {},
_getXmlHttpRequest: function() {
if ( this._xhr != null ) {
return this._xhr;
}
var xhr = null;
var these = [
function() { return new XMLHttpRequest(); }
, function() { return new ActiveXObject( "Msxml2.XMLHTTP" ); }
, function() { return new ActiveXObject( "Microsoft.XMLHTTP" ); }
, function() { return new ActiveXObject( "Msxml2.XMLHTTP.4.0" ); }
];
for ( var i = 0, length = these.length; i < length; i++ ) {
var func = these[ i ];
try {
xhr = func();
break;
}
catch( e ) {}
}
this._xhr = xhr;
return this._xhr;
},
_load: function( url, data, method ) {
var req = this._getXmlHttpRequest();
var mtd = ( method == null ) ? "GET" : "POST";
req.open( mtd, url, false );
if ( mtd == "POST" ) {
req.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" );
}
req.send( data );
return req.responseText;
},
getResponseText: function( url, data, method ) {
return this._load( url, data, method );
},
getResponseJSON: function( url, data, method ) {
var text = this._load( url, data, method );
return eval( "("+text+")" );
},
/// Math
random: function( limit ) {
return Math.floor( Math.random() * limit );
},
/// String
decodeHtml: function( str ) {
return str.replace( /&(quot|#0*34);/ig, "\"" )
.replace( /&(amp|#0*38);/ig, "&" )
.replace( /&(apos|#0*39);/ig, "'" )
.replace( /&(lt|#0*60);/ig, "<" )
.replace( /&(gt|#0*62);/ig, ">" )
.replace( /&(nbsp|#0*160);/ig, " " )
.replace( /&(frasl|#8260);/ig, "/" );
}
}
var _FrCas = {};
_FrCas.showMsg = true;
function isSiteUrl( url ) {
if ( url.match( /http:\/\/(www\.)?extreme\.com\/[^\/]+\/\d+/ ) ) return true;
if ( url.match( /http:\/\/(www\.)?freecaster\.(tv|com)\/[^\/]+\/\d+/ ) ) return true;
if ( url.match( /http:\/\/(www\.)?freecaster\.(tv|com)\/euforum\/video\/\d+/ ) ) return true;
//flash
if ( url.match( /http:\/\/player\.(?:extreme|freecaster)\.com\/FCPlayer\.swf(\?.+)/ )
&& RegExp.$1.match( /[?&]id=[^?]+/ ) ) return true;
return false;
}
function getVideoDetail( url ) {
if ( url.match( /http:\/\/(?:www\.)?extreme\.com\/[^\/]+\/(\d+)/ ) ||
url.match( /http:\/\/(?:www\.)?freecaster\.(?:tv|com)\/[^\/]+\/(\d+)/ ) ||
url.match( /http:\/\/(?:www\.)?freecaster\.(?:tv|com)\/euforum\/video\/(\d+)/ ) ) {
var vid = RegExp.$1;
var token = base64Encode( "v=" + vid );
} else if ( url.match( /http:\/\/player\.(?:extreme|freecaster)\.com\/FCPlayer\.swf(\?.+)/ )
&& RegExp.$1.match( /[?&]id=([^?]+)/ ) ) {
token = RegExp.$1;
} else {
//return null;
}
if ( !token ) return null;
var craving = new CravingSiteScript();
var infourl = "http://player.extreme.com/info/" + token;
try {
var text = craving.getResponseText( infourl );
} catch( e ) {
text = "";
}
if ( !text ) return null;
if ( text.match( /
]*)?>\s*(.*?)\s*<\/title>/ ) ) {
var title = craving.decodeHtml( RegExp.$1 );
}
if ( !title ) title = "extreme_" + ( vid || token );
title = title.replace(/[\\\/:*?"<>|]/g, "_");
var objReg = /]*)?>\s*(.*?)\s*<\/stream>/g;
//html_streams
var arrH = [];
var arrHLS = [];
if ( text.match( /]*)?>([\s\S]*?)<\/html_streams>/m ) ) {
var cntH = RegExp.$2;
while( objReg.test( cntH ) ) {
var attr = RegExp.$1;
var cnt = RegExp.$2;
if ( !cnt ) continue;
//if ( !cnt.match( /^http:\/\/.+/ ) ) continue;
var obj = {};
obj.url = craving.decodeHtml( cnt );
if ( attr.match( /\s+bitrate\s*=\s*("|')?(\d+)\1/ ) )
obj.bitrate = parseInt( RegExp.$2, 10 );
else obj.bitrate = 0;
obj.label = ( attr.match( /\s+label\s*=\s*("|')(.*?)\1/ ) )? RegExp.$2: "";
obj.ext = getExt( obj.url );
if ( obj.label == "iOS" || obj.ext == "m3u8" ) arrHLS.push( obj );
else arrH.push( obj );
}
}
if ( arrH.length > 0 ) {
arrH.reverse();
arrH.sort( function(a,b){ return b.bitrate-a.bitrate; } );
var realUrl = arrH[0].url;
if ( !chkUrl( realUrl, _FrCas.showMsg ) ) return null;
return { videoTitle0: title, videoUrl0: realUrl };
}
//streams
var arrS = [];
if ( text.match( /]*)?>([\s\S]*?)<\/streams>/m ) ) {
var attrS = RegExp.$1;
var cntS = RegExp.$2;
if ( attrS.match( /\s+server\s*=\s*("|')(.*?)\1/ ) ) var server = RegExp.$2;
if ( !server ) server = "";
if ( attrS.match( /\s+starttime\s*=\s*("|')(.*?)\1/ ) ) var starttime = RegExp.$2;
if ( !starttime ) starttime = "";
if ( attrS.match( /\s+endtime\s*=\s*("|')(.*?)\1/ ) ) var endtime = RegExp.$2;
if ( !endtime ) endtime = "";
while ( objReg.test( cntS ) ) {
attr = RegExp.$1;
cnt = RegExp.$2;
var obj = {};
obj.url = server + craving.decodeHtml( cnt );
if ( !obj.url ) continue;
//if ( !obj.url.match( /^https?:\/\/.+/ ) ) continue;
if ( attr.match( /\s+bitrate\s*=\s*("|')?(\d+)\1/ ) )
obj.bitrate = parseInt( RegExp.$2, 10 );
else obj.bitrate = 0;
if ( attr.match( /\s+type\s*=\s*("|')?(\d+)\1/ ) )
obj.type = RegExp.$2;
else obj.type = "";
arrS.push( obj );
}
}
if ( arrS.length <= 0 ) return null;
arrS.reverse();
arrS.sort( function(a,b){ return b.bitrate-a.bitrate; } );
var objS = arrS[0];
if ( !chkUrl( objS.url, _FrCas.showMsg ) ) return null;
if ( objS.type == "2" || objS.url.match( /\/smil\// ) ) {
var streamurl = getStreamUrl( objS.url, craving );
if ( !chkUrl( streamurl, _FrCas.showMsg ) ) return null;
if ( starttime ) {
streamurl = streamurl
+ ( ( streamurl.indexOf( "?" ) > -1 )? "&":"?" )
+ "seek=" + starttime;
}
if ( _FrCas.showMsg ) {
var objBx = new clsMsgBox();
if ( objBx.isOK ) {
objBx.MsgBox( "StreamUrl: " + streamurl
+ "\nStartTime: " + starttime + "\nEndTime: " + endtime,
"from Site-Script" );
}
}
return null;
}
realUrl = objS.url;
return { videoTitle0: title, videoUrl0: realUrl };
}
function chkUrl( strUrl, boolMsg ) {
if ( !strUrl || typeof( strUrl ) != "string" ) return false;
if ( boolMsg ) var objBx = new clsMsgBox();
if ( strUrl.match( /^rtmp[tse]*:\/\/.*/ ) ) {
if ( boolMsg && objBx.isOK ) {
objBx.MsgBox( "HTTPプロトコルではありません。\n" + strUrl, "from Site-Script" );
}
return false;
}
if ( strUrl.match( /^https?:\/\/([^\/]+\.)?(youtube\.com|youtu\.be)(:\d+)?\/.*/ ) ) {
if ( boolMsg && objBx.isOK ) {
objBx.MsgBox( "YouTubeの動画です。\n" + strUrl, "from Site-Script" );
}
return false;
}
if ( strUrl.match( /^https?:\/\/([^\/]+\.)?vimeo\.com(:\d+)?\/.*/ ) ) {
if ( boolMsg && objBx.isOK ) {
objBx.MsgBox( "Vimeoの動画です。\n" + strUrl, "from Site-Script" );
}
return false;
}
return true;
}
function getStreamUrl( strSmilUrl, craving ) {
try {
var text = craving.getResponseText( strSmilUrl );
} catch( e ) {
text = "";
}
if ( !text ) return "";
if ( text.match( /]*?name\s*=\s*("|')?httpBase\1[^>]*)>/ )
&& RegExp.$1.match( /\s+content\s*=\s*("|')(.*?)\1/ ) ) {
var base = RegExp.$2;
}
if ( !base ) base = "";
var objReg = /