使用ffmpeg实现cxk和wzl直播连麦打篮球的效果🏀🏀🏀

如果你对开源项目、提升技术、副业、面试、历史、八卦等等感兴趣的,可以加我微信 yunmz777,刚好我们有这样的交流群.

在直播中,连麦功能允许主播与观众或者其他主播进行实时互动,这种互动通常是通过视频或音频完成的。屏幕分屏效果是连麦中的一个重要视觉效果,它允许观众同时看到多个参与者。这种效果不仅增加了直播的互动性,还丰富了观众的观看体验。

屏幕分屏效果通常有几种不同的布局方式:

  1. 平分屏幕:这是最常见的分屏方式,屏幕被平均分成两部分,每个参与者占据一半的屏幕空间。这种方式适用于两个参与者的连麦。

  2. 画中画:在这种布局中,主播的视频画面占据大部分屏幕空间,而连麦的观众或另一个主播的画面则较小,通常出现在屏幕的一角。这种方式允许主画面保持观众的主要注意力,同时也可以看到连麦参与者的反应。

  3. 多分屏:当直播中有多于两个的参与者连麦时,屏幕会被分成多个小画面,每个参与者都有自己的一块区域。这种布局方式适用于团队讨论、多人游戏等场景。

  4. 动态切换:在一些直播平台或软件中,系统可以根据谁在说话来动态切换显示的画面。虽然这种方式在技术上更为复杂,但它能确保观众总是看到当前活跃的讲话者,从而提高直播的参与感和互动性。

那么在接下来的内容中,我们将使用 ffmpeg 实现平分屏幕的效果,也就是说将两个视频合并到一起。

视频高度相同的情况下

视频靠度的相同就是说我们同一台相机拍摄出来的,且都是横拍的那种,除此之外,编码和分辨率都是相同的。

要执行这些命令之前,我们首先要对安装 ffmpeg

js 复制代码
const { spawn } = require("child_process");

const ffmpegCommand = "ffmpeg";
const args = [
  "-i",
  "./m.mp4",
  "-i",
  "./n.mp4",
  "-filter_complex",
  "[0:v][1:v]hstack=inputs=2[v]",
  "-map",
  "[v]",
  "./output.mp4",
];

const process = spawn(ffmpegCommand, args);

process.stdout.on("data", (data) => {
  console.log(`stdout: ${data}`);
});

process.stderr.on("data", (data) => {
  console.error(`stderr: ${data}`);
});

process.on("close", (code) => {
  console.log(`child process exited with code ${code}`);
});

在上面的这段代码中,我们是直接使用了 Node.js 的 child_process 模块来执行 ffmpeg 命令来实现将两个视频文件并排合并成一个新的视频文件。

接下来分别了解一下之后的这些参数都分别代表什么:

  1. i ./m.mp4:指定输入文件 1./m.mp4

  2. -filter_complex "[0:v][1:v]hstack=inputs=2[v]":这是一个复杂过滤器的表达式,用于处理和生成新的视频流。[0:v][1:v] 表示选择第一个和第二个输入文件的视频流。hstack=inputs=2 将这两个视频流并排(水平堆叠)组合成一个视频流。[v]是这个新视频流的标签。

  3. -map "[v]":这个选项用来选择特定的视频流作为输出。在这个例子中,它选择了上面通过 filter_complex 生成的并排视频流。

而最终输出文件的路径和名称为 ./output.mp4

这是我们提前准备好的两个文件,如下图所示:

最终的结果输出了这样的文件内容:

上面的代码,要想将上述的代码中使用的 ffmpeg 命令转换为可以直接在 bash 或终端中执行的命令,你只需要使用 ffmpeg 命令行工具,并应用相同的参数:

bash 复制代码
ffmpeg -i ./m.mp4 -i ./n.mp4 -filter_complex "[0:v][1:v]hstack=inputs=2[v]" -map "[v]" ./output.mp4

视频高度不同的情况下

