2015-04-22 3 views
2

Я нашел грубый скрипт bash для кодирования и шифрования видеофайла в потоке HLS, и я немного его отредактировал (я понятия не имею о bash):Зашифрованный HLS работает как прямой эфир, не работает как VOD

#!/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 

И теперь он не работает с зашифрованными сегментами, только с шифрованными,. Я думал, что все сегменты зашифрованы отдельно? Кроме того, даже с незашифрованными файлами информация об общей длине отсутствует. Как я могу это исправить?

+0

'EXT-X-PLAYLIST-TYPE' не является обязательным. Если вы добавите 'EXT-X-ENDLIST', вы сообщите, что список воспроизведения содержит последний сегмент, и он больше не будет обновляться. Как вы тестируете поток, на устройстве ios? – aergistal

+0

Кроме того, 'EXT-X-KEY' применяется к сегментам, и вы можете иметь более одного в списке воспроизведения. Я думаю, что правильная позиция тега должна быть непосредственно перед первым «EXTINF». Это не должно меняться, но кто знает ... – aergistal

+0

Я тестирую на окнах, через VLC – Misiur

ответ

1

Вот несколько указателей, основанных на моих собственных экспериментах, которые, похоже, работают на VLC, iOS и Android.

  • инициализации векторов

    При отсутствии IV не указано в списке воспроизведения каждый сегмент имеет значение по умолчанию, равное IV последовательности медиа. Убедитесь, что сегмент 000 имеет IV = 0, сегмент-001 имеет IV = 1 и так далее.

  • Цитируя URI

    IOS, кажется, не нравится плейлист, где URI не используют кавычки, так что используйте EXT-X-KEY:METHOD=AES-128,URI="output.key"

  • типа Playlist VOD

    EXT-X-PLAYLIST-TYPE является необязательным и, как если у вас есть EXT-X-ENDLIST в конце, плейлист рассматривается как статический и позволяет вам искать. С этим тегом или без него оба VLC и iOS рассматривают ваш плейлист как VOD.

    Касательно Срок службы носителей, VLC показывает 0 wile iOS показывает правильное значение.

    Если вы сделать указать EXT-X-PLAYLIST-TYPE:VOD убедитесь, что он приходит послеEXT-X-VERSION:3 или VLC не понравится.