I translate video through socket and I see video stream in other side but I cant receive video. My video file is empty. I am thinking the problem can be wrong convert video format on the receive side. How I should encode video on the server side and how I should decode video in the client side?
I use Linux Ubuntu Mate, OpenCV 2.4.13.
Server:
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fstream>
#include <cstring>
#include <iostream>
#include "opencv2/opencv.hpp"
#include <opencv/cv.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <string>
#include <iomanip>
#include <pthread.h>
#include <SerialStream.h>
#include <unistd.h>
#include <ctime>
#include <iomanip>
#include "opencv2/opencv.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/mat.hpp>
#include <opencv2/core/types_c.h>
#include <vector>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;
using namespace cv;
char answer[] = "Y";
int main()
{
int sock, listener;
struct sockaddr_in addr;
char buf[1024];
int bytes_read;
if( (listener = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("socket() failed");
exit(1);
}
addr.sin_family = AF_INET;
addr.sin_port = htons(3425);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(listener, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
perror("bind");
exit(2);
}
listen(listener, 1);
ofstream of("readFile.txt");
vector<int> param;
param.push_back(CV_IMWRITE_JPEG_QUALITY);
Mat frame = Mat::zeros(480, 640, CV_8UC3);
Mat receive;
int imgSize = frame.total()*frame.elemSize();
if(! frame.isContinuous() ){
frame = frame.clone();
}
namedWindow("CV Video Client", 1);
uchar *iptr = frame.data;
int key;
uchar sockData[imgSize];
int count_of_receive_frame = 0;
int num_of_recv_bytes;
VideoWriter outputVideo;
Size S = Size((int) 480,(int) 640);
outputVideo.open("receive.avi", CV_FOURCC('X','V','I','D'), 30, S, true);
int i = 0;
char name_of_photo[20];
while(1)
{
sock = accept(listener, NULL, NULL);
if(sock < 0)
{
perror("accept");
exit(3);
}
while(key != 'q'){
if( num_of_recv_bytes = recv(sock, iptr, imgSize, MSG_WAITALL) == -1 ){
cerr << "recv failed, received bytes = " << num_of_recv_bytes << endl;
}
imshow("CV Video Client", frame);
outputVideo.write(frame);
if (key = waitKey(10) >= 0) break;
}
outputVideo.release();
close(sock);
break;
}
return 0;
}
Client:
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fstream>
#include <cstring>
#include <iostream>
#include "opencv2/opencv.hpp"
#include <opencv/cv.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <string>
#include <iomanip>
#include <pthread.h>
#include <unistd.h>
#include <ctime>
#include <iomanip>
#include "opencv2/opencv.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/mat.hpp>
#include <opencv2/core/types_c.h>
#include <vector>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;
using namespace cv;
size_t get_file_size( const char * filename );
void file_to_buf( char *buf, size_t _len, std::string filename );
void take_photo(char *name);
char answer[] = "N";
char message[] = "Hello there!\n";
int count_send_img = 0;
int main()
{
string filename = "img.jpg";
int sock;
struct sockaddr_in addr;
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock < 0)
{
perror("socket");
exit(1);
}
addr.sin_family = AF_INET;
addr.sin_port = htons(3425); // или любой другой порт...
addr.sin_addr.s_addr = /*net_addr*/htonl(/*"192.168.1.71"*/INADDR_LOOPBACK);
if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
perror("connect");
exit(2);
}
int bbytee;
cout << "before open the cam" << endl;
VideoCapture cap(0);
if(!cap.isOpened()){
cout<< "Could not open the camera" << endl;
}
cout << "cam opened" << endl;
Mat frame, frameGray;
frame = Mat::zeros(480, 640, CV_8UC3);
if(! frame.isContinuous() ){
frame = frame.clone();
}
int imgSize = frame.total()*frame.elemSize();
while(1){
cap >> frame;
cvtColor(frame, frameGray, CV_BGR2GRAY);
if( (bbytee = send(sock, frameGray.data, imgSize, 0)) < 0 ){
cerr<< "bytes = " << bbytee << endl;
break;
}
}
close(sock);
return 0;
}
Uh,I am also a newbie about opencv. But i can do this in opencv and Gstreamer. There are lots of solutions i'm not sure the FFmpeg can do it, you can try.
Here is the Gstremer documetion.Hope it will help you.And you can also search some project in github. This project help me but it is not my project, hope it will help you.
Env: OpenCV 3.3, G++5.4, Ubuntu 16.04
If you want to save the video, you should set
CV_FOURCE
toMJPG
。This is my result:
Code as follow:
客户端(Client.cpp):
服务端(Server.cpp):