吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 320|回复: 8
收起左侧

[经验求助] ffmpeg 如何传入二进制合并输出视频

[复制链接]
xiaopacI 发表于 2024-10-19 21:21
200吾爱币
事情是这样的我在Python代码中requests获取到的音频与视频文件,但是我不想分别保存成文件在进行调用ffmpeg合并,
这是我保存文件的代码
with open('aaa.mp4', 'wb') as f:
    f.write(video_resp)
    f.close()
with open('aaa.mp3'.format(_id), 'wb') as f:
    f.write(audio_resp)
    f.close()

下面这是保存成文件后的合并代码

ffmpeg -i aaa.mp4 -i aaa.mp3 -vcodec copy -acodec copy -y -strict experimental bbb.mp4
但是我想尽量减少对磁盘的读写,所以想寻找大佬们有没有什么方法,可以直接将音频与视频的字节流合并成视频

最佳答案

查看完整内容

如下代码,似乎是无临时文件生成的。 虽然跑通了,可以创建出目标视频文件,但是不能正常观看,全是噪点和白噪音。 我不懂编码,不能排查错误所在,如果楼主解决了,请回复赐教。 [mw_shl_code=python,true]import ffmpeg # pip3 install ffmpeg-python import requests import subprocess video_stream = ffmpeg.input('pipe:', format='rawvideo', pixel_format='rgb24', s='640x480' ) audio_stream = ffmpeg.input('p ...

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

vigiles 发表于 2024-10-19 21:21
本帖最后由 vigiles 于 2024-10-20 22:46 编辑

如下代码,似乎是无临时文件生成的。
虽然跑通了,可以创建出目标视频文件,但是不能正常观看,全是噪点和白噪音。
我不懂编码,不能排查错误所在,如果楼主解决了,请回复赐教。
[Python] 纯文本查看 复制代码
import ffmpeg # pip3 install ffmpeg-python
import requests
import subprocess

video_stream = ffmpeg.input('pipe:', format='rawvideo', pixel_format='rgb24', s='640x480' )
audio_stream = ffmpeg.input('pipe:', format='s16le')
output_stream = ffmpeg.output(video_stream, audio_stream, 'output.mp4')
ffmpeg_cmd = ffmpeg.compile(output_stream)

video_url = 'http://localhost:8080/ov.mp4'
audio_url = 'http://localhost:8080/oa.mp3'
video_response = requests.get(video_url).content 
audio_response = requests.get(audio_url).content

proc = subprocess.Popen(ffmpeg_cmd, stdin=subprocess.PIPE)
proc.stdin.write(video_response)
proc.stdin.write(audio_response)
proc.stdin.close()
proc.wait()
if proc.returncode != 0:
    raise Exception('FFmpeg进程错误结束')
print('音视频合并完成,输出文件为output.mp4')
silartsua 发表于 2024-10-20 09:42

直接在内存中处理音频和视频的字节流?通过 ffmpegstdin 来处理字节流输入,就不需要保存到磁盘上。

import subprocess
import requests

# 假设 video_resp 和 audio_resp 是通过 requests 获取的字节流
video_resp = requests.get("视频URL").content
audio_resp = requests.get("音频URL").content

# 使用 subprocess 通过管道方式传递音频和视频数据给 ffmpeg
ffmpeg_cmd = [
    'ffmpeg',
    '-i', 'pipe:0',  # 视频流通过stdin传入
    '-i', 'pipe:1',  # 音频流通过stdin传入
    '-vcodec', 'copy',
    '-acodec', 'copy',
    '-y', 'bbb.mp4'  # 输出的合并视频
]

# 使用 subprocess Popen 启动 ffmpeg
process = subprocess.Popen(ffmpeg_cmd, stdin=subprocess.PIPE)

# 将音频和视频数据通过 stdin 写入 ffmpeg
process.stdin.write(video_resp)
process.stdin.write(audio_resp)

# 关闭管道并等待进程完成
process.stdin.close()
process.wait()

print("音视频合并完成")

pipe:0pipe:1 分别代表通过标准输入(stdin)传入的视频和音频流。
subprocess.Popen 启动了 ffmpeg 进程并使用 stdin 管道来将音视频数据传入 ffmpeg 进行处理。
最后,bbb.mp4 会是音视频合并后的文件。

 楼主| xiaopacI 发表于 2024-10-20 11:46
