2

皆さん、良い一日を!

画面をキャプチャし、ストリームを rtmp (ブロードキャスト用) で Wowza サーバーに送信する Windows 用のアプリケーションを作成しています。私のアプリケーションはffmpegとQtを使用しています。WinApi で画面をキャプチャし、バッファーを YUV444 に変換し (最も単純なため)、decoding_encoding.c ファイルで説明されているようにフレームをエンコードします (FFmpeg の例から)。

///////////////////////////
//Encoder initialization
///////////////////////////
avcodec_register_all();
codec=avcodec_find_encoder(AV_CODEC_ID_H264);
c = avcodec_alloc_context3(codec);
c->width=scr_width;
c->height=scr_height;
c->bit_rate = 400000;
int base_num=1;
int base_den=1;//for one frame per second
c->time_base= (AVRational){base_num,base_den};
c->gop_size = 10;
c->max_b_frames=1;
c->pix_fmt = AV_PIX_FMT_YUV444P;
av_opt_set(c->priv_data, "preset", "slow", 0);

frame = avcodec_alloc_frame();
frame->format = c->pix_fmt;
frame->width  = c->width;
frame->height = c->height;

for(int counter=0;counter<10;counter++)
{
///////////////////////////
//Capturing Screen
///////////////////////////
    GetCapScr(shotbuf,scr_width,scr_height);//result: shotbuf is filled by screendata from HBITMAP
///////////////////////////
//Convert buffer to YUV444 (standard formula)
//It's handmade function because of problems with prepare buffer to swscale from HBITMAP
///////////////////////////
    RGBtoYUV(shotbuf,frame->linesize,frame->data,scr_width,scr_height);//result in frame->data
///////////////////////////
//Encode Screenshot
///////////////////////////
    av_init_packet(&pkt);
    pkt.data = NULL;    // packet data will be allocated by the encoder
    pkt.size = 0;
    frame->pts = counter;
    avcodec_encode_video2(c, &pkt, frame, &got_output);
    if (got_output) 
    {
        //I think that  sending packet by rtmp  must be here!
        av_free_packet(&pkt);             

    }

}
// Get the delayed frames
for (int got_output = 1,i=0; got_output; i++)
{
    ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);
    if (ret < 0)
        {
            fprintf(stderr, "Error encoding frame\n");
            exit(1);
        }
        if (got_output)
        {
        //I think that  sending packet by rtmp  must be here!
        av_free_packet(&pkt);      
        }
}

///////////////////////////
//Deinitialize encoder
///////////////////////////
avcodec_close(c);
av_free(c);
av_freep(&frame->data[0]);
avcodec_free_frame(&frame);

このコードによって生成されたビデオ ストリームを RTMP サーバーに送信する必要があります。つまり、このコマンドには c++/c アナログが必要です。

ffmpeg -re -i "sample.h264" -f flv rtmp://sample.url.com/screen/test_stream

便利ですが、ストリームをファイルに保存したくありません。ffmpeg ライブラリを使用して、画面キャプチャをリアルタイムでエンコードし、エンコードされたフレームを自分のアプリケーション内の RTMP サーバーに送信したいと考えています。AVFormatContext を適切に初期化し、エンコードされたビデオ AVPackets をサーバーに送信する方法の例を少し教えてください。

ありがとう。

4

1 に答える 1

7

私の問題は、ffmpeg のソースからの例を使用して解決できます。ファイルmuxing.cが必要です。ffmpeg\docs\examplesこれは、ffmpeg のソースのフォルダーにあります。サンプル ストリームを rtmp サーバーまたはファイルに書き込むために必要なすべてのソース コードがあります。これらのソースのみを理解し、サンプル ストリームの代わりに独自のストリーム データを追加する必要があります。予期しない問題が発生する可能性がありますが、一般的には解決策があります。

于 2013-03-03T16:32:29.080 に答える