【问题标题】:Encrypted HLS works as live stream, doesn't work as VOD加密 HLS 可用作实时流,不能用作 VOD
【发布时间】:2015-04-23 03:27:14
【问题描述】:

我找到了一些粗略的 bash 脚本,用于将视频文件编码和加密到 HLS 流中,并且我稍微编辑了它(我不知道 bash):

#!/bin/bash

set -e     # Exit on errors

tsFile="$1"

if ! [ -f "$tsFile" -a -r "$tsFile" ]; then
    echo "First argument is required" >&2
    exit 2
fi

if [ -z "$3" ]; then
    output="output"
else
    output="$3"
fi


keyFile="$output.key"
keyInfoFile="$output.keyinfo"
playList="$output.m3u8"

if [ -z "$4" ]; then
    separator='-'
else 
    separator="$4"
fi

splitFilePrefix="$output$separator"


if [ -d "$2" ]; then
    outDir="$2"
else
    mkdir "$2" || exit 1
    outDir="$2"
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

现在它不适用于加密段,只能用于未加密段。我认为所有段都是单独加密的?此外,即使使用未加密的文件,也不存在有关总长度的信息。我该如何解决?

【问题讨论】:

  • EXT-X-PLAYLIST-TYPE 是可选的。如果您添加EXT-X-ENDLIST,则表明播放列表包含最后一段并且不再刷新。您如何在 ios 设备上测试流?
  • 另外,EXT-X-KEY 适用于片段,您可以在播放列表中拥有多个片段。我认为标签的正确位置应该在第一个EXTINF之前。它不应该有所作为,但谁知道......
  • 我正在通过 VLC 在 Windows 上进行测试
  • 不,订单似乎没有任何改变。我以为您需要多个键的#EXT-X-DISCONTINUITY,但它适用于多个单独的文件。密钥轮换有一些不同的机制。
  • 我尝试了一个像你这样的例子(它使用基于媒体序列的默认 IV),它在 VLC 2.1.6、iOS 8.3 和 Android 4.4.4 上使用或不使用 EXT-X-PLAYLIST-TYPE:VOD 都可以正常工作跨度>

标签: bash ffmpeg http-live-streaming


【解决方案1】:

以下是基于我自己的实验的一些建议,这些建议似乎适用于 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 否则VLC 不会喜欢它。

【讨论】:

    猜你喜欢
    • 2017-11-29
    • 2017-11-23
    • 2014-09-06
    • 2018-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-19
    相关资源
    最近更新 更多