视频储存——在线播放一直是个人博客/站长的一大难点。大多数人是选择上传到视频网站,再在博客中调用视频网站上的视频。

这个项目已失效,仅作为备份

我的博客是有播放视频的需求,最开始是OneDrive直链,但随着oneindex的api逐渐失效,我又尝试过rclone挂载OneDrive后从我的服务器中转,或者是3o独服储存视频,最后选择了甲骨文的对象存储。这些都有个缺点,就是在夜晚高峰期网速直接爆炸。虽然我有GIA线路的服务器,但作为视频服务器还是太奢侈了,国内服务器太贵不考虑。
现在又有了新的方案
利用图床来储存视频。
据原作者说:

我也是偶然发现的。把视频切片成 m3u8 之后,视频会变成一段段的 ts 格式的视频。这个时候我想了一下。如果说某些图床有 bug
不验证文件格式,那么是不是就可以把切片视频放在他的服务器上进行播放了?

嘿嘿,没想到真的可以。当当当~ 他就是某里的“图床”。

这个其实不是什么图床,是某巴客服中一个漏洞,稳定几年了,很多什么图床网站就是用这个接口

下面,让我们开始吧。

请使用甲骨文/vultr/GCP这一类可以随时更换ip的服务器,这是为了防止图床限制单ip的上传量。如果是上传大的视频(大于50M),请自行手动切割好视频后,分批执行脚本分ip上传,以免触发api的风控

我不建议你使用家宽来上传,因为大部分家宽的连接性并不好,极有可能上传某个部分上传失败,这个脚本没有校验机制,上传失败手动修复太麻烦了

环境

我是使用centos7,其它的系统我也不会折腾它的环境。

首先还是全新安装系统,尤其是你之前装过宝塔等web环境的服务器最好不用。

其实是因为我懒得排错,如果你非要用的话就自行排错吧

安装PHP

原作者没说限定啥PHP版本,我偷懒直接用软件包里的PHP,虽然陈旧,反正够用就行。

yum install php

安装ffmpeg

我搜了下中文网站里安装ffmpeg的方法既陈旧又不完整,试了好几个教程都不能正常执行下面的脚本。最后把我搞毛了直接搜英文的教程。最后找到了篇不错的文章

从存储库安装FFMPEG

建议不要用存储库安装FFMPEG


首先安装epel-release

yum -y install epel-release

安装nux存储库

rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpm

安装ffmpeg和ffmpeg -devel软件包

yum install ffmpeg ffmpeg-devel -y

确保其有效:

# ffmpeg -version
ffmpeg version 2.6.8 Copyright (c) 2000-2016 the FFmpeg developers
built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-4)
configuration: --prefix=/usr --bindir=/usr/bin --datadir=/usr/share/ffmpeg --incdir=/usr/include/ffmpeg --libdir=/usr/lib64 --mandir=/usr/share/man --arch=x86_64 --optflags='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic' --enable-bzlib --disable-crystalhd --enable-gnutls --enable-ladspa --enable-libass --enable-libcdio --enable-libdc1394 --enable-libfaac --enable-nonfree --enable-libfdk-aac --enable-nonfree --disable-indev=jack --enable-libfreetype --enable-libgsm --enable-libmp3lame --enable-openal --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libvorbis --enable-libv4l2 --enable-libx264 --enable-libx265 --enable-libxvid --enable-x11grab --enable-avfilter --enable-avresample --enable-postproc --enable-pthreads --disable-static --enable-shared --enable-gpl --disable-debug --disable-stripping --shlibdir=/usr/lib64 --enable-runtime-cpudetect
libavutil 54. 20.100 / 54. 20.100
libavcodec 56. 26.100 / 56. 26.100
libavformat 56. 25.101 / 56. 25.101
libavdevice 56. 4.100 / 56. 4.100
libavfilter 5. 11.102 / 5. 11.102
libavresample 2. 1. 0 / 2. 1. 0
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 1.100 / 1. 1.100
libpostproc 53. 3.100 / 53. 3.100

使用静态预构建版本安装FFMPEG

获取安装程序脚本:

wget https://raw.githubusercontent.com/q3aql/ffmpeg-install/master/ffmpeg-install

使它可执行

chmod a+x ffmpeg-install

安装发行版本

./ffmpeg-install --install release

确保其有效:

# ffmpeg -version
ffmpeg version 3.3.2-static http://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2017 the FFmpeg developers
built with gcc 5.4.1 (Debian 5.4.1-11) 20170519
configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-5 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gray --enable-libass --enable-libfreetype --enable-libfribidi --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzimg
libavutil 55. 58.100 / 55. 58.100
libavcodec 57. 89.100 / 57. 89.100
libavformat 57. 71.100 / 57. 71.100
libavdevice 57. 6.100 / 57. 6.100
libavfilter 6. 82.100 / 6. 82.100
libswscale 4. 6.100 / 4. 6.100
libswresample 2. 7.100 / 2. 7.100
libpostproc 54. 5.100 / 54. 5.100

