加密的 HLS 用作直播,不用作 VOD
Encrypted HLS works as live stream, doesn't work as VOD
我找到了一些用于将视频文件编码和加密为 HLS 流的粗略 bash 脚本,我对其进行了轻微编辑(我不知道 bash):
#!/bin/bash
set -e # Exit on errors
tsFile=""
if ! [ -f "$tsFile" -a -r "$tsFile" ]; then
echo "First argument is required" >&2
exit 2
fi
if [ -z "" ]; then
output="output"
else
output=""
fi
keyFile="$output.key"
keyInfoFile="$output.keyinfo"
playList="$output.m3u8"
if [ -z "" ]; then
separator='-'
else
separator=""
fi
splitFilePrefix="$output$separator"
if [ -d "" ]; then
outDir=""
else
mkdir "" || exit 1
outDir=""
fi
tempDir="$outDir/.$$_tmp"
keyFile="$outDir/$keyFile"
mkdir $tempDir
echo "$outdir/$keyFile\n$outdir/$keyFile" > "$outdir/$keyInfoFile"
ffmpeg -i "$tsFile" -hls_time 5 -hls_list_size 0 -hls_segment_filename "$tempDir/$splitFilePrefix%03d.ts" -strict -2 "$tempDir/$playList"
openssl rand 16 > $keyFile
encryptionKey=`cat $keyFile | hexdump -e '16/1 "%02x"'`
numberOfTsFiles=$(( `ls "$tempDir/$splitFilePrefix"*.ts | wc -l` -1 ))
for i in $(seq -f "%03g" 0 $numberOfTsFiles); do
initializationVector=`printf '%032x' $(( 10#$i))`
openssl aes-128-cbc -e -in "$tempDir/$splitFilePrefix"$i.ts \
-out "$outDir/$splitFilePrefix"$i.ts -nosalt -iv $initializationVector -K $encryptionKey
done
{
head -4 "$tempDir/$playList"
echo '#EXT-X-KEY:METHOD=AES-128,URI='"$keyFile"
egrep "$tempDir/$playList" -vie '#EXT-X-TARGETDURATION:' \
| tail -n +4
} > "$outDir/$playList"
#rm -r "$tempDir"
结果如下:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI=output.key
#EXT-X-TARGETDURATION:11
#EXTINF:10.176833,
output-000.ts
#EXTINF:8.341667,
output-001.ts
#EXTINF:8.341667,
output-002.ts
#EXTINF:3.136467,
output-003.ts
#EXT-X-ENDLIST
这几乎行得通。但是我需要 VOD,而不是直播。所以,我添加了行:
#EXT-X-PLAYLIST-TYPE:VOD
现在它不适用于加密的段,只能用于未加密的段。我以为所有段都是单独加密的?此外,即使是未加密的文件,也不会显示有关总长度的信息。我该如何解决?
这里有一些基于我自己的实验的建议,它们似乎适用于 VLC,iOS 和 Android。
初始化向量
当播放列表中未指定 IV
时,每个片段的默认 IV
等于媒体序列。确保 segment-000 的 IV=0,segment-001 的 IV=1 等等。
引用 URI
iOS 似乎不喜欢 URI
不使用引号的播放列表,所以使用 EXT-X-KEY:METHOD=AES-128,URI="output.key"
播放列表类型VOD
EXT-X-PLAYLIST-TYPE
是可选的,只要最后有 EXT-X-ENDLIST
,播放列表就会被视为静态的,并允许您进行搜索。无论有无此标签,VLC 和 iOS 都将您的播放列表视为 VOD。
关于 媒体持续时间,VLC 显示 0 而 iOS 显示正确的值。
如果您做指定EXT-X-PLAYLIST-TYPE:VOD
确保它在EXT-X-VERSION:3
之后EXT-X-VERSION:3
否则VLC不会喜欢它.
我找到了一些用于将视频文件编码和加密为 HLS 流的粗略 bash 脚本,我对其进行了轻微编辑(我不知道 bash):
#!/bin/bash
set -e # Exit on errors
tsFile=""
if ! [ -f "$tsFile" -a -r "$tsFile" ]; then
echo "First argument is required" >&2
exit 2
fi
if [ -z "" ]; then
output="output"
else
output=""
fi
keyFile="$output.key"
keyInfoFile="$output.keyinfo"
playList="$output.m3u8"
if [ -z "" ]; then
separator='-'
else
separator=""
fi
splitFilePrefix="$output$separator"
if [ -d "" ]; then
outDir=""
else
mkdir "" || exit 1
outDir=""
fi
tempDir="$outDir/.$$_tmp"
keyFile="$outDir/$keyFile"
mkdir $tempDir
echo "$outdir/$keyFile\n$outdir/$keyFile" > "$outdir/$keyInfoFile"
ffmpeg -i "$tsFile" -hls_time 5 -hls_list_size 0 -hls_segment_filename "$tempDir/$splitFilePrefix%03d.ts" -strict -2 "$tempDir/$playList"
openssl rand 16 > $keyFile
encryptionKey=`cat $keyFile | hexdump -e '16/1 "%02x"'`
numberOfTsFiles=$(( `ls "$tempDir/$splitFilePrefix"*.ts | wc -l` -1 ))
for i in $(seq -f "%03g" 0 $numberOfTsFiles); do
initializationVector=`printf '%032x' $(( 10#$i))`
openssl aes-128-cbc -e -in "$tempDir/$splitFilePrefix"$i.ts \
-out "$outDir/$splitFilePrefix"$i.ts -nosalt -iv $initializationVector -K $encryptionKey
done
{
head -4 "$tempDir/$playList"
echo '#EXT-X-KEY:METHOD=AES-128,URI='"$keyFile"
egrep "$tempDir/$playList" -vie '#EXT-X-TARGETDURATION:' \
| tail -n +4
} > "$outDir/$playList"
#rm -r "$tempDir"
结果如下:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI=output.key
#EXT-X-TARGETDURATION:11
#EXTINF:10.176833,
output-000.ts
#EXTINF:8.341667,
output-001.ts
#EXTINF:8.341667,
output-002.ts
#EXTINF:3.136467,
output-003.ts
#EXT-X-ENDLIST
这几乎行得通。但是我需要 VOD,而不是直播。所以,我添加了行:
#EXT-X-PLAYLIST-TYPE:VOD
现在它不适用于加密的段,只能用于未加密的段。我以为所有段都是单独加密的?此外,即使是未加密的文件,也不会显示有关总长度的信息。我该如何解决?
这里有一些基于我自己的实验的建议,它们似乎适用于 VLC,iOS 和 Android。
初始化向量
当播放列表中未指定
IV
时,每个片段的默认IV
等于媒体序列。确保 segment-000 的 IV=0,segment-001 的 IV=1 等等。引用
URI
iOS 似乎不喜欢
URI
不使用引号的播放列表,所以使用EXT-X-KEY:METHOD=AES-128,URI="output.key"
播放列表类型
VOD
EXT-X-PLAYLIST-TYPE
是可选的,只要最后有EXT-X-ENDLIST
,播放列表就会被视为静态的,并允许您进行搜索。无论有无此标签,VLC 和 iOS 都将您的播放列表视为 VOD。关于 媒体持续时间,VLC 显示 0 而 iOS 显示正确的值。
如果您做指定
EXT-X-PLAYLIST-TYPE:VOD
确保它在EXT-X-VERSION:3
之后EXT-X-VERSION:3
否则VLC不会喜欢它.