while (true) { int bytes = recv(sockConn, buffer, 2048, 0); if (bytes <= 0) break; fileSize += bytes; // 将接收到的视频数据写入到.avi文件中 std::ofstream videoFile("server_video.avi", std::ios::binary | std::ios::app); videoFile.write(buffer, bytes); videoFile.close(); } VideoWriter writer("server_video.avi", cv::VideoWriter::fourcc('M', 'J', 'P', 'G'), 25.0, Size(640, 480)); if (writer.isOpened()) { writer.write(videoData); }为什么这段代码无法正常打开视频
时间: 2024-04-15 07:26:59 浏览: 164
这段代码中的问题在于在每次循环中都会打开并关闭文件流。这会导致文件指针不会在每次循环迭代之间保持一致,从而导致无法正确写入视频数据。解决方法是将文件流的打开和关闭放在循环外部,只在开始时打开文件流,在循环结束后关闭文件流。以下是修改后的代码示例:
```cpp
std::ofstream videoFile("server_video.avi", std::ios::binary | std::ios::app);
while (true) {
int bytes = recv(sockConn, buffer, 2048, 0);
if (bytes <= 0) break;
fileSize += bytes;
videoFile.write(buffer, bytes);
}
videoFile.close();
VideoWriter writer("server_video.avi", cv::VideoWriter::fourcc('M', 'J', 'P', 'G'), 25.0, Size(640, 480));
if (writer.isOpened()) {
writer.write(videoData);
}
```
请注意,视频数据的来源(videoData)在你提供的代码中没有明确指定,你需要根据实际情况将其添加到代码中。此外,还要确保 OpenCV 库已正确链接和配置。
相关问题
怎样修改这段代码让他让视频保存到本地并上传到数据库中void ShowVideo() { //创建数据库连接 MYSQL mysql; mysql_init(&mysql); mysql_real_connect(&mysql, "localhost", "root", "password", "database", 3306, NULL, 0); mysql_query(&mysql, "set names utf8"); SOCKET server = socket(AF_INET, SOCK_STREAM, 0); char buffer[2048] = " "; SOCKET sockConn = accept(server, NULL, NULL); Mat videoData; while (true) { int bytes = recv(sockConn, buffer, 2048, 0); if (bytes <= 0) break; // 将接收到的视频数据拼接在一起 videoData.push_back(Mat(1, bytes, CV_8UC1, buffer).clone()); } closesocket(sockConn); size_t fileSize = 0; std::ofstream videoFile("server_video.avi", std::ios::binary | std::ios::app); while (true) { int bytes = recv(sockConn, buffer, 2048, 0); if (bytes <= 0) break; fileSize += bytes; // 将接收到的视频数据写入到.avi文件中 std::ofstream videoFile("server_video.avi", std::ios::binary | std::ios::app); videoFile.write(buffer, bytes); } videoFile.close(); VideoWriter writer("server_video.avi", cv::VideoWriter::fourcc('M', 'J', 'P', 'G'), 25.0, Size(640, 480)); if (writer.isOpened()) { writer.write(videoData); } //读取视频文件内容并保存到数据库 ifstream fin("server_video.avi", ios::binary | ios::in); if (!fin) { cout << "打开文件失败" << endl; exit(0); } fin.seekg(0, ios::end); int filesize = fin.tellg(); fin.seekg(0, ios::beg); char* fileContent = new char[filesize]; fin.read(fileContent, filesize); string fileContentStr(fileContent, filesize);
你可以修改这段代码,让它将视频保存到本地并上传到数据库中。首先,你需要添加一些必要的头文件:
```cpp
#include <mysql.h>
#include <WinSock2.h>
#include <fstream>
#include <iostream>
#include <opencv2/opencv.hpp>
```
然后,你可以修改 `ShowVideo` 函数:
```cpp
void ShowVideo()
{
// 创建数据库连接
MYSQL mysql;
mysql_init(&mysql);
mysql_real_connect(&mysql, "localhost", "root", "password", "database", 3306, NULL, 0);
mysql_query(&mysql, "set names utf8");
SOCKET server = socket(AF_INET, SOCK_STREAM, 0);
char buffer[2048] = " ";
SOCKET sockConn = accept(server, NULL, NULL);
Mat videoData;
while (true) {
int bytes = recv(sockConn, buffer, 2048, 0);
if (bytes <= 0) break;
// 将接收到的视频数据拼接在一起
videoData.push_back(Mat(1, bytes, CV_8UC1, buffer).clone());
}
closesocket(sockConn);
std::ofstream videoFile("server_video.avi", std::ios::binary | std::ios::app);
while (true) {
int bytes = recv(sockConn, buffer, 2048, 0);
if (bytes <= 0) break;
// 将接收到的视频数据写入到.avi文件中
videoFile.write(buffer, bytes);
}
videoFile.close();
VideoWriter writer("server_video.avi", cv::VideoWriter::fourcc('M', 'J', 'P', 'G'), 25.0, Size(640, 480));
if (writer.isOpened()) {
writer.write(videoData);
}
// 将视频文件内容保存到数据库
ifstream fin("server_video.avi", ios::binary | ios::in);
if (!fin) {
cout << "打开文件失败" << endl;
exit(0);
}
fin.seekg(0, ios::end);
int filesize = fin.tellg();
fin.seekg(0, ios::beg);
char* fileContent = new char[filesize];
fin.read(fileContent, filesize);
string fileContentStr(fileContent, filesize);
// 将视频内容上传到数据库
string query = "INSERT INTO videos (content) VALUES ('" + fileContentStr + "')";
mysql_query(&mysql, query.c_str());
// 释放资源
delete[] fileContent;
fin.close();
}
```
请注意,此修改假设你已经正确安装了 MySQL 和 OpenCV 库,并且数据库中已经存在名为 `videos` 的表,其中包含一个名为 `content` 的 BLOB 类型的字段来存储视频内容。你需要根据你的实际情况进行适当的调整。另外,记得将 `localhost`、`root`、`password` 和 `database` 替换为你的实际数据库连接信息。
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { int i; HAL_StatusTypeDef ret; int32_t data_len = 0; recv_bytes += Size; if(!parse_head_flag && recv_bytes >= PACKAGE_HEAD_SIZE){ data_len = parse_package_head(RX_IDLE_Buffer, PACKAGE_HEAD_SIZE); parse_head_flag = 1; } if(recv_bytes >= PACKAGE_HEAD_SIZE + data_len + 2){ int size; int err = parse_package(RX_IDLE_Buffer, PACKAGE_HEAD_SIZE + data_len + 2); memcpy(TX_ACK_Buffer, RX_IDLE_Buffer, PACKAGE_HEAD_SIZE- 2); size = make_ack_package(TX_ACK_Buffer, TX_ACK_BUFFER_SIZE, err); HAL_UART_Transmit(&huart2, TX_ACK_Buffer, size, 1000); parse_head_flag = 0; recv_bytes = 0; } ret = HAL_UARTEx_ReceiveToIdle_IT(&huart1, RX_IDLE_Buffer + recv_bytes, RX_IDLE_BUFFER_SIZE- recv_bytes); if(ret != HAL_OK){ printf("Fail to HAL_UARTEx_ReceiveToIdle_IT,ret:%d\r\n",ret); return; } return; }写注释
以下是对这段代码的注释:
```c
/**
* @brief UART接收中断回调函数
* @param huart: UART句柄
* @param Size: 接收数据的字节数
*/
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {
int i;
HAL_StatusTypeDef ret;
int32_t data_len = 0;
recv_bytes += Size; // 更新接收字节数
// 如果还未解析头部并接收到了足够的字节数,则解析头部
if(!parse_head_flag && recv_bytes >= PACKAGE_HEAD_SIZE){
data_len = parse_package_head(RX_IDLE_Buffer, PACKAGE_HEAD_SIZE);
parse_head_flag = 1;
}
// 如果接收到了一个完整的数据包,则解析数据包并生成ACK包,并通过UART发送ACK包
if(recv_bytes >= PACKAGE_HEAD_SIZE + data_len + 2){
int size;
int err = parse_package(RX_IDLE_Buffer, PACKAGE_HEAD_SIZE + data_len + 2);
memcpy(TX_ACK_Buffer, RX_IDLE_Buffer, PACKAGE_HEAD_SIZE- 2);
size = make_ack_package(TX_ACK_Buffer, TX_ACK_BUFFER_SIZE, err);
HAL_UART_Transmit(&huart2, TX_ACK_Buffer, size, 1000); // 通过UART发送ACK包
parse_head_flag = 0;
recv_bytes = 0;
}
// 继续异步接收UART数据
ret = HAL_UARTEx_ReceiveToIdle_IT(&huart1, RX_IDLE_Buffer + recv_bytes, RX_IDLE_BUFFER_SIZE- recv_bytes);
// 如果接收失败,则输出错误信息
if(ret != HAL_OK){
printf("Fail to HAL_UARTEx_ReceiveToIdle_IT,ret:%d\r\n",ret);
return;
}
return;
}
```
阅读全文