// ==UserScript==
// @name Flash2MPlayer
// @namespace youku.todou.vlc.player
// @description Flash.2.MPlayer
// @version 1
// @match http://*/*
// @match http://www.tudou.com/*
// @match http://douban.fm/
// @match http://pan.baidu.com/*
// @match http:/tv.sohu.com/*
// @grant GM_xmlhttpRequest
// ==/UserScript==
(function() {
function Flash2Mplayer(global) {
global.playIndex = 0;
global.playlist = [];
global.videoSeconds = 0;
global.seqsPlayTime = 0;
global.mpalyer_videoId = null;
global.DBR = null;
//global.playerBox = null;
global.cookieExpire = 60 * 24 * 3600;
global.replace = false;
document.body.onload = function() {
if (document.getElementsByTagName('video').length == 0)
return;
var html5video = document.getElementsByTagName('video')[0];
var htmlUrl = html5video.getAttribute('type', 'video/mp4');
replacePlayer();
};
function randomString(len) {
len = len || 32;
var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
var maxPos = $chars.length;
var pwd = '';
for (i = 0; i < len; i++) {
pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
}
return pwd;
}
;
global.getNode = function getNode(id) {
return document.getElementById(id);
};
global.getDoubanPlayList = function getDoubanPlayList() {
var r = randomString(10);
var url = 'http://douban.fm/j/mine/playlist?type=n&sid=&pt=0.0'
+ '&channel=' + global.channel + '&from=mainsite&r=' + r;
var XMLHttp = new XMLHttpRequest();
XMLHttp.open('GET', url, 10);
XMLHttp.send();
XMLHttp.onreadystatechange = function() {
if (XMLHttp.readyState == 4 && XMLHttp.status == 200) {
global.playlist = JSON.parse(XMLHttp.responseText)['song'];
global.playIndex = 0;
nextAudio();
}
};
};
global.bdloadCnt = 0;
global.bdPanVideo = function dbPanVideo() {
var token = window.self.FileUtils.bdstoken;
global.bdloadCnt++;
if (typeof token == 'undefined') {
if (global.bdloadCnt > 5) {
return;
}
setTimeout(dbPanVideo, 1000);
return;
}
console.log(token);
var path = window.location.hash.split('=')[1].split('&')[0].split('/')[2];
var url = 'http://pan.baidu.com/api/list?channel=chunlei&clienttype=0'
+ '&web=1&dir=' + path + '&bdstoken=' + token + '&channel=chunlei&clienttype=0&web=1';
var XMLHttp = new XMLHttpRequest();
XMLHttp.open('GET', url, 10);
XMLHttp.send();
XMLHttp.onreadystatechange = function() {
if (XMLHttp.readyState == 4 && XMLHttp.status == 200) {
var videourl = JSON.parse(XMLHttp.responseText);
console.log(videourl);
embed = +'';
getNode('video-wrap').innerHTML = embed;
}
};
};
global.nextAudio = function nextAudio() {
var nextIndex = global.playIndex + 1;
if (nextIndex < global.playlist.length) {
global.playIndex = nextIndex;
var audioInfo = ''
+ '
'
+ ''
+ '歌者:' + global.playlist[nextIndex]['artist']
+ '
公司:' + global.playlist[nextIndex]['company']
+ '
歌名:' + global.playlist[nextIndex]['title']
+ '
专辑:' + global.playlist[nextIndex]['albumtitle']
+ '
下一首'
+ '
';
getNode("audioInfo").innerHTML = audioInfo;
getNode('mplayer').setAttribute('src', global.playlist[nextIndex]['url']);
//getNode('mplayer').innerHTML = s;
//getNode('mplayer').Play();
//nextIndex++;
return;
} else {
getDoubanPlayList();
}
};
global.cleanDoubanFMEvent = function cleanDoubanFMEvent() {
// global.initBannerAd = function() {
// };
// global.bgad = {has_channel_ad: function() {
// }};
global.DBR = {swf: function() {
}, act: function(s, q) {
},
radio_getlist: function(q) {
},
close_video: function() {
},
play_video: function() {
},
is_paused: function() {
},
logout: function() {
window.is_user_login = false;
delete globalConfig.uid;
$("#fm-header").find("#anony_nav").remove().end().find("#user_info").remove().end().prepend($.tmpl($("#tmpl_user_info").html(), {}))
},
show_login: function() {
var q = globalConfig.doubanHost + "/service/account/check_with_js?" + $.param({return_to: globalConfig.login_check_url, sig: globalConfig.ajax_sig, r: Math.random()}) + "&callback=?";
$.getJSON(q, function(r) {
$.getJSON(r.url, function(s) {
if (s.r == 0) {
$(window).trigger(window.consts.LOGIN_EVENT, s.user_info)
} else {
show_login()
}
})
})
}};
$(".channel_list").undelegate();
$(".channel_list").delegate(".channel:not(.selected)", "click", function(V) {
var T = $(this), R = $(".channel"), X = T.data("cid"),
U = T.closest(".channel_list").attr("id");
global.channel = T.attr("cid");
setCookie('mplayer_doubanChannel', global.channel, global.cookieExpire);
getDoubanPlayList();
$.getJSON("/j/change_channel?fcid=" + T.attr("data-cid") + "&tcid=" + X + "&area=" + U);
});
};
global.mplayerError = function mplayerError(error) {
var msg = '';
switch (error) {
case 1:
msg = 'ERROR_NO_STREAM';
break;
case 1 << 1:
msg = 'ERROR_CODEC_FAILURE';
break;
case 1 << 2:
msg = 'ERROR_EXPLICIT_KILL';
break;
case 1 << 3:
msg = 'ERROR_PLAYER_INTERRUPTED';
break;
case 1 << 4:
msg = 'ERROR_EXECV';
break;
case 1 << 5:
msg = 'ERROR_NOT_PLAYLIST';
break;
case 1 << 6:
msg = 'ERROR_FILE_NOT_FOUND';
break;
default:
return;
}
console.log(msg);
};
global.createDoubanFmAudo = function createDoubanFmAudo() {
cleanDoubanFMEvent();
global.channel = getCookie('mplayer_doubanChannel') || 1;
var htmlRadio = ''
+ '
'
+ '';
global.player = getNode('mplayer');
getNode('fm-player').firstElementChild.innerHTML = htmlRadio;
getDoubanPlayList();
};
function replacePlayer() {
if (global.replace) {
return;
}
console.log('replace');
global.replace = true;
if (document.domain == 'douban.fm') {
function check() {
getNode('fm-player').firstElementChild.innerHTML = '';
if (typeof getNode('radioplayer') != 'undefined') {
createDoubanFmAudo();
} else {
setTimeout(check, 1000);
}
}
check();
}
if (document.domain == 'tv.sohu.com') {
return sohuVideo();
}
if (document.domain == 'pan.baidu.com') {
return bdPanVideo();
}
if (typeof videoId2 !== 'undefined' && videoId2 != '') {
var videoId = videoId2;
} else if (typeof vcode !== 'undefined' && vcode != '') {
var videoId = window.vcode;
} else if (typeof iid !== 'undefined') {
var videoId = window.iid;
document.getElementById('__flash2mplayer').setAttribute('tudouiid', 1);
document.getElementById('__flash2mplayer').setAttribute('segs', itemData.segs.toString());
} else if (typeof itemData != 'undefined' && typeof itemData.iid != 'undefined') {
var videoId = itemData.iid;
document.getElementById('__flash2mplayer').setAttribute('segs', itemData.segs.toString());
} else if (typeof pageConfig != 'undefined' && typeof pageConfig.iid != 'undefined') {
var videoId = pageConfig.iid;
document.getElementById('__flash2mplayer').setAttribute('tudouiid', 1);
document.getElementById('__flash2mplayer').setAttribute('segs', pageConfig.segs);
} else {
console.log('No Video Id');
var embedList = document.getElementsByTagName('embed');
for (var i = 0; i < embedList.length; i++) {
var embedNode = embedList[i];
if (embedNode.getAttribute('type') == 'application/x-shockwave-flash') {
var uriInfo = embedNode.getAttribute('src').split('/');
if (uriInfo.indexOf('player.youku.com') >= 0) {
var i = uriInfo.indexOf('sid') + 1;
videoId = uriInfo[i];
embedNode.parentNode.setAttribute('id', 'player');
document.getElementById('__flash2mplayer').setAttribute('site', 'youku');
document.getElementById('__flash2mplayer').setAttribute('embed', 1);
}
}
}
if (typeof videoId == 'undefined') {
return;
}
}
global.mpalyer_videoId = 'youkutudou' + videoId;
document.getElementById('__flash2mplayer').setAttribute('vcode', videoId);
//getNode('player').innerHTML = 'Loading Mplayer...';
}
;
global.farmatTime = function farmatTime(sec) {
var s = sec % 60;
s = s > 9 ? s : '0' + s;
var m = Math.round(sec / 60);
m = m > 9 ? m : '0' + m;
return m + ':' + s;
};
global.F2McallbackGetData = function F2McallbackGetData(re, seconds) {
if ((typeof vcode !== 'undefined' && vcode != '') || document.domain == 'youku.com') {
return F2MgetYoukuURL(re);
}
if (getNode('__flash2mplayer').getAttribute('site') == 'youku') {
return F2MgetYoukuURL(re);
}
global.playlist = re;
global.videoSeconds = seconds;
if (document.domain == 'tv.sohu.com') {
videoWarperId = 'sohuplayer';
} else {
videoWarperId = 'player';
if (!getNode('player')) {
videoWarperId = 'playerPlaceholder';
}
}
var vid = getCookie('mplayer_videoId');
var history = parseInt(getCookie('mplayer_seqs'));
if (history && vid && vid == global.mpalyer_videoId) {
global.playIndex = history;
createPlayer(re[history]['url'], videoWarperId);
} else {
setCookie('mplayer_seqs', 0, global.cookieExpire);
global.playIndex = 0;
createPlayer(re[0]['url'], videoWarperId);
}
};
global.sohuVideo = function sohuVideo() {
var fuid = getCookie('fuid');
if (!fuid) {
setTimeout(sohuVideo, 1000);
return;
}
global.mpalyer_videoId = 'sohu' + vid;
document.getElementById('__flash2mplayer').setAttribute('sohufuid', fuid);
document.getElementById('__flash2mplayer').setAttribute('sohuplaylistId', playlistId);
document.getElementById('__flash2mplayer').setAttribute('vid', vid);
//createPlayer('sohuplayer');
};
global.getCookie = function getCookie(cn) {
var i, x, y, a = document.cookie.split(";");
for (i = 0; i < a.length; i++) {
x = a[i].substr(0, a[i].indexOf("="));
y = a[i].substr(a[i].indexOf("=") + 1);
x = x.replace(/^\s+|\s+$/g, "");
if (x == cn)
return unescape(y);
}
return null;
};
global.setCookie = function setCookie(cn, v, ex) {
var e = new Date(), n = e.getTime();
ex = n + ex * 1000;
e.setTime(ex);
var cv = escape(v) + "; exs=" + e.toUTCString();
document.cookie = cn + "=" + cv;
};
global.createPlayer = function createPlayer(url, playerId) {
playerId = playerId || 'player';
if (!getNode(playerId)) {
var objectList = document.getElementsByTagName('object');
for (var i = 0; i < objectList.length; i++) {
var embedNode = objectList[i];
if (/youku\.com|tudou\.com|sohu\.com/.test(embedNode.getAttribute('src'))) {
embedNode.parentNode.id = 'playerWarper';
playerId = 'playerWarper';
}
}
}
var w = getNode(playerId).offsetWidth;
var t = farmatTime(global.videoSeconds);
var ih = ''
+ '1/' + global.playlist.length + ''
+ '00:00/' + t + ''
+ '下一节'
+ '上一节'
+ ''
+ '
';
global.useMplayer = function useMplayer() {
//html = '' + ih;
getNode(playerId).innerHTML = html;
global.player = getNode('mplayer');
};
getNode(playerId).setAttribute('style', 'background-color:#EEE;margin:0;padding:0;text-indent: 0;');
getNode(playerId).innerHTML = '' + ih;
//global.playIndex = 0;
getNode('curIdx').innerHTML = (global.playIndex + 1) + '/' + global.playlist.length;
global.player = getNode('mplayer');
setCookie('mplayer_videoId', global.mpalyer_videoId, global.cookieExpire);
global.timeUpdate = function timeUpdate() {
if(typeof global.player.currentTime == 'undefined') {
var cpt = global.player.getTime();
} else {
var cpt = global.player.currentTime;
}
var nt = Math.round(global.seqsPlayTime + (cpt || 0));
getNode('videoTime').innerHTML = farmatTime(nt) + '/' + t;
setTimeout(timeUpdate, 1000);
};
timeUpdate();
return global.player;
};
global.videoNextSeqs = function videoNextSeqs(clk) {
playComplete(clk);
};
global.videoPreviousSeqs = function videoPreviousSeqs() {
var preIndex = global.playIndex - 1;
if (preIndex >= 0) {
global.playIndex = preIndex;
setCookie('mplayer_seqs', preIndex, global.cookieExpire);
global.seqsPlayTime -= global.playlist[preIndex]['seconds'];
getNode('curIdx').innerHTML = (preIndex + 1) + '/' + global.playlist.length;
player.setAttribute('src', global.playlist[preIndex]['url']);
videoPlay();
return;
}
};
global.sleep = function sleep(sec) {
d = sec * 1000;
for (var t = Date.now(); Date.now() - t <= d; )
;
};
global.videoPlay = function videoPlay() {
try {
return player.Play();
} catch(e) {
return player.play();
}
};
global.setVideoTime = function setVideoTime(v) {
try {
return player.PlayAt(curTime);
} catch(e) {
player.currentTime = curTime;
}
};
global.getVideoTime = function getVideoTime() {
try{
return player.getTime();
} catch(e) {
return player.currentTime;
}
};
global.videoFullScreenState = function videoFullScreenState() {
if(typeof player.fullscreen != 'undefined') {
return player.fullscreen;
}
return document.mozFullScreenElement != null;
};
global.setFullScreen = function setFullScrenn() {
if(typeof player.fullscreen != 'undefined') {
return player.fullscreen = true;
}
return player.mozRequestFullScreen()
};
global.getVideoPercent = function getVideoPercent() {
try {
return player.getPercent();
} catch(e) {
return player.currentTime/player.duration;
}
}
global.playComplete = function playComplete(e) {
var fullscreen = videoFullScreenState;
if (e != 'click') {
var curTime = getVideoTime();
function continuePlay() {
videoPlay();
getNode('videoState').innerHTML = 'playing..';
setTimeout(function() {
setVideoTime(curTime);
setTimeout(function() {
setVideoTime(curTime);
if (fullscreen) {
setFullScreen();
}
}, 1000);
}, 1000);
}
;
if (getVideoPercent() < 0.95) {
setTimeout(continuePlay, 50000);
getNode('videoState').innerHTML = 'waiting..';
return;
}
}
var nextIndex = global.playIndex + 1;
if (nextIndex <= global.playlist.length) {
global.playIndex = nextIndex;
setCookie('mplayer_seqs', nextIndex, global.cookieExpire);
global.seqsPlayTime += global.playlist[nextIndex]['seconds'];
getNode('curIdx').innerHTML = (global.playIndex + 1) + '/' + global.playlist.length;
player.setAttribute('src', global.playlist[nextIndex]['url']);
videoPlay();
if (fullscreen) {
function fs() {
if(typeof player.playState == 'undefined') {
setFullScreen();
return;
}
if (player.playState == 8 || player.playState == 1) {
return;
}
if (player.playState == 6) {
setTimeout(fs, 2000);
return;
}
if (player.playState != 3) {
setTimeout(fs, 1000);
return;
}
setFullScreen();
player.setAttribute("fullscreen", fullscreen);
}
fs();
}
return;
}
};
global.F2MgetYoukuURL = function F2MgetYoukuURL(spec) {
var data = spec.data[0], d = new Date(), fileType = getFileType(data['streamfileids']);
var fileid = getFileID(data['streamfileids'][fileType], data['seed']);
var rand1 = 1000 + parseInt(Math.random() * 999);
var rand2 = 1000 + parseInt(Math.random() * 9000);
var sid = d.getTime() + '' + rand1 + '' + rand2;
var first = '';
var pathType = fileType == 'mp4' ? 'mp4' : 'flv';
for (var i = 0, len = (data['segs'][fileType]).length; i < len; i++) {
var k = data['segs'][fileType][i]['k'],
url = 'http://f.youku.com/player/getFlvPath/sid/' +
sid + '_' + toHex(i) + '/st/' + pathType + '/fileid/' +
fileid.substr(0, 8) + toHex(i) + fileid.substr(10, fileid.length - 2) + '?start=0&K=' + k + '&hd=2&myp=0&ts=185&ypp=0';
global.videoSeconds += parseInt(data['segs'][fileType][i]['seconds']);
var seq = {};
seq['seconds'] = parseInt(data['segs'][fileType][i]['seconds']);
seq['url'] = url;
global.playlist.push(seq);
if (i == 0) {
first = url;
}
}
var vid = getCookie('mplayer_videoId');
var history = parseInt(getCookie('mplayer_seqs'));
if (history && vid && vid == global.mpalyer_videoId) {
global.playIndex = history;
createPlayer(global.playlist[history]['url']);
} else {
setCookie('mplayer_seqs', 0, global.cookieExpire);
global.playIndex = 0;
createPlayer(first);
}
};
function getFileIDMixString(seed) {
var mixed = [
];
var source = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/\\:._-1234567890'.split('');
var index,
len = source.length;
for (var i = 0; i < len; i++) {
seed = (seed * 211 + 30031) % 65536;
index = Math.floor(seed / 65536 * source.length);
mixed.push(source[index]);
source.splice(index, 1);
}
return mixed;
}
;
function getFileID(fileid, seed) {
var mixed = getFileIDMixString(seed);
var ids = fileid.split('*');
var realId = [
];
var idx;
for (var i = 0; i < ids.length; i++) {
idx = parseInt(ids[i], 10);
realId.push(mixed[idx]);
}
return realId.join('');
}
;
function getFileType(obj) {
var keys = Object.keys(obj);
console.log(keys);
if (keys.indexOf('hd2') >= 0) {
return 'hd2';
} else if (keys.indexOf('mp4') >= 0) {
return 'mp4';
} else if (keys.indexOf('flv') >= 0) {
return 'flv';
}
}
;
function toHex(number) {
var str = number.toString(16);
return ((str.length < 2) ? '0' + str : str).toUpperCase();
}
;
replacePlayer();
}
;
function run(callback) {
if (window.top != window)
return true;
var script = document.createElement('script');
script.id = '__flash2mplayer';
script.textContent = '(' + callback.toString() + ')(window);';
document.body.appendChild(script);
if (document.domain == 'douban.fm') {
return;
}
var conunt = 0, max = 6;
function request() {
if (document.domain == 'tv.sohu.com') {
var vid = document.getElementById('__flash2mplayer').getAttribute('vid');
if (!vid) {
if (count > max)
return;
count++;
setTimeout(request, 1000);
return;
}
var fuid = document.getElementById('__flash2mplayer').getAttribute('sohufuid');
var playlistId = document.getElementById('__flash2mplayer').getAttribute('sohuplaylistId');
var url = "http://hot.vrs.sohu.com/vrs_flash.action?vid=" + vid
+ "&af=1&bw=8135&plid=" + playlistId + "&uid=" + fuid + "&out=0&g=8&referer="
+ encodeURIComponent(window.location.href) + '&t=' + Math.random();
var playlist = [];
var count = 0;
GM_xmlhttpRequest({method: 'GET', url: url,
onload: function(response) {
var videoList = JSON.parse(response.responseText);
var sohucatcode = videoList.catcode;
var ip = videoList.allot;
var len = videoList.data.su.length;
for (var i in videoList.data.su) {
var clip = videoList.data.clipsURL[i].split('/').splice(-4, 4).join('/');
var getrealurl = "http://" + ip + "/?prot=2&t=0.123123&file=" + clip + "&new=" + videoList.data.su[i];
var sec = videoList.data.clipsDuration;
var tsec = videoList.data.totalDuration;
GM_xmlhttpRequest({method: 'GET', url: getrealurl,
su: videoList.data.su[i],
idx: i, sec: sec,
onload: function(response) {
count++;
var realurl = response.responseText.split('|');
var videourl = realurl[0] + this.su + '?key=' + realurl[3]
+ '&ua=&ch=v&catcode=' + sohucatcode
+ '&plat=flash_Linux3.11.10-200.fc19.x86_64&n=6&a=4019';
playlist[this.idx] = {};
playlist[this.idx]['url'] = videourl;
playlist[this.idx]['seconds'] = this.sec;
if (count == len) {
var script = document.createElement('script');
script.textContent = 'F2McallbackGetData(' + JSON.stringify(playlist) + ',' + Math.round(tsec) + ');';
document.body.appendChild(script);
}
}});
}
}});
return;
}
var vcode = document.getElementById('__flash2mplayer').getAttribute('vcode');
if (!vcode) {
if (count > max)
return;
count++;
setTimeout(request, 1000);
return;
}
var tudoduiid = document.getElementById('__flash2mplayer').getAttribute('tudouiid');
if (tudoduiid || (vcode && document.domain == 'tudou.com')) {
var videosegs = JSON.parse(document.getElementById('__flash2mplayer').getAttribute('segs'));
if (typeof videosegs['5'] !== 'undefined') {
var seg = videosegs['5'];
} else if (typeof videosegs['3'] !== 'undefined') {
var seg = videosegs['3'];
} else {
var seg = videosegs['2'];
}
var playlist = [];
var len = seg.length;
var count = 0;
var seconds = 0;
for (var i in seg) {
var url = 'http://v2.tudou.com/f?sender=pepper&v=4.2.2&sj=1&id=' + seg[i]['k'] + '&sid=11000&hd=5&r=0';
seconds = seconds + seg[i]['seconds'];
request = GM_xmlhttpRequest({
idx: i,
method: 'GET',
seconds: seconds,
url: url,
onload: function(response) {
var tmp = document.createElement('span');
var re = response.responseText.split('>') [1].split('<') [0];
tmp.innerHTML = re;
var index = seg[this.idx]['no'];
playlist[index] = {};
playlist[index]['url'] = tmp.textContent;
playlist[index]['seconds'] = Math.round(this.seconds / 1000);
count++;
if (count == len) {
var script = document.createElement('script');
script.textContent = 'F2McallbackGetData(' + JSON.stringify(playlist) + ',' + Math.round(seconds / 1000) + ');';
document.body.appendChild(script);
}
delete tmp;
}
});
}
return;
} else {
var url = 'http://v.youku.com/player/getPlayList/VideoIDS/' + vcode + '/timezone/+08/version/5/source/out/Sc/2?password=&ran=9777&n=3';
}
GM_xmlhttpRequest({
method: 'GET',
url: url,
onload: function(response) {
var re = response.responseText;
var script = document.createElement('script');
script.textContent = 'F2McallbackGetData(' + re + ',0);';
document.body.appendChild(script);
}
});
}
request();
//setTimeout(request, 1000);
}
;
var ckc = 1;
var stop = false;
var call = function() {
if (ckc == 4) {
stop = true;
}
if(ckc >= 5)
return;
if (document.getElementsByTagName('object').length == 0
&& document.getElementsByTagName('embed').length == 0) {
if (stop) {
run(Flash2Mplayer);
return;
}
setTimeout(call, 2000);
} else {
var stop = true;
run(Flash2Mplayer);
return;
}
ckc++;
}
call();
})();