写点什么

BMF 框架:多媒体处理的强大利器

作者:RoSofteg
  • 2023-12-30
    广东
  • 本文字数:4732 字

    阅读完需:约 16 分钟

BabitMF(Babit Multimedia Framework,BMF),作为一个通用的多媒体处理框架,能够提供简单易用的跨语言接口、灵活的调度和可扩展性,以及以模块化的方式动态扩展、管理和复用视频处理的原子能力。BMF 以 graph/pipeline 的形式构建多媒体处理链路,或通过直接调用各个处理能力实现项目集成,帮助多媒体用户在各类生产环境中方便、高效地实施项目。BMF 的使用场景涵盖视频转码、视频帧提取、视频增强、视频分析、视频帧插入、视频编辑、视频会议以及 VR 等。目前,BMF 每天处理的视频数以亿计。在此过程中,BMF 框架的功能多样性、易用性、兼容性和稳定性得到了充分的打磨。

链接:https://github.com/BabitMF/bmf

BabitMF



上图是 BMF 的概要架构图,包括一整套的生态体系,主要由三部分组成:

  • 应用层:顶层为用户提供多语言的 API 包括 Python、Go、C++,方便用户根据不同的项目需求进行开发集成。

  • 框架层:中间层包括框架的 graph/pipeline 调度,跨数据类型跨设备的数据流转 Backend,以及常用的跨设备 reformat、color space conversion、tensor 算子等 SDK。

  • 模块层:包含具有各种原子能力的模块,提供多语言模块开发机制。用户可以根据自身需求将算法/处理实现为 Python、Go、C++ 语言的任意一种。


BMF 的安装部署指南

安装方式选择————》》》

  • pip 安装: 使用 Python 的包管理工具 pip 进行安装。这是最简单的安装方式之一。

  • Docker 安装: 利用 Docker 容器进行 BMF 的安装,提供了一种轻量、可移植的部署方案。

  • 预编译二进制文件: 使用预编译的二进制文件,适用于各种操作系统。

  • 源代码构建: 从源代码编译安装,适用于需要定制化配置的情况。

依赖————》》》

  • 常规依赖: 安装系统所需的所有 package,可以使用 apt、yum 或 brew 进行安装。

  • Python 依赖: 如果您使用 Python API 或通过预编译安装包调用 Python 模块,需要安装 Python,要求版本在 Mac ARM 为 3.9 以上,Linux 和 Windows 为 3.7 以上。

  • FFmpeg 依赖: BMF 目前支持 4.2 - 5.1 版本的 FFmpeg,您可以使用系统的 package 管理器安装。对于 ubuntu、debian、CentOS:8 和 macOS,可以直接使用系统提供的安装方式。

安装步骤————》》

  • pip 安装: 使用pip install BMF进行安装,确保您的 Python 版本满足要求。

  • Docker 安装: 利用 Docker 容器,您可以使用 Docker Hub 上的 BMF 镜像,通过docker pull获取镜像并运行容器。

  • 预编译二进制文件: 下载适用于您操作系统的预编译二进制文件,并按照说明进行安装。

  • 源代码构建: 从 BMF 的源代码中构建安装,首先获取源代码,然后按照 README 或安装指南进行编译和安装。

下载 Python 源代码

bashCopy codecd /optwget https://www.python.org/ftp/python/3.9.13/Python-3.9.13.tgztar xvf Python-3.9.13.tgzcd Python-3.9.13
复制代码

这将下载 Python 3.9.13 版本的源代码并解压缩到指定目录。

配置编译选项

在进入 Python 源代码目录后,执行以下命令来配置编译选项:

bashCopy codesudo ./configure --enable-optimizations
复制代码

这将根据您的系统和需求配置 Python 编译选项。--enable-optimizations选项会在编译过程中应用一些优化。

编译

配置完成后,使用以下命令进行编译:

bashCopy codesudo make altinstall
复制代码

这将启动编译过程。请注意,使用 make altinstall 而不是 make install,是为了避免与系统默认的 Python 版本发生冲突。altinstall 将安装 Python 到一个版本特定的目录,而不是默认的 /usr/local/bin 目录。

验证安装

编译完成后,可以使用以下命令验证 Python 是否成功安装:

bashCopy codepython3.9.13 --version
复制代码

这应该输出 Python 3.9.13 的版本信息,证明编译安装成功。

设置环境变量

如果您希望新编译的 Python 版本成为系统默认的 Python 版本,可以考虑设置相应的环境变量。例如,在 .bashrc.zshrc 文件中添加以下行:

bashCopy codeexport PATH="/opt/Python-3.9.13/bin:$PATH"
复制代码



BMF 的基本使用

转码

使用 BMF 以及如何使用 FFmpeg 兼容选项来实现所需的功能。使用 BMF 在转码时需要 FFmpeg 4.x 或 5.x,通过 apt 检查版本,如果版本符合要求,通过 apt 安装 ffmpeg,否则,就需要从源码编译 ffmpeg。

! apt show ffmpeg | grep "^Package:\|^Version:"! apt install -y ffmpeg! git clone https://github.com/BabitMF/bmf bmf! ./bmf/scripts/build_ffmpeg.sh nasm yasm x264 x265
复制代码

BMF 的安装:

! pip3 install BabitMF
复制代码

下载我们将使用的视频文件:

! gdown --fuzzy https://drive.google.com/file/d/1l8bDSrWn6643aDhyaocVStXdoUbVC3o2/view?usp=sharing -O big_bunny_10s_30fps.mp4
! ffprobe big_bunny_10s_30fps.mp4
复制代码

然后进行视频转码