silartsua 发表于 2024-10-20 09:42
[md]直接在内存中处理音频和视频的字节流?通过 `ffmpeg` 的 `stdin` 来处理字节流输入,就不需要保存到磁 ...

对的,您理解的很对,但是我尝试使用过此方法,会在第一次写入视频的时候报错:
报错内容如下:
ffmpeg version N-117612-gc98810ab47-20241018 Copyright (c) 2000-2024 the FFmpeg developers
  built with gcc 14.2.0 (crosstool-NG 1.26.0.120_4d36f27)
  configuration: --prefix=/ffbuild/prefix --pkg-config-flags=--static --pkg-config=pkg-config --cross-prefix=x86_64-w64-mingw32- --arch=x86_64 --target-os=mingw32 --enable-gpl --enable-version3 --disable-debug --enable-shared --disable-static --disable-w32threads --enable-pthreads --enable-iconv --enable-zlib --enable-libfreetype --enable-libfribidi --enable-gmp --enable-libxml2 --enable-lzma --enable-fontconfig --enable-libharfbuzz --enable-libvorbis --enable-opencl --disable-libpulse --enable-libvmaf --disable-libxcb --disable-xlib --enable-amf --enable-libaom --enable-libaribb24 --enable-avisynth --enable-chromaprint --enable-libdav1d --enable-libdavs2 --enable-libdvdread --enable-libdvdnav --disable-libfdk-aac --enable-ffnvcodec --enable-cuda-llvm --enable-frei0r --enable-libgme --enable-libkvazaar --enable-libaribcaption --enable-libass --enable-libbluray --enable-libjxl --enable-libmp3lame --enable-libopus --enable-librist --enable-libssh --enable-libtheora --enable-libvpx --enable-libwebp --enable-libzmq --enable-lv2 --enable-libvpl --enable-openal --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopenmpt --enable-librav1e --enable-librubberband --enable-schannel --enable-sdl2 --enable-libsoxr --enable-libsrt --enable-libsvtav1 --enable-libtwolame --enable-libuavs3d --disable-libdrm --enable-vaapi --enable-libvidstab --enable-vulkan --enable-libshaderc --enable-libplacebo --enable-libvvenc --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libzimg --enable-libzvbi --extra-cflags=-DLIBTWOLAME_STATIC --extra-cxxflags= --extra-libs=-lgomp --extra-ldflags=-pthread --extra-ldexeflags= --cc=x86_64-w64-mingw32-gcc --cxx=x86_64-w64-mingw32-g++ --ar=x86_64-w64-mingw32-gcc-ar --ranlib=x86_64-w64-mingw32-gcc-ranlib --nm=x86_64-w64-mingw32-gcc-nm --extra-version=20241018
  libavutil      59. 44.100 / 59. 44.100
  libavcodec     61. 22.100 / 61. 22.100
  libavformat    61.  9.100 / 61.  9.100
  libavdevice    61.  4.100 / 61.  4.100
  libavfilter    10.  6.100 / 10.  6.100
  libswscale      8.  6.100 /  8.  6.100
  libswresample   5.  4.100 /  5.  4.100
  libpostproc    58.  4.100 / 58.  4.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'pipe:0':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2mp41iso5
    encoder         : Lavf59.27.100
    description     : Packed by XCoder v2.0.2
  Duration: 00:03:59.83, start: 0.033000, bitrate: N/A
  Stream #0:0[0x1](und): Video: hevc (Main) (hev1 / 0x31766568), yuv420p(tv, bt709), 1080x1920 [SAR 1:1 DAR 9:16], 333 kb/s, 30 fps, 30 tbr, 16k tbn (default)
    Metadata:
      handler_name    : Bento4 Video Handler
      vendor_id       : [0][0][0][0]