建议使用静态预构建版本安装FFMPEG,使用存储库安装的FFMPEG在执行脚本时会提示x264环境有问题

处理视频脚本

这个脚本是PHP写的,直接复制脚本内容,在服务器中储存为handle.php(什么名都成!这个就随便命名一下)

handle.php

<?php
 
$v_path = $argv[1]; //切片路径
$v_name = $argv[2]; //带切片的视频路径名称
$s = 5; //切片秒  ts 切片必须小于 5MB
if (empty($v_path) || empty($v_name)) {
    echo "请填写完整参数";
    exit;
}
 
if ($v_path == '/' || $v_path == '\\') {
    $v_path = '';
} else {
    mkFolder($v_path);
    $v_path = $v_path . "/";
}
//这是 FFmpeg 处理命令大家自行更改
exec("ffmpeg -i $v_name -c copy -map 0 -f segment -segment_list " . $v_path . "playlist.m3u8 -segment_time $s " . $v_path . "player%03d.ts");
 
$m = file_get_contents('./' . $v_path . 'playlist.m3u8');
 
preg_match_all('/player(.*?)\.ts/', $m, $arr);
 
foreach ($arr[1] as $key => $value) {
    echo "处理第" . $value . '个切片' . "\n";
    $ali = upload('./' . $v_path . 'player' . $value . '.ts');
    $m = str_replace('player' . $value . '.ts', $ali, $m);
    file_put_contents('./' . $v_path . 'play.m3u8', $m);
}
 
echo "处理完毕" . "\n";
echo "播放链接为:/" . $v_path . 'play.m3u8';
 
function upload($file) {
    $post['file'] = file_path($file);
    $post['scene'] = 'aeMessageCenterV2ImageRule';
    $post['name'] = 'player.jpg';
    $rel = get_curl('https://kfupload.alibaba.com/mupload', $post, 'iAliexpress/6.22.1 (iPhone; iOS 12.1.2; Scale/2.00)');
    $rel = json_decode($rel, true);
 
    return $rel['url'];
}
 
function get_curl($url, $post = 0, $ua = 0) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    // 不验证证书
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    // 最大执行时间
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120);
    curl_setopt($ch, CURLOPT_TIMEOUT, 120);
    $httpheader[] = "Accept:application/json";
    $httpheader[] = "Accept-Encoding:gzip,deflate,sdch";
    $httpheader[] = "Accept-Language:zh-CN,zh;q=0.8";
    $httpheader[] = "Connection:close";
    $ip = mt_rand(48, 140) . "." . mt_rand(10, 240) . "." . mt_rand(10, 240) . "." . mt_rand(10, 240); //随机 ip
    $httpheader[] = 'CLIENT-IP:' . $ip;
    $httpheader[] = 'X-FORWARDED-FOR:' . $ip;
    curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
    if ($post) {
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
    }
 
    if ($ua) {
        curl_setopt($ch, CURLOPT_USERAGENT, $ua);
    } else {
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Linux; U; Android 4.0.4; es-mx; HTC_One_X Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0");
    }
    curl_setopt($ch, CURLOPT_ENCODING, "gzip");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $ret = curl_exec($ch);
    curl_close($ch);
    return $ret;
}
function mkFolder($path) {
    if (!is_readable($path)) {
        is_file($path) or mkdir($path, 0700);
    }
}
function file_path($file) {
    if (class_exists('CURLFile')) {
        return $post['file'] = new \CURLFile(realpath($file));
    } else {
        return $post['file'] = '@' . realpath($file);
    }
}

将需要处理的视频片段放入同一个文件夹中(我重命名为test.mp4了)
运行命令:

php handle.php out test.mp4

out是指输出ts文件存放的位置文件夹,包括后面你需要在这个位置获取m3u8的文件
test.mp4就是你需要处理的视频文件位置

执行脚本,它会提示:

处理完毕
播放链接为:/out/play.m3u8

你把play.m3u8上传到网盘或者对象存储中,获取直链,再用dplayer播放即可。

脚本执行完成后会自动上传到图床中,记得执行前给脚本和视频权限。777完事

作者的话:

注意:这个接口只能上次小于 5MB 以下的图片(视频切片)所以切片完文件大小必须小于 5MB,还有就是 PHP
本身就不适合写脚本,单线程处理,很慢.建议用 PY 或者 java(我不会,希望有大佬写一下),其他的自己看代码就能懂,其实没啥.

typecho播放m3u8

我在这里使用的是dplayer
关于如何安装使用建议看官方文档
我在这里提醒下,

url="http://xxx.com/xxx.mp4"

这里url后面需要你使用m3u8文件的直链,你可以将获得的m3u8文件上传到对象存储或者网盘获取直链,填进去
还有dplayer插件的设置那需要你把HLS支持打开

测试视频

我和我的祖国 av68818070


参考:
FFMPEG INSTALL ON CENTOS 7
视频完美切片存储方案 附自动化处理脚本
MoePlayer/DPlayer-Typecho

最后修改:2020 年 05 月 20 日
如果觉得我的文章对你有用,请随意赞赏