import bmf
input_video_path = "./big_bunny_10s_30fps.mp4"output_path = "./remux_output.m3u8"
# create graphgraph = bmf.graph()
# decodevideo = graph.decode({ "input_path": input_video_path, "video_codec": "copy", "audio_codec": "copy"})
( bmf.encode( video['video'], video['audio'], { "output_path": output_path, "format": "hls", "mux_params": { "hls_list_size": "0", "hls_time": "2", "hls_segment_filename": "./file%03d.ts" } } ).run())
复制代码

AI 推理

此演示展示了如何将最先进的 AI 算法集成到 BMF 视频处理管道中。著名的开源着色算法 DeOldify 被包装成一个 BMF pyhton 模块。最终效果如下图所示,左侧是原始视频,右侧是彩色视频。



环境设置,下载预训练权重,pip 安装 BMF 包,BMF 框架利用 FFmpeg 视频解码器和编码器作为视频解码和编码的内置模块。在使用 BMF 之前,用户必须安装受支持的 FFmpeg 库。

!git clone https://github.com/eefengwei/DeOldify.git DeOldify
!pip3 install -r ./DeOldify/requirements-colab.txt
!mkdir -p ./DeOldify/models
!wget -c https://data.deepai.org/deoldify/ColorizeVideo_gen.pth -O ./DeOldify/models/ColorizeVideo_gen.pth
!pip install BabitMF-GPU
!sudo apt install ffmpeg
!dpkg -l | grep -i ffmpeg
!pip install wurlitzer
%load_ext wurlitzer
复制代码




import sys
sys.path.insert(0, '/content/DeOldify')
print(sys.path)%%file py_deoldify_module.py
import bmfimport numpy as npfrom bmf import ProcessResult, Packet, Timestamp, VideoFrameimport PILimport bmf.hml.hmp as mp
from deoldify import devicefrom deoldify.device_id import DeviceIdimport torchfrom deoldify.visualize import *import warnings
debug = False
class py_deoldify_module(bmf.Module): def __init__(self, node, option=None): print(f'py_deoldify_module init ...') self.node_ = node self.option_ = option print(option) warnings.filterwarnings("ignore", category=UserWarning, message=".*?Your .*? set is empty.*?")
#NOTE: This must be the first call in order to work properly! #choices: CPU, GPU0...GPU7 device.set(device=DeviceId.GPU0)
if not torch.cuda.is_available(): print('warning: GPU is not available, the computation is going to be very slow...')
weight_path=Path('/content/DeOldify') if option and 'model_path' in option.keys(): model_path = option['model_path'] if not model_path: print(f'model_path={model_path}') weight_path=Path(model_path)
self.colorizer = get_stable_video_colorizer(weight_path) self.idx = 0
print(f'py_deoldify_module init successfully...')

def process(self, task): # iterate through all input queues to the module idx = self.idx
for (input_id, input_queue) in task.get_inputs().items(): # get output queue output_queue = task.get_outputs()[input_id]
while not input_queue.empty(): # get the earliest packet from queue packet = input_queue.get()
# handle EOF if packet.timestamp == Timestamp.EOF: output_queue.put(Packet.generate_eof_packet()) task.timestamp = Timestamp.DONE
# process packet if not empty if packet.timestamp != Timestamp.UNSET and packet.is_(VideoFrame):
vf = packet.get(VideoFrame) rgb = mp.PixelInfo(mp.kPF_RGB24) np_vf = vf.reformat(rgb).frame().plane(0).numpy()
# numpy to PIL image = Image.fromarray(np_vf.astype('uint8'), 'RGB')
colored_image = self.colorizer.colorize_single_frame_from_image(image)
if not colored_image: print(f'Fail to process the input image with idx = {idx}') continue
if debug: input_name = f'video/bmf_raw/frame_{idx}.png' print(f'input_name = {input_name}') image.save(input_name)
output_name = f'video/bmf_out/frame_{idx}.png' print(f'output_name = {output_name}') colored_image.save(output_name)
self.idx = idx + 1 out_frame_np = np.array(colored_image) rgb = mp.PixelInfo(mp.kPF_RGB24) frame = mp.Frame(mp.from_numpy(out_frame_np), rgb)
out_frame = VideoFrame(frame) out_frame.pts = vf.pts out_frame.time_base = vf.time_base
pkt = Packet(out_frame) pkt.timestamp = out_frame.pts
output_queue.put(pkt)

return ProcessResult.OK
复制代码




使用体验

总体来说,使用起来还是十分丝滑的。

  • 多媒体处理全面涵盖:BMF 提供了丰富的多媒体处理功能,涵盖了视频、音频和图像的各个方面。从简单的转码到复杂的编辑管道,再到人工智能推理,BMF 提供了全面而完善的解决方案,使其成为一个多才多艺的多媒体处理框架。

  • 模块化设计:BMF 的模块化设计让用户能够轻松地构建复杂的处理管道。通过组合不同的模块,用户可以实现各种定制化的处理流程,从而满足不同项目的需求。这种模块化的设计也促进了代码的可重用性,提高了开发效率。

  • 多语言支持:BMF 支持多语言编程,包括 Python、Go、C++ 等,使得开发者可以根据自己的偏好和项目需求选择适合的编程语言。这种灵活性有助于提高团队的协作效率,同时也扩大了 BMF 的用户群体。


THE end

BMF 作为一款多媒体处理框架,在其全面的功能和灵活的设计中体现了强大的潜力。尽管在使用过程中遇到了一些挑战,但其优点仍然让我对这个框架抱有信心。通过不断的学习和实践,我相信 BMF 将为多媒体领域的开发者提供更多可能性。

发布于: 27 分钟前阅读数: 8
用户头像

RoSofteg

关注

还未添加个人签名 2023-12-11 加入

还未添加个人简介

评论

发布
暂无评论
BMF 框架:多媒体处理的强大利器_BMF_RoSofteg_InfoQ写作社区
vConsole