shell 从变量运行Bash命令- Shaka打包问题

tcbh2hod  于 2022-11-16  发布在  Shell
关注(0)|答案(2)|浏览(202)

我正在尝试在ubuntu-ec2机器上使用shaka packager并遵循official tutorial打包一些视频。
所以我有一个多分辨率文件的列表,比如original=x.mp4,转换后是x_480p.mp4, x_360p.mp4等等。我的最低分辨率是360 p。我的bash脚本会自动检测高度,并自动转换到低于这个高度。使用ffmpeg做得很好。现在的问题是,我需要使用shaka自动打包converted目录中的文件(所有文件)。
如果我在一行中运行脚本,它就可以工作。

sudo packager in=dpnd_comp.mp4,stream=video,out=test/video.mp4 in=dpnd_comp.mp4,stream=audio,out=test/audio.mp4

对于自动处理,我将路径保存在变量inputs中。当我使用变量运行此操作时,它只处理最后一个视频,这里只处理360p
这就是-

# using a for loop here

        inputs="$inputs   in="$output_path"/"$content_id"_"$height"p.mp4,stream=video,output="$packaged_out"/"$content_id"_"$height"p.mp4  "
done

echo "$inputs"

sudo packager "$inputs"

注意,'echo“$inputs”返回以下内容

in=../bin/converted/0001_720p.mp4,stream=video,output=../bin/packaged/0001_720p.mp4     in=../bin/converted/0001_480p.mp4,stream=video,output=../bin/packaged/0001_480p.mp4     in=../bin/converted/0001_360p.mp4,stream=video,output=../bin/packaged/0001_360p.mp4

任何形式的帮助都将受到高度赞赏。如果有人曾经与沙卡合作,并使过程自动化,请帮助。

**编辑:**需要在输入后添加更多参数,如下所示-

sudo packager "$inputs" \
    --enable_widevine_encryption \
    --key_server_url "$key_server" \
    --content_id "$content_id" \
    --signer "$signer_uname" \
    --aes_signing_key "$signing_key" \
    --aes_signing_iv "$signing_iv" \
    --mpd_output "$packaged_out"/"$content_id".mpd \
    --hls_master_playlist_output "$packaged_out"/"$content_id".m3u8"
xxls0lw8

xxls0lw81#

你的第一个命令(你手动尝试过的那个,并且成功了)传递了两个参数给“packager”(都以in=...开头)。你的第二个命令packager "$input"只传递了一个参数(在一个字符串中包含一个空格in=... in=...)。
因此,您可以在调用时在最后一行中去掉$input两边的双引号:sudo packager $input。如果你确定你的in=...字符串中没有包含空格,那么它就可以工作。但是这是不可取的。因为如果你的文件中包含空格,比如“vid 720.mp4”,那么输入将看起来像in=vid 720.mp4,output=packaged/vid 720.mp4 in=other.mp4,output=pack.mp4
然后用引号(sudo packager "$input")运行是wong,因为pakager将用一个参数in=vid 720.mp4,output=packaged/vid 720.mp4 in=other.mp4,output=pack.mp4运行,这意味着与它没有任何相干性。
运行时不带引号(sudo packager $input)也是错误的,因为打包程序将使用4个参数运行,in=vid720.mp4,output=packaged/vid720.mp4int=other.mp4,output=pack.mp4。这也不是您想要的。
因此,如果您确信文件名中没有任何空格,请继续运行,不要用双引号将输入括起来,并停止阅读:-)
否则,我会使用数组。

inputs=()
# using a for loop here

        inputs+=("in="$output_path"/"$content_id"_"$height"p.mp4,stream=video,output="$packaged_out"/"$content_id"_"$height"p.mp4  ")
done

echo "${inputs[@]}"

sudo packager "${inputs[@]}"

注1:如果你想知道args是如何拆分的,可以使用printf而不是echo。因为你看不到echo "one two"echo one two之间的区别。而printf "(%s) " one twoprintf "(%s) " "one two"显示的是args。
注2:每次添加变量时,不需要以双引号结尾。变量在双引号内展开。因此