当使用 ffmpeg 合并两个分辨率和编码不同的视频时报错,通常是因为这些差异导致 ffmpeg 无法直接将视频流合并到一起。具体来说,可能存在以下问题:

  1. 分辨率不一致:当你使用 hstack(水平堆叠)或 vstack(垂直堆叠)等滤镜进行视频合并时,所有视频流需要具有相同的分辨率。如果分辨率不同,ffmpeg 无法对它们进行直接堆叠。

  2. 编码格式不同:虽然不同的编码格式不会直接阻止合并过程,但在最终输出之前,可能需要对视频进行重编码以确保兼容性。如果没有指定合适的编码设置,可能会导致错误或合并后的视频无法正确播放。

要解决这些问题,你可以在合并之前对视频进行预处理,以确保它们具有一致的分辨率和兼容的编码设置。因此我们可以使用 ffmpeg 的 scale 滤镜调整视频的分辨率。

首先我们接下来使用到的是这两个视频,如下:

js 复制代码
const { spawn } = require("child_process");

const ffmpegCommand = "ffmpeg";
const args = [
  "-i",
  "./mm.mp4",
  "-i",
  "./nn.mp4",
  "-filter_complex",
  `[0:v]scale=-2:540[video1]; [1:v]scale=-2:540[video2]; [video1][video2]hstack=inputs=2[video]; [0:a][1:a]amix=inputs=2[audio]`,
  "-map",
  "[video]",
  "-map",
  "[audio]",
  "./mmm.mp4",
];

const process = spawn(ffmpegCommand, args);

process.stdout.on("data", (data) => {
  console.log(`stdout: ${data}`);
});

process.stderr.on("data", (data) => {
  console.error(`stderr: ${data}`);
});

process.on("close", (code) => {
  console.log(`子进程以代码 ${code} 退出`);
});

在上面的这个代码中,我们主要对几个核心的参数来进行讲解:

  1. 过滤器复杂操作(-filter_complex):

    • 0:v\]scale=-2:540\[video1\]; \[1:v\]scale=-2:540\[video2\];:这部分将第一个(\[0:v\])和第二个(\[1:v\])视频的分辨率调整为宽度自动适应、高度为 540 像素,并分别标记为\[video1\]和\[video2\]。

    • 0:a\]\[1:a\]amix=inputs=2\[audio\]:将两个视频的音频流混合成一个音频流,并标记为\[audio\]。

除了使用脚本来执行之外,我们还是可以使用 bash 命令来执行的,如下:

bash 复制代码
ffmpeg -i ./mm.mp4 -i ./nn.mp4 \
-filter_complex "[0:v]scale=-2:540[video1]; [1:v]scale=-2:540[video2]; [video1][video2]hstack=inputs=2[video]; [0:a][1:a]amix=inputs=2[audio]" \
-map "[video]" -map "[audio]" ./mmm.mp4

剩下的那些就是我们之前降到的了,接下来我们看看效果:

现在这样子就实现我们标题中说的直播连麦 pk 的效果了。

总结

通过 ffmpeg 我们可以搞到很多很有趣的东西,别的不说,我写这个文章的时候看到这个视频就一直在笑,可能是我笑点低吧哈哈哈哈哈。

最后分享两个我的两个开源项目,它们分别是:

这两个项目都会一直维护的,如果你也喜欢,欢迎 star 🚗🚗🚗

相关推荐
GISer_Jing1 小时前
前端面试通关:Cesium+Three+React优化+TypeScript实战+ECharts性能方案
前端·react.js·面试
落霞的思绪2 小时前
CSS复习
前端·css
咖啡の猫4 小时前
Shell脚本-for循环应用案例
前端·chrome
uzong6 小时前
面试官:Redis中的 16 库同时发送命令,服务端是串行执行还是并行执行
后端·面试·架构
百万蹄蹄向前冲7 小时前
Trae分析Phaser.js游戏《洋葱头捡星星》
前端·游戏开发·trae
追逐时光者7 小时前
.NET 使用 MethodTimer 进行运行耗时统计提升代码的整洁性与可维护性!
后端·.net
朝阳5817 小时前
在浏览器端使用 xml2js 遇到的报错及解决方法
前端
GIS之路7 小时前
GeoTools 读取影像元数据
前端
ssshooter8 小时前
VSCode 自带的 TS 版本可能跟项目TS 版本不一样
前端·面试·typescript
你的人类朋友8 小时前
【Node.js】什么是Node.js
javascript·后端·node.js