[python][ubuntu]opencv读取rtsp图像处理后推流rtmp Windows10下搭建nginx-rtmp流媒体服务器
参考上述链接解决环境等问题 自行替换代码中的rtsp、rtmp地址和ffmpeg位置 样例代码设置流的分辨率为1280x720、30帧,亦可执行替换 推流之后可使用potplayer等播放器打开rtmpUrl来获取流,也可通过opencv获取流并播放
#include <iostream>
#include <vector>
#include <string>
#include <opencv2/opencv.hpp>
#include <windows.h>
using namespace std;
using namespace cv;
const char* rtspUrl = "rtsp://admin:lj123456@192.168.1.64:554/h264/ch1/main/av_stream";
const char* rtmpUrl = "rtmp://localhost:1900/live/test";
const char* ffmpegPath = R"(D:\dependency\ffmpeg-4.4.1-full_build\bin\ffmpeg.exe)";
Size streamSize = { 1280,720 };
string join(const vector<string>& sequence, const string& separator)
{
std::string result;
for (size_t i = 0; i < sequence.size(); ++i)
result += sequence[i] + ((i != sequence.size() - 1) ? separator : "");
return result;
}
void videoTest() {
VideoCapture cap(rtspUrl);
vector<string> arguments = {
ffmpegPath,
"-y", "-an",
"-f", "rawvideo",
"-vcodec", "rawvideo",
"-pix_fmt", "bgr24",
"-s", "1280x720",
"-r", "30",
"-i", "-",
"-c:v", "libx264",
"-pix_fmt", "yuv420p",
"-preset", "ultrafast",
"-f", "flv",
rtmpUrl };
string cmd = join(arguments, " ");
cout << cmd << endl;
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
HANDLE hwrite, hread;
if (CreatePipe(&hread, &hwrite, &sa, 0) == NULL)
{
cout << "pPipe Create error!" << endl;
return;
}
STARTUPINFO si;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOW;
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
si.hStdOutput = hwrite;
si.hStdInput = hread;
PROCESS_INFORMATION pi;
if (!CreateProcess(NULL, cmd.data(), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
cout << "进程创建错误" << endl;
CloseHandle(hread);
CloseHandle(hwrite);
hread = NULL;
hwrite = NULL;
return;
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
Mat frame;
while (cap.isOpened()) {
cap >> frame;
cv::resize(frame, frame, streamSize);
imshow("rtsp", frame);
if (waitKey(1) == 27)
break;
DWORD txcount = 0;
if (!WriteFile(hwrite, frame.data, frame.step[0] * frame.rows, &txcount, nullptr)) {
cout << "WriteFile failed\n";
continue;
}
}
}
int main() {
videoTest();
}
|