前言
之所以会有这样的需求,是因为我在用 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 应该也可以做到,但我实在不想折腾了。
Comments | 5 条评论
博主 ZLOE
兄弟 你知道他们这个视频是怎么传上去的吗
博主 傲娇的小基基
@ZLOE 不知道……
博主 mengz
兄弟现在你知道怎么传了吗
博主 傲娇的小基基
@mengz 还是不知道……
博主 LumiaGG
哈哈, 我就是疯狂请求 headers 来解决重定向的.