inputs=()
# using a for loop here

        inputs+=("in=${output_path}/${content_id}_${height}p.mp4,stream=video,output=${packaged_out}/${content_id}_${height}p.mp4")
done

printf "(%s) " "${inputs[@]}"

sudo packager "${inputs[@]}"

(Not这里所有的${...}都是必需的。但是养成每次都使用${...}的习惯可以避免问题,例如对于您的${height}p.mp4:避免将p作为变量名的一部分)

附录:一些实验

要了解此处发生的情况,请参阅

printf "(%s) "  in=1  in=2
#(in=1) (in=2)

input=""
input="$input in=1"
input="$input in=2"
printf "(%s) " "$input"
#( in=1 in=2)

input=""
input="$input in=1"
input="$input in=2"
printf "(%s) " $input
#(in=1) (in=2)
# So, victory? No! see below

input=""
input="$input in=one 1"
input="$input in='two 2'" # in case you expect something in nested quotes
printf "(%s) " "$input" #Nope: ( in=one 1 in='two 2')
printf "(%s) " $input # Even worse: (in=one) (1) (in='two) (2')

# Now arrays
input=()
input+=("in=1")
input+=("in=two 2")
input+=("in='three 3'")
avar="four 4"
input+=("in=${avar}") # Just to check what I say about variable inside double quotes
printf "(%s) " "${input[@]}" # Victory: (in=1) (in=two 2) (in='three 3') (in=four 4)
printf "(%s) " ${input[@]} # Don't forget quotes. (in=1) (in=two) (2) (in='three) (3') (in=four) (4)

编辑

要考虑您对问题的编辑:它应该不会改变什么。故障是什么?你确定它以前不存在,但不能看到它,因为以前的问题现在解决了。
只是为了实验(不使用“打包程序”程序,但再次用printf替换它)

inputs=()
for i in {1..5}
do
   content="content $i"
   height=$((i*100))
   inputs+=("in=indir/${content}_${height}p.mp4,out=out/${content}_${height}p.mp4")
done

key_server=aServer
content_id=123
signer_uname="John Doe"
packaged_out=/home/me/out
printf '(%s) ' sudo packager "${inputs[@]}" \
    --enable_widevine_encryption \
    --key_server_url "${key_server}" \
    --content_id "${content_id}" \
    --signer "${signer_uname}" \
    --mpd_output "${packaged_out}/${content_id}.mpd" \
    --hls_master_playlist_output "${packaged_out}/${content_id}.m3u8"

显示器

(sudo) (packager) (in=indir/content 1_100p.mp4,out=out/content 1_100p.mp4) (in=indir/content 2_200p.mp4,out=out/content 2_200p.mp4) (in=indir/content 3_300p.mp4,out=out/content 3_300p.mp4) (in=indir/content 4_400p.mp4,out=out/content 4_400p.mp4) (in=indir/content 5_500p.mp4,out=out/content 5_500p.mp4) (--enable_widevine_encryption) (--key_server_url) (aServer) (--content_id) (123) (--signer) (John Doe) (--mpd_output) (/home/me/out/123.mpd) (--hls_master_playlist_output) (/home/me/out/123.m3u8)

这正是我们所期望的。

bfhwhh0e

bfhwhh0e2#

好的,我通过从python运行bash命令解决了这个问题(变通方法)。

cmd_prefix = 'sudo packager..'
cmd_postfix = '--mpd_output "${packaged_out}/${content_id}.mpd" --hls_master_playlist_output "${packaged_out}/${content_id}.m3u8"

for inp in inputs
    cmd_prefix += inp

drm_command = cmd_perfix + cmd_postfix

drm_processor_response = Popen(f"({drm_command})", stderr=PIPE, stdout=PIPE, shell=True)
output, errors = drm_processor_response.communicate()
log_update([drm_processor_response.returncode, errors.decode("utf-8"), output.decode("utf-8")])

这是有效的,使用python我有更多的控制。

相关问题