[in#1 @ 000001608d6972c0] Error opening input: Bad file descriptor
Error opening input file pipe:1.
Error opening input files: Bad file descriptor
vigiles 发表于 2024-10-20 13:49
本帖最后由 vigiles 于 2024-10-20 13:50 编辑

尝试了多种问法,从百度ai上得到的几种答案,包括mmap、FIFOs、等等,筛选了下——总之吧,我这里没有网络的独立video和audio,所以没有测试。楼主试过后回复我一下是否成功
[Python] 纯文本查看 复制代码
import ffmpeg # pip3 install ffmpeg-python
import requests
import io

# 假设 video_url 和 audio_url 是您的视频和音频URL
video_url = "视频URL"
audio_url = "音频URL"

# 使用requests获取视频和音频的字节流
video_response = requests.get(video_url)
audio_response = requests.get(audio_url)

# 将字节流转换为BytesIO对象,以便ffmpeg-python可以处理
video_stream = io.BytesIO(video_response.content)
audio_stream = io.BytesIO(audio_response.content)

# 使用ffmpeg-python合并音频和视频
# 注意:这里假设视频和音频流已经是兼容的格式和编码
# 如果不是,您可能需要先对它们进行转码或处理
output_stream = io.BytesIO()

# 创建ffmpeg输入流
video_input = ffmpeg.input('pipe:', format='mp4')
audio_input = ffmpeg.input('pipe:', format='mp3')

# 创建ffmpeg输出流,并指定不重新编码(如果格式和编码兼容)
output = ffmpeg.output(video_input, audio_input, 'pipe:', vcodec='copy', acodec='copy')

# 运行ffmpeg命令,将输出写入output_stream
ffmpeg.run(output, pipe_stdin=True, pipe_stdout=output_stream)

# 将合并后的数据保存到文件(如果需要)
# 或者直接处理output_stream中的内容
with open('output.mp4', 'wb') as f:
    f.write(output_stream.getvalue())

# 打印完成信息
print("音视频合并完成") 
grekevin 发表于 2024-10-20 14:07
使用临时文件的方式可以实现,但是会增加读写磁盘的次数
[Python] 纯文本查看 复制代码
import subprocess
import os

# 假设 video_resp 和 audio_resp 是你通过 requests 获取到的字节流
video_resp = b'...'  # 视频字节流
audio_resp = b'...'  # 音频字节流

# 创建两个子进程来分别处理视频和音频流
video_process = subprocess.Popen(
    ['ffmpeg', '-f', 'mp4', '-i', 'pipe:0', '-vcodec', 'copy', '-y', 'temp_video.mp4'],
    stdin=subprocess.PIPE
)
audio_process = subprocess.Popen(
    ['ffmpeg', '-f', 'mp3', '-i', 'pipe:0', '-acodec', 'copy', '-y', 'temp_audio.mp3'],
    stdin=subprocess.PIPE
)

# 将视频和音频字节流分别写入子进程的 stdin
video_process.stdin.write(video_resp)
video_process.stdin.close()
audio_process.stdin.write(audio_resp)
audio_process.stdin.close()

# 等待子进程完成
video_process.wait()
audio_process.wait()

# 合并视频和音频
merge_process = subprocess.Popen(
    ['ffmpeg', '-i', 'temp_video.mp4', '-i', 'temp_audio.mp3', '-vcodec', 'copy', '-acodec', 'copy', '-y', 'video_with_audio.mp4']
)
merge_process.wait()

# 删除临时文件
os.remove('temp_video.mp4')
os.remove('temp_audio.mp3')

 楼主| xiaopacI 发表于 2024-10-20 17:01
vigiles 发表于 2024-10-20 13:49
尝试了多种问法,从百度ai上得到的几种答案,包括mmap、FIFOs、等等,筛选了下——总之吧,我这里没有网络 ...

video_stream 与audio_stream 貌似没有被引用吧
 楼主| xiaopacI 发表于 2024-10-20 17:02
grekevin 发表于 2024-10-20 14:07
使用临时文件的方式可以实现,但是会增加读写磁盘的次数
[mw_shl_code=python,true]import subprocess
im ...

请阅读完正文,主要是想减少磁盘读写
 楼主| xiaopacI 发表于 2024-10-21 16:59
vigiles 发表于 2024-10-20 22:45
如下代码,似乎是无临时文件生成的。
虽然跑通了,可以创建出目标视频文件,但是不能正常观看,全是噪点和 ...

您是对的,这样貌似确实能生成视频了,您提到的噪点与白噪音可能是视频源编码信息与您设定的视频编码格式不匹配所造成的
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-15 15:01

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表