Python 在Google云函数上执行shell脚本

Python 在Google云函数上执行shell脚本,python,ffmpeg,google-cloud-functions,Python,Ffmpeg,Google Cloud Functions,我正在尝试使用FFmpeg将.mp4视频编码到hls中 我正在使用子流程调用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:

我正在尝试使用FFmpeg将.mp4视频编码到hls中

我正在使用
子流程
调用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))
调试了它们,所以现在我想知道我用subprocess调用的FFmpeg是否可以访问/tmp文件夹

我知道我可以使用Python FFmpeg库,但我不知道如何使用该库运行我的FFmpeg命令。你能帮忙吗


p、 我可以在本地成功运行此命令。

发生此错误是因为您应该拆分命令

从子流程导入Popen
#工作正常
Popen('ffmpeg')
#崩溃
Popen('ffmpeg-h')
#工作正常
Popen('ffmpeg-h'.split())

小心,
“v:0,a:0 v:1,a:1”
这不会按预期进行分析,您需要手动拆分命令。

发生此错误是因为您应该拆分命令

从子流程导入Popen
#工作正常
Popen('ffmpeg')
#崩溃
Popen('ffmpeg-h')
#工作正常
Popen('ffmpeg-h'.split())

小心,
“v:0,a:0 v:1,a:1”
这将无法按预期进行分析,您需要手动拆分该命令。

我可以在本地成功运行该命令。所以问题在于在google云函数上运行它。我很确定这是GCF中的问题,因为错误是
[Errno 2]没有这样的文件或目录
,这意味着python有错误,而不是ffmpeg。在ffmpeg
的情况下,没有这样的文件错误
,错误将以字节的形式出现在stderr中。啊,可能是!GCP是unix,我在本地使用Windows。我要试试看!thanksI可以在本地成功运行此命令。所以问题在于在google云函数上运行它。我很确定这是GCF中的问题,因为错误是
[Errno 2]没有这样的文件或目录
,这意味着python有错误,而不是ffmpeg。在ffmpeg
的情况下,没有这样的文件错误
,错误将以字节的形式出现在stderr中。啊,可能是!GCP是unix,我在本地使用Windows。我要试试看!感谢不要忘记像这样管道
stderr
stdout
process=subprocess.Popen(cmd,stdout=subprocess.pipe,stderr=subprocess.pipe)
。如果不执行此操作,则stderr和stdout将始终为空。不要忘记像这样管道
stderr
stdout
(cmd,stdout=subprocess.pipe,stderr=subprocess.pipe)。如果不执行此操作,则stderr和stdout将始终为null。