由于疫情原因,这个寒假格外长,闲赋在家,看了看之前的TODO LIST ,一个YouTube的播放器问题吸引了我,趁时间,捡起来研究研究,于是便有了这片文章
要想做一个YouTube播放器,首先是API部分,这个有官方的API,不用我们自己爬数据,但是有请求量限制,不过这个也好说,加一层缓存,既提高了性能也降低了源请求量,等流量真的大了,还可以做多密钥负载均衡.
https://developers.google.cn/youtube/v3/docs/
提供的API很多,但是我们只需要实现自己需要的就OK了.
总体来说就是加密钥,处理缓存,中转代理,我们选用GO语言来编写,这个处理起来十分容易.不得不说GO语言的网络库封装的非常好用.
有了API下面就是前端界面,我们直接VUE全家桶搞起来,UI界面懒得慢慢打磨直接用个muse-ui框架,看起来还是很简洁的.
播放地址解析 播放器部分是我们的重点.
Data API 是不提供资源的播放地址的,播放地址也是敏感信息,我们需要自己实现.
根据页面分析和抓包,再参考广大互联网群众的智慧,我们完成了 https://github.com/suconghou/youtubevideoparser 这个库
根据视频ID解析出播放地址,但是播放地址由于某种原因我们是无法直接播放的,所以这需要一个合适的中转.
如果中转整个视频,CDN很不友好,文件太大,CDN节点也不会为我们缓存.并且分析播放器我们也知道官方的播放器也不是一整个加载的,而是分片加载.
如何分片是个问题,因为一旦采取了分片,意味着我们要使用MSE去处理视频.
尝试了一下随便range分片结合mse,实践证明是行不通的.
那官方的播放器是怎么做的呢,很明显关键点在这个分片的算法,不是随意分片的.
但是找遍了源码也没找到这个分片的规则定义在哪?
最后突然想到突破点可能是在视频文件本身,顺着这个思路问题解决.
中间浪费了大量时间.这里不得不吐槽一下广大科普MSE的文章.
大部分文章都提到了fragment mp4,都知道range请求,一片一片去addSourceBuffer
但是对于range的划分原则,.mpd索引的原理和sidx segment丝毫未提.
换句话说就是不是你想addSourceBuffer就能addSourceBuffer的,你必须取到一块完整的fragment才能addSourceBuffer,如何从视频中知道哪一字节至哪一字节是一个完整的fragment
我们需要从视频的sidx segment中提取,.mpd索引就是预先根据sidx segment分析出来的结果.
持有mpd索引,我们播放时就不需要再去下载视频中的sidx segment现场分析了.
如何解析sidx segment 关于MSE的基本使用,这里不再赘述,网上入门的文章太多了,这里主要展开讨论一下mp4文件与sidx segment,无论是mp4还是fragment mp4,我们都可以将mp4文件拆解为基本的box
常见的box类型有
ftyp 确定文件的类型 moov 保存了媒体的时间信息、trak信息和媒体索引等。 mdat 所有媒体数据统一存放在mdat中 free sidx moof 一个moov box中,可能还会嵌入其他的box,这个我们现在用不到,可以不用考虑.
我们只看顶层的box,使用qtfaststart -l file.mp4 可以查看他的顶层box
对于普通的mp4
ftyp (32 bytes) moov (135554 bytes) free (8 bytes) mdat (35973570 bytes) 对于fragment mp4
默认的配置文件是当前目录下的 dnscrypt-proxy.toml, 可以使用-config指定配置文件
listen_addresses = ['0.0.0.0:53'] max_clients = 250 ipv4_servers = true ipv6_servers = false dnscrypt_servers = true doh_servers = true require_dnssec = false require_nolog = true require_nofilter = true force_tcp = false timeout = 2500 keepalive = 30 lb_strategy = 'fastest' use_syslog = false cert_refresh_delay = 240 fallback_resolver = '114.114.114.114:53' ignore_system_dns = false netprobe_timeout = 30 log_files_max_size = 10 log_files_max_age = 7 log_files_max_backups = 1 block_ipv6 = true cache = true cache_size = 512 cache_min_ttl = 600 cache_max_ttl = 86400 cache_neg_min_ttl = 60 cache_neg_max_ttl = 600 [query_log] file = 'query.
Linux 性能优化 ulimit 确保
/proc/sys/fs/nr_open > /proc/sys/fs/file-max > ulimit -Hn > ulimit -Sn > 10000
ulimit -a 查看配置
可根据pid查看某一进程目前的限制
cat /proc/16223/limits
查看每个进程所允许的最大opend files ulimit -n
查看目前系统已打开的open files lsof | wc -l 或者 ls -l /proc/*/fd | wc -l
lsof会列出重复的, 使用 lsof|awk '{print $9}'|sort|uniq|wc -l 可以去除重复
cat /proc/sys/fs/file-nr 会在系统内核层面统计,比较正确
查看系统所允许的最大open files cat /proc/sys/fs/file-max
查看一个进程目前已打开的 lsof -p 28290 或者 lsof -a -p 28290
或者
ls -l /proc/28290/fd | wc -l
查看 hard limit ulimit -Hn
imagemagick https://www.imagemagick.org/script/download.php
https://www.imagemagick.org/download/
并提供各平台二进制可执行文件下载
png 图片压缩工具 https://css-ig.net/png-tools-overview.php#overview
https://github.com/chrissimpkins/Crunch
https://nukesaq88.github.io/Pngyu/
图像压缩软件 ImageOptim无损压缩
mozjpeg Mozilla的jpg压缩技术,支持无损,有损压缩在线压缩,最大2M.
tinypng 众多压缩软件中压缩效果较好的,支持png,jpg在线批量压缩
kraken 类似于tinypng,也提供在线压缩
pngquant 开源的压缩png,据说tinypng基于此项目
nodejs imagemin NodeJs模块,压缩jpg,png,压缩效果一般
国内在线压缩 https://imgless.com/
https://zhitu.isux.us/
https://www.picdiet.com/zh-cn
filebrowser https://github.com/filebrowser/filebrowser
Caddy 有插件集成
filerun php 开发
https://www.filerun.com/download
filerun 的模式和 nextcloud 类似,比较复杂
h5ai h5ai 是一个比较简单的php网盘
https://larsjung.de/h5ai/
调试QQ浏览器X5内核 用QQ浏览器或者微信打开 http://debugx5.qq.com/
注意不要使用https访问
微信内还可以对内核调试 微信打开 http://debugtbs.qq.com/
Chrome 打开 chrome://inspect/#devices
使用其他 工具 https://github.com/liriliri/eruda
配置frp服务器端 查看 https://github.com/fatedier/frp
服务器端配置文件/etc/frps.ini
[common] bind_port = 7000 kcp_bind_port = 7000 privilege_allow_ports = 7700,7800-7900 vhost_http_port = 5050 dashboard_port = 7500 dashboard_user = admin dashboard_pwd = 123abc881 网页控制台为7500端口
编写/etc/systemd/system/frps.service文件使开机启动
[Unit] Description=frps service After=network.target network-online.target [Service] Type=simple User=nobody Restart=on-failure RestartSec=5s ExecStart=/usr/local/bin/frps -c /etc/frps.ini [Install] WantedBy=multi-user.target sudo systemctl daemon-reload sudo systemctl enable frps sudo systemctl start frps
配置frp客户端 要穿透的代理配置 /etc/frpc.ini
[common] server_addr = x.x.x.x server_port = 7000 [ssh] type = tcp local_ip = 127.
https://css-tricks.com/
1. 使用CSS画出三角 box shadow with angle
content: " "; border: 6px solid #fff; border-left-color: transparent; border-bottom-color: transparent; display: block; position: absolute; bottom: -6px; left: 50%; -webkit-transform: translateX(-50%) rotate(135deg); transform: translateX(-50%) rotate(135deg); box-shadow: 2px -2px 2px rgba(1,1,1,.12);
proxy https://github.com/kklis/proxy
macOs 可直接编译
make darwin
./proxy 查看用法
监听本地8080端口,并将流量同时复制到192.168.1.2:80 , 必须确保 192.168.1.2:80 可写.
proxy -l 8080 -h 192.168.1.2 -p 80 默认后台运行,使用参数-f不进入后台
proxy -l 8080 -h 192.168.1.2 -p 80 -f
查看转发的数据
proxy -l 80 -h 67.215.245.160 -p 80 -i "tee input.log" -o "tee output.log" 直接输出到控制台
proxy -l 80 -h 67.215.245.160 -p 80 -f -i "tee /dev/stderr" -o "tee /dev/stderr" 转发到多个后端
查看 https://github.com/kklis/proxy
命令行参数 在当前目录下开启静态服务器
caddy -host t.xxx.cn
首次运行后会提示输入邮箱,用于获取https证书,获取完证书即开启成功
默认启用http2,默认http端口80,https端口443,默认启用http跳转到https,默认首页自动加载index.html
使用-root参数可以设置根目录,默认为当前目录
相关文件会存储于~/.caddy文件夹中.
sudo setcap cap_net_bind_service=+ep ./caddy
使用QUIC caddy -host t.xxx.cn -quic 使用quic协议
使用quic参数后,通过netstat -anltup 可以查看到tcp和udp的80和443端口都被监听.
Chrome浏览器支持quic,可以通过chrome://net-internals/#quic 查看是使用的是quic还是http2
使用配置文件 Caddyfile
:80 { log stdout errors stderr redir https://{host}{uri} } :443 { log stdout errors stderr gzip tls /caddy/ssl/default.crt /caddy/ssl/default.key root /caddy/sites.d/0-default markdown / } site1.local { log stdout errors stderr gzip proxy / dockerhost.local:32000 { policy least_conn transparent insecure_skip_verify fail_timeout 10s max_fails 1 try_duration 1s } } site2.