Большое спасибо, я понимаю, где была моя ошибка. Это был неправильный размер для VideoWriter на принимающей стороне.

нслирую видео через сокет и вижу видеопоток с другой стороны, но не могу получить видео. Мой видео файл пуст. Я думаю, что проблема может быть неправильно конвертировать видео формат на приемной стороне. Как я должен кодировать видео на стороне сервера и как я должен декодировать видео на стороне клиента?

Я использую Linux Ubuntu Mate, OpenCV 2.4.13.

Сервер:

#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;
}

Клиент:

#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;
}

Ответы на вопрос(2)

Решение Вопроса

Если вы хотите сохранить видео, вы должны установитьCV_FOURCE вMJPG

VideoWriter outputVideo;
Size S = Size((int) 640,(int) 480);
outputVideo.open("receive.avi", CV_FOURCC('M','J','P','G'), 30, S, true);

Это мой результат:

Код как следует:

客户 端(Client.cpp):

//!2017.12.19 19:19:01 CST
//!2017.12.19 22:19:38 CST
//!2017.12.19 22:39:37 CST
// 客户端
// 使用 OpenCV 读取视频(并处理),然后使用 SOCKET 上传到服务器。

#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <string>
#include <vector>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    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 = htonl(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;
        close(sock);
        return -1;
    }

    Mat frame;
    frame = Mat::zeros(480, 640, CV_8UC3);
    int imgSize = frame.cols*frame.rows*3;

    int cnt=0;
    //Mat frame;
    while(1) {
        cap >> frame;
        if(frame.empty()) {
            cerr<<"[client] VideoCapture(0) error!"<<endl;
        }

        cout<< ++cnt << ":"<< frame.isContinuous()<<"," <<frame.size()<<endl;;

        if( (bbytee = send(sock, frame.data, imgSize, 0)) < 0 ) {
            cerr<< "bytes = " << bbytee << endl;
            break;
        }

        cv::imshow("client", frame);
        if(cv::waitKey(100) == 'q') {
            break;
        }
    }
    close(sock);
    return 0;
}

服务 端(Server.cpp):

//!2017.12.19 19:19:01 CST
//!2017.12.19 22:19:38 CST
//!2017.12.19 22:39:37 CST
// 服务器
// 监听客户端请求,读取视频流(并处理),保存。
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <string>
#include <vector>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    int sock, listener;
    struct sockaddr_in addr;

    if( (listener = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("[server] 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("[server] binding faild!");
        exit(2);
    }

    listen(listener, 1);


    int num_of_recv_bytes;
    VideoWriter outputVideo;
    Size S = Size((int) 640,(int) 480);
    outputVideo.open("receive.avi", CV_FOURCC('M','J','P','G'), 30, S, true);

    int imgSize = 480*640*3;
    Mat frame = Mat::zeros(480, 640, CV_8UC3);
    uchar *iptr = frame.data;
    int key;

    int cnt=0;
    while(1){
        cout << ++cnt<<endl;
        sock = accept(listener, NULL, NULL);
        if(sock < 0){
            perror("[server] accept() faild!");
            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;
            }

            outputVideo<< frame;
            imshow("server", frame);
            if (key = waitKey(100) >= 0) break;
        }
        outputVideo.release();
        close(sock);
        break;
    }
    return 0;
}
 Влад Кабанцов20 дек. 2017 г., 09:20
Спасибо за ответ) Это может сработать, и с CV_FOURCE моей ошибкой был неправильный размер видео на принимающей стороне.

сть много решений, я не уверен, что FFmpeg может это сделать, вы можете попробовать.

ЗдесьГстремер документацияНадеюсь, это поможет вам. И вы также можете искать некоторые проекты в GitHub. Этот проект помогает мне, но этоне мой проектНадеюсь, это поможет вам.

 Влад Кабанцов19 дек. 2017 г., 14:43
Большое спасибо, я понимаю, где была моя ошибка. Это был неправильный размер для VideoWriter на принимающей стороне.

Ваш ответ на вопрос