Выполнение сценария оболочки в Google Cloud Functions - PullRequest
0 голосов
/ 09 июля 2020

Я пытаюсь кодировать видео .mp4 в hls с помощью FFmpeg.

Я использую subprocess для вызова FFmpeg:

def transcoder(data, context):
    """Background Cloud Function to be triggered by Cloud Storage.
       This generic function logs relevant data when a file is changed.

    Args:
        data (dict): The Cloud Functions event payload.
        context (google.cloud.functions.Context): Metadata of triggering event.
    Returns:
        None; the output is written to Stackdriver Logging
    """
    try:
        input_filename = data['name'].split('/')[-1] #videos have no extension
        input_path = f'/tmp/{input_filename}'
        print(f'filename {input_filename}')
        print(f'input_path {input_path}')
        print(f"bucket {data['bucket']}")
        print(f"name {data['name']}")

        outdir_path = f'/tmp/output/{input_filename}'
        os.makedirs(outdir_path, exist_ok=True)

        bucket = client.get_bucket(data['bucket'])
        blob = bucket.get_blob(data['name'])
        blob.download_to_filename(input_path)

        cmd = f'''ffmpeg -y -i {input_path} \
              -preset ultrafast -g 60 -sc_threshold 0 \
              -map 0:0 -map 0:1 -map 0:0 -map 0:1 \
              -s:v:0 360x640 -c:v:0 libx264 -b:v:0 365k \
              -s:v:1 720x1280 -c:v:1 libx264 -b:v:1 3000k \
              -c:a copy \
              -var_stream_map "v:0,a:0 v:1,a:1" \
              -master_pl_name master.m3u8 \
              -f hls -hls_time 6 -hls_list_size 0 \
              -hls_segment_filename "{outdir_path}/%v_fileSequence%d.ts" \
              -hls_playlist_type vod \
               {outdir_path}/%v_prog_index.m3u8'''

        process = subprocess.Popen(cmd)
        stdout, stderr = process.communicate()
        upload_local_directory_to_gcs(outdir_path, upload_bucket, input_filename)
    except Exception as e:
        print(e)

Проблема в том, что я получаю сообщение об ошибке:

[Errno 2] No such file or directory: 'ffmpeg -y -i /tmp/video -preset ultrafast -g 60 -sc_threshold 0 -map 0:0 -map 0:1 -map 0:0 -map 0:1 -s:v:0 360x640 -c:v:0 libx264 -b:v:0 365k -s:v:1 720x1280 -c:v:1 libx264 -b:v:1 3000k -c:a copy -var_stream_map "v:0,a:0 v:1,a:1" -master_pl_name master.m3u8 -f hls -hls_time 6 -hls_list_size 0 -hls_segment_filename "/tmp/output/video/%v_fileSequence%d.ts" -hls_playlist_type vod /tmp/output/video/%v_prog_index.m3u8': 'ffmpeg -y -i /tmp/video -preset ultrafast -g 60 -sc_threshold 0 -map 0:0 -map 0:1 -map 0:0 -map 0:1 -s:v:0 360x640 -c:v:0 libx264 -b:v:0 365k -s:v:1 720x1280 -c:v:1 libx264 -b:v:1 3000k -c:a copy -var_stream_map "v:0,a:0 v:1,a:1" -master_pl_name master.m3u8 -f hls -hls_time 6 -hls_list_size 0 -hls_segment_filename "/tmp/output/video/%v_fileSequence%d.ts" -hls_playlist_type vod /tmp/output/video/%v_prog_index.m3u8'

Но я знаю, что входные и выходные файлы существуют, потому что я отлаживал это с помощью print(os.listdir(path)), поэтому теперь мне интересно, имеет ли FFmpeg, который я вызываю с подпроцессом, доступ к папке / tmp. .?

Я знаю, что есть библиотека Python FFmpeg, которую я мог бы использовать, но я не знаю, как запустить мою команду FFmpeg, используя эту библиотеку. Можете ли вы помочь?

ps Я могу успешно запустить это локально.

1 Ответ

2 голосов
/ 09 июля 2020

Эта ошибка возникает из-за того, что вы должны разделить вашу команду. документы подпроцесса

from subprocess import Popen

# working fine
Popen('ffmpeg')

# crashing
Popen('ffmpeg -h')

# working fine
Popen('ffmpeg -h'.split())

Будьте осторожны, "v:0,a:0 v:1,a:1" это не будет проанализировано должным образом, вам нужно будет разделить команду вручную.

...