惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
Schneier on Security
The Last Watchdog
The Last Watchdog
Cyberwarzone
Cyberwarzone
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cyber Attacks, Cyber Crime and Cyber Security
L
Lohrmann on Cybersecurity
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 司徒正美
The Cloudflare Blog
V
V2EX
博客园_首页
博客园 - 聂微东
Vercel News
Vercel News
人人都是产品经理
人人都是产品经理
G
GRAHAM CLULEY
T
Tenable Blog
Last Week in AI
Last Week in AI
Y
Y Combinator Blog
L
LINUX DO - 最新话题
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
SecWiki News
SecWiki News
博客园 - 三生石上(FineUI控件)
S
Secure Thoughts
N
News | PayPal Newsroom
T
The Blog of Author Tim Ferriss
The GitHub Blog
The GitHub Blog
T
Troy Hunt's Blog
博客园 - 【当耐特】
Forbes - Security
Forbes - Security
H
Hacker News: Front Page
A
About on SuperTechFans
B
Blog RSS Feed
Engineering at Meta
Engineering at Meta
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
D
DataBreaches.Net
P
Privacy & Cybersecurity Law Blog
Schneier on Security
Schneier on Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Google DeepMind News
Google DeepMind News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Jina AI
Jina AI
D
Docker
P
Proofpoint News Feed

叹世界

优雅地在 Docker 中使用 NGINX 笔笔皆是天意 如何在 Windows 中优雅的使用 sing-box CS182/282A Spring 2023 1/23/23 CS182/282A Spring 2023 1/18/23 二进制中 1 的个数 ——《C/C++ 位运算黑科技 03》 2 的幂次方 ——《C/C++ 位运算黑科技 02》 绝对值 ——《C/C++ 位运算黑科技 01》 可信软件设计实验环境搭建 单周期 CPU 模型机的设计与实现
C++ 调用 ffmpeg 进行 rtmp 推流
Homing So · 2021-09-27 · via 叹世界

Published on

Authors
  • avatar
    Name
    Homing So
    Twitter

效果 🔅

Clion 中演示的效果

Clion 调试效果图

终端中运行也没有问题

终端中运行效果图

思路 💡

通过 fork 一个子进程来调用 ffmpeg 进行推流, 视频帧通过 opencv 来获取, 通过管道传输到子进程, 实现推流

代码 🔨

需要注意的是, 机器上要先安装 ffmpeg, 其次视频的帧率一定要匹配, 否则会出现莫名其妙的问题

#include <csignal>

#include <iostream>

#include <opencv4/opencv2/opencv.hpp>

bool is_running = true;

void on_signal(int) {
  is_running = false;
}

int main() {
  signal(SIGINT, on_signal);
  signal(SIGQUIT, on_signal);
  signal(SIGTERM, on_signal);

  cv::VideoCapture capture(0);
  if (!capture.isOpened()) {
    std::cerr << "Failed to open camera." << std::endl;
    return EXIT_FAILURE;
  }
  capture.set(cv::CAP_PROP_FRAME_WIDTH, 1280);
  capture.set(cv::CAP_PROP_FRAME_HEIGHT, 720);

  std::string rtmp_server_url = "rtmp://localhost:1935/live/test";

  std::stringstream command;
  command << "ffmpeg ";

  // infile options
  command << "-y "  // overwrite output files
          << "-an " // disable audio
          << "-f rawvideo " // force format to rawvideo
          << "-vcodec rawvideo "  // force video rawvideo ('copy' to copy stream)
          << "-pix_fmt bgr24 "  // set pixel format to bgr24
          << "-s 1280x720 "  // set frame size (WxH or abbreviation)
          << "-r 30 "; // set frame rate (Hz value, fraction or abbreviation)

  command << "-i - "; //

  // outfile options
  command << "-c:v libx264 "  // Hyper fast Audio and Video encoder
          << "-pix_fmt yuv420p "  // set pixel format to yuv420p
          << "-preset ultrafast " // set the libx264 encoding preset to ultrafast
          << "-f flv " // force format to flv
          << rtmp_server_url;

  cv::Mat frame;

  FILE *fp = nullptr;
  fp = popen(command.str().c_str(), "w");

  if (fp != nullptr) {
    while (is_running) {
      capture >> frame;
      if (frame.empty()) {
        continue;
      }

      fwrite(frame.data, sizeof(char), frame.total() * frame.elemSize(), fp);
    }
    pclose(fp);
    return EXIT_SUCCESS;
  } else {
    return EXIT_FAILURE;
  }
}
cmake_minimum_required(VERSION 3.20)
project(rtmp_test)

set(CMAKE_CXX_STANDARD 20)

find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

if (CMAKE_BUILD_TYPE STREQUAL Debug)
    ADD_DEFINITIONS(-DDEBUG)
    message(STATUS "CMake Build Type: Debug")
    message("")
elseif (CMAKE_BUILD_TYPE STREQUAL Release)
    message(STATUS "CMake Build Type: Release")
    message("")
endif ()

file(GLOB ProjectSRC
        "*.cc")

add_executable(${PROJECT_NAME} ${ProjectSRC})
target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS})