前言

之所以会有这样的需求,是因为我在用 Chrome 浏览dokidoka上类似《为美好的世界献上祝福》这样的视频时,发现总是无法解析,之前用的一直是电脑和手机上的 Safari 浏览器所以没有在意,但既然 Chrome 无法解析,那肯定还是有优化的余地的。

方法

在基于苹果cms(或者其他源码)的视频站上,Chrome 解析不了话题圈视频的原因有两个:一是你向目标网址传了 refer,触发了防盗链,在开发者模式中可以看到这条请求返回了403 Forbidden;另一个原因是 Mixed Content,也就是你的网站开启了全站 https,但是话题圈的视频会重定向到一个 http 的视频链接,Chrome 出于安全考虑就直接再重定向到 https 链接,而这个http链接没有直接对应的 https 视频源,就会返回404 Not Found。

防盗链

解决防盗链问题的方法很简单,首先找到你播放器对应的 html 文件,不知道具体路径的话,可以查看一下苹果 cms 后台的播放器 js 代码:

MacPlayer.Html = '<iframe border="0" src="'+maccms.path+'/static/player/dplayer.html'"width="100%" height="100%" marginWidth="0" frameSpacing="0" marginHeight="0" frameBorder="0" scrolling="no" vspale="0" allowfullscreen="true" noResize></iframe>';

从上面可以看出播放器文件的位置: /static/player/dplayer.html

打开这个html文件,在 head 标签里加上一行:

<meta name='referrer' content='same-origin'>

清空缓存之后再去 Chrome 里试试,应该不会再触发防盗链返回 403 了。

重定向

话题圈视频重定向之后其实是可以直接播放的,比如

http://quan.qq.com/video/1098_bf2b84523854a1be4a9681fd56e5a5bd 

的视频会重定向到

http://223.110.16.155/183.192.164.30/vmtt.tc.qq.com/1098_bf2b84523854a1be4a9681fd56e5a5bd.f0.mp4?vkey=64CB74C04A1B03A684144B6283F7C628438EBF3B6D625E9A3AFE01B6C8FC74E54B7034D39FB905C3F331E54F8B13BA499DF8E8126391E4A40A40F18B8DE0411CA01CA634E0504D8B13282B969F472A4C1952BBAD6B663F66

这并不影响观看。

Chrome 中返回 404 其实只是因为你的网站开了全站 https,而在 https 网页中引入含有 http 链接的 iframe 是不被允许的,以前貌似会警告或者报错,现在直接是警告之后给你自动转 https 了。

方法 1

如果你不是强迫症的话,那么解决方法其实也特别简单。只要撤销你的全站 https 就行了,就像著名的樱花动漫(yhdm.tv 和 imomoe.jp,这俩都叫樱花动漫),这样的话不用做任何修改就可以完美解析和播放。

但这种方法真是我无法忍受的。加不加 https 其实无所谓,但是你在网站运行了很久之后突然撤掉 https,不但会影响 SEO,而且你以前发出去的链接还要全部修改,这得有多大的工作量呢。之前我倒是想了个折中的办法,就是保持 https,但不强制转换 http,然后修改一下播放器的封面,提示大家“视频加载失败的话试试把地址栏里的 https 修改成 http”,这样相对来说好一点,但还是达不到我的要求。

方法 2

想解决 Mixed Content,要么就全 http,要么就全 https。前文已经说了,那个 http://223.110.16.155/183.192.164.30/开头的链接没有对应的 https 源,所以全 https 看似无解,但我在逛嘀哩嘀哩的时候却发现它是全站 https 的,一番研究过后,我发现它还真有个奇技淫巧。

原来把前面那一串ip修改成 https://apd-vliveachy.apdcdn.tc.qq.com/ 也可以播放啊干!

这不就相当于找到了对应的 https 源嘛。

下一步只要想办法替换一下链接就可以了。

思路很简单,先向原始的 quan.qq.com.....这个链接发送 HEAD 请求,返回的 headers 中 Location 对应的值就是 http://223.110.16.155/183.192.164.30/开头的地址,再把它替换成https://apd-vliveachy.apdcdn.tc.qq.com/

就这简单的几步,用 python 写完可能都用不到一分钟,但我毕竟对 js 和 php 零基础,为了能应用到网站,花了整整一晚上。

下面直接放解决方法和代码

登录苹果cms的后台,修改播放器的js代码,把dplayer.html修改成 dplayer.php?url= 再加上 MacPlayer.PlayUrl,效果如下

MacPlayer.Html = '<iframe border="0" src="'+maccms.path+'/static/player/dplayer.php?url='+ MacPlayer.PlayUrl + '"width="100%" height="100%" marginWidth="0" frameSpacing="0" marginHeight="0" frameBorder="0" scrolling="no" vspale="0" allowfullscreen="true" noResize></iframe>';

登录服务器,定位到网站目录/static/player/ 把 dplayer.html,修改成 dplayer.php(或者新建一个dplayer.php,把dplayer.html里面的代码粘贴进去),这样才可以执行 php 代码。

在dplayer.php里插入一段 PHP 程序

<?php
	function quan_qq($video){
	stream_context_set_default(array('http'=>array('method'=>'HEAD')));
	$headers = get_headers($video);
	foreach($headers as $value){
		if (strpos($value, 'vmtt.tc.qq.com')!==false){
			$video = strstr($value, 'vmtt.tc.qq.com');
			$video = 'https://apd-vliveachy.apdcdn.tc.qq.com/'."".$video;
			}
		}
	return $video;
	}
	$video = quan_qq($_GET['url'])
?>

$_GET['url'] 读取了 dplayer.php?url= 后面的内容,而quan_qq()这个函数则把链接转换成 https 链接。所以这段代码实际上返回了处理后的链接。

然后找到下面的js代码

var dp = new DPlayer({
	container: document.getElementById('playerCnt'),
	autoplay: true,
	screenshot: false,
	video: {
            url: parent.MacPlayer.PlayUrl,
            live: live,
            type:type
        },
	contextmenu: [
  ]
	}
);

把php嵌套进去

var dp = new DPlayer({
	container: document.getElementById('playerCnt'),
	autoplay: true,
	screenshot: false,
	video: {
            url: "<?php echo $video?>",
        },
	contextmenu: [
  ]
	}
);

当然了,如果你不只是用这个播放器来解析话题圈的视频,也可以先判断一下要不要处理链接

比如这样

var play_url = "<?php echo $_GET['url'];?>"
if (play_url.indexOf('quan.qq.com')>-1){
    play_url = "<?php
                function quan_qq($video){
                    stream_context_set_default(array('http'=>array('method'=>'HEAD')));
                    $headers = get_headers($video);
                    foreach($headers as $value){
                        if (strpos($value, 'vmtt.tc.qq.com')!==false){
                            $video = strstr($value, 'vmtt.tc.qq.com');
                            $video = 'https://apd-vliveachy.apdcdn.tc.qq.com/'."".$video;
                            }
                        }
                    echo $video;
                }
                quan_qq($_GET['url'])
                ?>"
}
…………
video: {
            url: play_url,
        },

然后清空一下网站缓存,这下 Chrome 应该不再报错了。

理论上纯 js 应该也可以做到,但我实在不想折腾了。