Home > Software engineering >  Python - how to build a multi-list for loop?
Python - how to build a multi-list for loop?

Time:05-20

At my application, I use FFmpeg to pack videos for web delivery in HLS format. During development, I wrote the following for loop in order to create a master.m3u8 playlist. Basically, this is working fine, except of one thing I currently don't understand. How can I make this work exactly the same way if I have multiple video jobs. Meaning, I have one job at position [0] and a second one at [1] ?

for agroup_name, agroup in a_groups.items():
    streaminf = f'#EXT-X-STREAM-INF:BANDWIDTH={int(job["config"]["output_options"]["stream_bandwidth_multiplier"] * (job["video"][0]["bitrate"]   max(audio["bitrate"] for audio in agroup)))}'
    streaminf  = f',RESOLUTION={str(job["video"][0]["width"])}x{str(job["video"][0]["height"])}'
    streaminf  = f',CODECS="{",".join([job["video"][0]["hls"]["codec"], *set(map(lambda x: x["hls"]["codec"], agroup))])}"'
    streaminf  = f',AUDIO="{agroup_name}"'

    if has_subtitles:
        # We expect only one subtitle group -> Will always be [0]
        subtitle_group_name = list(s_groups.values())[0][0]
        streaminf  = f',SUBTITLES="{build_groupname(subtitle_group_name["hls"]["group_id"][0], "subtitle")}"'

    write_file_newlines(file, [
        streaminf,
        build_name(job["video"][0])   "/master.m3u8",
        ""
    ])

Currently, the output look like this:

#EXT-X-STREAM-INF:BANDWIDTH=12238336,RESOLUTION=3840x1606,CODECS="avc1.640033,ac-3",AUDIO="a-0",SUBTITLES="s-0"
v-h264/master.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=11815936,RESOLUTION=3840x1606,CODECS="avc1.640033,mp4a.40.2",AUDIO="a-1",SUBTITLES="s-0"
v-h264/master.m3u8

But in the end it has to look like this. All this information is packed in the video job element:

#EXT-X-STREAM-INF:BANDWIDTH=12238336,RESOLUTION=3840x1606,CODECS="avc1.640033,ac-3",AUDIO="a-0",SUBTITLES="s-0"
v-h264/master.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=11815936,RESOLUTION=3840x1606,CODECS="avc1.640033,mp4a.40.2",AUDIO="a-1",SUBTITLES="s-0"
v-h264/master.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=15238336,RESOLUTION=3840x1606,CODECS="hev1.1.6.L93.B0,ac-3",AUDIO="a-0",SUBTITLES="s-0"
v-hevc/master.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=14815936,RESOLUTION=3840x1606,CODECS="hev1.1.6.L93.B0,mp4a.40.2",AUDIO="a-1",SUBTITLES="s-0"
v-hevc/master.m3u8

So I somehow need to loop over the jobs, but this total makes my mind suffer ^^

Thanks in advance

CodePudding user response:

If position [0] means job["video"][0] and position [1] means job["video"][1] then you should use outer for-loop with for item in job['video']: and later use item instead of job["video"][0]

Something like this:

for item in job['video']:

    for agroup_name, agroup in a_groups.items():
        streaminf = f'#EXT-X-STREAM-INF:BANDWIDTH={int(job["config"]["output_options"]["stream_bandwidth_multiplier"] * (item["bitrate"]   max(audio["bitrate"] for audio in agroup)))}'
        streaminf  = f',RESOLUTION={item["width"]}x{item["height"]}'
        streaminf  = f',CODECS="{",".join([item["hls"]["codec"], *set(map(lambda x: x["hls"]["codec"], agroup))])}"'
        streaminf  = f',AUDIO="{agroup_name}"'
    
        if has_subtitles:
            # We expect only one subtitle group -> Will always be [0]
            subtitle_group_name = list(s_groups.values())[0][0]
            streaminf  = f',SUBTITLES="{build_groupname(subtitle_group_name["hls"]["group_id"][0], "subtitle")}"'
    
        write_file_newlines(file, [
            streaminf,
            build_name(item)   "/master.m3u8",
            ""
        ])

If you use [0] with other variables then you may need for i in range(len(job['video'])): and later use [i] in job['video'][i] and other_variable[i]

  • Related