C++实现视频传输代码
时间: 2023-11-12 18:06:05 浏览: 88
以下是一个基于TCP协议的简单视频传输示例代码:
服务端代码:
```c++
#include <iostream>
#include <fstream>
#include <string>
#include <thread>
#include <chrono>
#include <opencv2/opencv.hpp>
#include <boost/asio.hpp>
using namespace std;
using namespace cv;
using namespace boost::asio;
void sendVideo(ip::tcp::socket& socket, const string& videoPath) {
// 打开视频文件
VideoCapture cap(videoPath);
if (!cap.isOpened()) {
cerr << "Failed to open video file: " << videoPath << endl;
return;
}
// 获取视频信息
int width = cap.get(CAP_PROP_FRAME_WIDTH);
int height = cap.get(CAP_PROP_FRAME_HEIGHT);
int fps = cap.get(CAP_PROP_FPS);
int totalFrames = cap.get(CAP_PROP_FRAME_COUNT);
// 发送视频信息
string info = to_string(width) + "," + to_string(height) + "," + to_string(fps) + "," + to_string(totalFrames);
write(socket, buffer(info, info.size()));
// 发送视频帧
Mat frame;
int frameCount = 0;
while (cap.read(frame)) {
vector<uchar> buffer;
imencode(".jpg", frame, buffer);
string sizeStr = to_string(buffer.size());
write(socket, buffer(sizeStr.size()));
write(socket, buffer(sizeStr.data(), sizeStr.size()));
write(socket, buffer.data(), buffer.size());
frameCount++;
this_thread::sleep_for(chrono::milliseconds(1000 / fps)); // 模拟发送帧的时间间隔
}
cout << "Sent " << frameCount << " frames." << endl;
}
int main() {
io_service io;
ip::tcp::acceptor acceptor(io, ip::tcp::endpoint(ip::tcp::v4(), 8080));
while (true) {
ip::tcp::socket socket(io);
acceptor.accept(socket);
// 新建一个线程处理连接
thread t([&socket]() {
// 接收视频文件路径
array<char, 1024> recvBuffer;
size_t bytesRead = socket.read_some(buffer(recvBuffer));
string videoPath(recvBuffer.data(), bytesRead);
// 发送视频
sendVideo(socket, videoPath);
socket.close();
});
t.detach();
}
return 0;
}
```
客户端代码:
```c++
#include <iostream>
#include <fstream>
#include <string>
#include <thread>
#include <chrono>
#include <opencv2/opencv.hpp>
#include <boost/asio.hpp>
using namespace std;
using namespace cv;
using namespace boost::asio;
void receiveVideo(ip::tcp::socket& socket, const string& savePath) {
// 接收视频信息
array<char, 1024> infoBuffer;
size_t bytesRead = socket.read_some(buffer(infoBuffer));
string info(infoBuffer.data(), bytesRead);
int pos1 = 0, pos2 = info.find(",", pos1);
int width = stoi(info.substr(pos1, pos2 - pos1));
pos1 = pos2 + 1; pos2 = info.find(",", pos1);
int height = stoi(info.substr(pos1, pos2 - pos1));
pos1 = pos2 + 1; pos2 = info.find(",", pos1);
int fps = stoi(info.substr(pos1, pos2 - pos1));
pos1 = pos2 + 1;
int totalFrames = stoi(info.substr(pos1));
// 接收视频帧
VideoWriter writer(savePath, VideoWriter::fourcc('M', 'J', 'P', 'G'), fps, Size(width, height));
int frameCount = 0;
while (frameCount < totalFrames) {
// 接收帧大小
array<char, 16> sizeBuffer;
bytesRead = socket.read_some(buffer(sizeBuffer));
string sizeStr(sizeBuffer.data(), bytesRead);
size_t size = stoi(sizeStr);
// 接收帧数据
vector<char> dataBuffer(size);
bytesRead = socket.read_some(buffer(dataBuffer));
while (bytesRead < size) {
size_t readSize = socket.read_some(buffer(dataBuffer.data() + bytesRead, size - bytesRead));
bytesRead += readSize;
}
// 解码并写入视频文件
Mat frame = imdecode(dataBuffer, IMREAD_COLOR);
writer.write(frame);
frameCount++;
}
cout << "Received " << frameCount << " frames." << endl;
}
int main() {
io_service io;
ip::tcp::socket socket(io);
socket.connect(ip::tcp::endpoint(ip::address::from_string("127.0.0.1"), 8080));
// 发送视频文件路径
string videoPath = "/path/to/video.mp4";
write(socket, buffer(videoPath, videoPath.size()));
// 接收视频
string savePath = "/path/to/output.avi";
receiveVideo(socket, savePath);
socket.close();
return 0;
}
```
这只是一个简单的示例,实际应用中需要更全面和完善的错误处理、调试和优化。
阅读全文