提问人:Riley Bain 提问时间:11/14/2023 最后编辑:genpfaultRiley Bain 更新时间:11/14/2023 访问量:23
基于 OpenCV 的流媒体视频客户端无法显示视频?[关闭]
OpenCV-based streaming video client won't display video? [closed]
问:
我正在开发一个程序,使用 OpenCV 和 C++ 通过 TCP 直播视频片段。但是,代码似乎不是 100% 正确的。我遇到的问题出在客户端(我相信),视频将显示在服务器端,所以我知道相机正在正确捕获。但是在客户端,我认为它没有正确接收数据,救命!
服务器:
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <ws2tcpip.h>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/videoio/videoio.hpp>
#include <fstream>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <vector>
using namespace cv;
int capDev = 0;
VideoCapture cap(capDev); //open the default camera
// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")
#define DEFAULT_BUFLEN 256
#define DEFAULT_PORT "12345"
int __cdecl main(void)
{
//Initialize variables
Mat img;
WSADATA wsaData;
int iResult, key;
std::vector<uchar> buffer; //create vector buffer
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
//initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
//resolve the server address and port
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
//create a SOCKET for the server to listen for client connections.
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
else
{
printf("Socket init: Successful\n");
}
//setup the TCP listening socket
iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
else
{
printf("Bind: Successful\n");
}
freeaddrinfo(result);
//listen for client socket
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
else
{
printf("Server: Listening...\n");
}
//accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
else
{
printf("Accept: Successful\n");
}
//no longer need server socket
closesocket(ListenSocket);
//----------------------------------------------------------
//OpenCV Code
//----------------------------------------------------------
//commented out code old code for b&w image
//img = Mat::zeros(480, 640, CV_8U);
/*//make img continuos
if ( ! img.isContinuous() )
{
img = img.clone();
}
size_t imgSize = img.total() * img.elemSize();
int bytes = 0;
std::cout << "Image Size:" << imgSize << std::endl; */
//runs while VideoCapture obj is operational
while(cap.isOpened())
{
cap >> img; //get a frame from camera
if (img.empty())
{
printf("Err: 1");
break;
}
imencode(".jpg", img, buffer); //encode the data
uint64_t imgSize = buffer.size(); //create var for buffer size
send(ClientSocket, (char *) &imgSize, sizeof(imgSize), 0); //send buffer size
send(ClientSocket, (char *) buffer.data(), (int) imgSize, 0); //send buffer data (image)
buffer.clear(); //clear the buffer for next frame
//checks for empty frames
if (!(img.empty()))
{
imshow("Sending...", img); //displays image being sent
}
if (key = waitKey(10) == 27) //exits window with "esc"
{
goto S;
}
}
S : //shutdown the connection since we're done
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR)
{
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
//cleanup
cap.release();
closesocket(ClientSocket);
WSACleanup();
return 0;
}
客户:
#define WIN32_LEAN_AND_MEAN
#include <iostream>
#include <opencv2/opencv.hpp>
#include <ws2tcpip.h>
#include <vector>
#include <cstring>
using namespace cv;
//need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
#define DEFAULT_BUFLEN 256
#define DEFAULT_PORT "12345"
int __cdecl main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL, *ptr = NULL, hints;
Mat img;
int bytes = 0;
char key = 's';
int payloadSize = 1024;
int bufferSize = 4 * 1024;
std::vector<uchar> buffer;
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
//validate the parameters
if (argc != 2)
{
printf("usage: %s server-name\n", argv[0]);
return 1;
}
//initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0)
{
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
//resolve the server address and port
iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
if ( iResult != 0 )
{
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
//attempt to connect to an address until one succeeds
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next)
{
//create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET)
{
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
else
{
printf("Socket init: Successful\n");
}
//connect to server.
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR)
{
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET)
{
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
else
{
printf("Connection: Successful\n");
}
//----------------------------------------------------------
//OpenCV Code
//----------------------------------------------------------
/*size_t imgSize = img.total() * img.elemSize();
std::cout << "Image Size:" << imgSize << std::endl;*/
namedWindow("Receiving...", WINDOW_AUTOSIZE);
while (1)
{
uint64_t imgSize;
if(recv(ConnectSocket, (char *) &imgSize, sizeof(imgSize), MSG_WAITALL <= 0))
{
printf("Err: 1");
break;
}
buffer.resize(imgSize);
if (recv(ConnectSocket, (char *) buffer.data(), (int) imgSize, MSG_WAITALL <= 0))
{
printf("Err: 2");
break;
}
img = imdecode(buffer, IMREAD_COLOR);
imshow("Receiving...", img);
if(waitKey(10) == 27)
{
goto S;
}
}
// cleanup
S : closesocket(ConnectSocket);
WSACleanup();
return 0;
}
答: 暂无答案
评论
flags
recv
MSG_WAITALL <= 0
)
recv