BMF 框架:多媒体处理的强大利器 | 社区征文

BMF

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

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

BabitMF

picture.image

上图是 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或安装指南进行编译和安装。

picture.image

下载 Python 源代码

 bashCopy codecd /opt
 wget https://www.python.org/ftp/python/3.9.13/Python-3.9.13.tgz
 tar xvf Python-3.9.13.tgz
 cd 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 graph
 graph = bmf.graph()
 ​
 # decode
 video = 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 模块。最终效果如下图所示,左侧是原始视频,右侧是彩色视频。

picture.image

环境设置,下载预训练权重,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

picture.image

picture.image

 import sys
 ​
 sys.path.insert(0, '/content/DeOldify')
 ​
 print(sys.path)
 %%file py_deoldify_module.py
 ​
 import bmf
 import numpy as np
 from bmf import ProcessResult, Packet, Timestamp, VideoFrame
 import PIL
 import bmf.hml.hmp as mp
 ​
 from deoldify import device
 from deoldify.device_id import DeviceId
 import torch
 from 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

picture.image


使用体验

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

  • 多媒体处理全面涵盖:BMF 提供了丰富的多媒体处理功能,涵盖了视频、音频和图像的各个方面。从简单的转码到复杂的编辑管道,再到人工智能推理,BMF 提供了全面而完善的解决方案,使其成为一个多才多艺的多媒体处理框架。
  • 模块化设计:BMF 的模块化设计让用户能够轻松地构建复杂的处理管道。通过组合不同的模块,用户可以实现各种定制化的处理流程,从而满足不同项目的需求。这种模块化的设计也促进了代码的可重用性,提高了开发效率。
  • 多语言支持:BMF 支持多语言编程,包括 Python、Go、C++ 等,使得开发者可以根据自己的偏好和项目需求选择适合的编程语言。这种灵活性有助于提高团队的协作效率,同时也扩大了 BMF 的用户群体。

THE end

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

infoQ社区链接:https://xie.infoq.cn/article/ce636a7697e0aa6f53db17bc2

0
0
0
0
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论