使用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]。

    • [video1][video2]hstack=inputs=2[video];:将调整分辨率后的两个视频水平堆叠成一个视频流,并标记为[video]。

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

  2. 映射输出流(-map):map "[video]"-map "[audio]" 这些选项指定了 ffmpeg 应该使用哪些处理过的流作为最终输出的视频和音频流。

除了使用脚本来执行之外,我们还是可以使用 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 🚗🚗🚗

相关推荐
路在脚下@1 分钟前
Spring如何处理循环依赖
java·后端·spring
小白学前端66638 分钟前
React Router 深入指南:从入门到进阶
前端·react.js·react
海绵波波1071 小时前
flask后端开发(1):第一个Flask项目
后端·python·flask
web130933203981 小时前
前端下载后端文件流,文件可以下载,但是打不开,显示“文件已损坏”的问题分析与解决方案
前端
outstanding木槿1 小时前
react+antd的Table组件编辑单元格
前端·javascript·react.js·前端框架
好名字08212 小时前
前端取Content-Disposition中的filename字段与解码(vue)
前端·javascript·vue.js·前端框架
隐形喷火龙2 小时前
element ui--下拉根据拼音首字母过滤
前端·vue.js·ui
m0_748241122 小时前
Selenium之Web元素定位
前端·selenium·测试工具
风无雨2 小时前
react杂乱笔记(一)
前端·笔记·react.js
前端小魔女2 小时前
2024-我赚到自媒体第一桶金
前端·rust