C ++ Потоковое видео и Transimisson

Я новичок в декодировании / кодировании видео. В настоящее время у меня есть задача проверить передачу видео на сетевое кодирование. Программа сетевого кодирования уже была готова.

Сначала я попытался разделить видео на кадры в opencv и передать их, но после разделения я обнаружил, что видео размером 3 МБ преобразуется в кадры общего размера 80 МБ !! который не эффективен для передачи. Есть ли лучший способ сделать передачу видео? Может ли кто-нибудь из профессионалов предоставить мне пример кода на C ++? Мне сказали, что нельзя напрямую помещать видео в буфер из-за ограничения пропускной способности передачи. Мне интересно использовать разницу между кадрами, чтобы уменьшить размер передаваемого файла, но я не знаю, как это сделать в C ++.

Вот мой код для видео, разделенного на кадры.

#include "opencv2/highgui/highgui.hpp"#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char* argv[])
{

VideoCapture cap("/home/yonghao/Documents/50MbitMJPEG1080p.mp4"); // open the video file for readingdouble fps = cap.get(CV_CAP_PROP_FPS); //get the frames per seconds of the video
int numFrames = cap.get(CV_CAP_PROP_FRAME_COUNT); // get the total number of frames

cout << "Frame per seconds : " << fps << endl;
cout << "Total Frame Numbers : " << numFrames << endl;

namedWindow("MyVideo",CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"
int frame_number = 1;

while(frame_number<=numFrames)
{
Mat frame;

bool bSuccess = cap.read(frame); // read a new frame from video

if (!bSuccess) //if not success, break loop
{
cout << "Cannot read the frame from video file" << endl;
break;
}

imshow("MyVideo", frame); //show the frame in "MyVideo" window

//save frame

stringstream ss;
string name = "/home/yonghao/Documents/Frames/frame_";
string type = ".jpg";

ss<<name<<(frame_number)<<type;

string filename = ss.str();
ss.str("");

imwrite(filename, frame);

cout << "Frame " << frame_number << " has been generated." << endl;

frame_number++;

//user exit by press ESC button

if(waitKey(30) == 27) //wait for 'esc' key press for 30 ms. If 'esc' key is pressed,    break loop
{
cout << "esc key is pressed by user" << endl;
break;
}
}
return 0;
}

-3

Решение

Если битрейт вашего видео слишком велик для вашей полосы пропускания, вам необходимо повторно сжать его, используя стандартный видеокодек, например, h264.
Вы можете сделать это с помощью программы ffmpeg, используя что-то вроде:

ffmpeg -i <your_input_file> -c:v libx264 -crf 22 video.avi

Это будет кодировать с параметрами по умолчанию и постоянным качеством (параметр crf, чем ниже, тем выше качество), см. Вот для опций кодера h264, в вашем случае вы можете предпочесть использовать постоянный битрейт вместо постоянного качества.

Чтение видео с правильной скоростью и потоковая передача по сети было бы возможно в c библиотекой libavformat (часть библиотек ffmpeg), но, вероятно, сложно для новичка.

Одним из более простых решений было бы перенаправить вывод команды ffmpeg в вашу программу, которая выполняет сетевое кодирование.

Например:

ffmpeg -re -i input.avi -f rawvideo -c:v copy pipe:1 | ./network_encode

Это прочитает закодированный видеофайл и отправит необработанный видеопоток в вашу программу сетевого кодирования (здесь network_encode считывает данные со стандартного ввода, применяет сетевое кодирование и отправляет его)

На приемнике вы можете сделать что-то похожее для визуализации вашего видео (здесь network_decode получает данные из сети, декодирует их и записывает результат в стандартный вывод):

./network_decode | ffplay -i -
0

Другие решения


По вопросам рекламы [email protected]