FFmpeg Realization Recording screen + record

Source: Internet
Author: User

1, overview of the simplest ffmpeg-based Avdevice example (screen recording + sound capture), video using MPEG4 encoding, audio using AAC encoding, and generate MP4 files, which FIFO is the key to this program, this program is just a demo a lot of optimizations are not done, for reference only.
2. Code
/** * Simplest ffmpeg-based Avdevice example (screen recording + sound capture), video with MPEG4 encoding, audio using AAC encoding, and generating MP4 file * Miu MK *[email protected] */#include " StdAfx.h "#ifdef__cplusplusextern" C "{#endif # include" libavcodec/avcodec.h "#include" libavformat/avformat.h "# Include "Libswscale/swscale.h" #include "libavdevice/avdevice.h" #include "libavutil/audio_fifo.h" #pragma comment ( LIB, "Avcodec.lib") #pragma comment (lib, "Avformat.lib") #pragma comment (lib, "Avutil.lib") #pragma comment (lib, " Avdevice.lib ") #pragma comment (lib," Avfilter.lib ")//#pragma comment (lib," Avfilter.lib ")//#pragma comment (lib," Postproc.lib ")//#pragma comment (lib," Swresample.lib ") #pragma comment (lib," Swscale.lib ") #ifdef __cplusplus};# Endifavformatcontext*pformatctx_video = null, *pformatctx_audio = NULL, *pformatctx_out = NULL; Avcodeccontext*pcodecctx_video; Avcodec*pcodec_video; Avfifobuffer*fifo_video = NULL; Avaudiofifo*fifo_audio = Null;int Videoindex, audioindex; critical_section audiosection, videosection; Swscontext *img_convert_ctx;int frame_size = 0;uint8_T *picture_buf = NULL, *frame_buf = Null;bool BCap = True;dword WINAPI screencapthreadproc (lpvoid lpparam);D word WINAPI Audiocapthreadproc (LPVOID lpparam); int openvideocapture () {Avinputformat *ifmt=av_find_input_format ("Gdigrab");// Here you can add parameters to open, for example, you can specify the acquisition frame rate avdictionary *options = Null;av_dict_set (&options, "framerate", "All", NULL);//av_dict_set ( &options, "offset_x", "0",//the distance from the top edge of the the screen or Desktop//av_dict_set (&options, " Offset_y "," Max ", 0);//video frame size. The default is to capture the full Screenav_dict_set (&options, "Video_size", "", 0); if (Avformat_open_input ( &pformatctx_video, "desktop", Ifmt, &options)!=0) {printf ("couldn ' t open input stream. (Unable to turn on video input streams) \ n"); return- 1;} if (Avformat_find_stream_info (pformatctx_video,null) <0) {printf ("couldn ' t find stream information. (Unable to get video stream information) \ n" ); return-1;} if (pformatctx_video->streams[0]->codec->codec_type! = avmedia_type_video) {printf ("couldn ' t find Video Stream information. (CannotGet video stream information) \ n "); return-1;} Pcodecctx_video = Pformatctx_video->streams[0]->codec;pcodec_video = Avcodec_find_decoder (pCodecCtx_Video- &GT;CODEC_ID); if (Pcodec_video = = NULL) {printf ("Codec not found. (no decoder found) \ n"); return-1;} if (Avcodec_open2 (Pcodecctx_video, Pcodec_video, NULL) < 0) {printf ("Could not open codec. (Unable to turn on decoder) \ n"); return-1;} Img_convert_ctx = Sws_getcontext (Pcodecctx_video->width, Pcodecctx_video->height, PCodecCtx_Video->pix_ FMT, Pcodecctx_video->width, Pcodecctx_video->height, pix_fmt_yuv420p, sws_bicubic, NULL, NULL, and NULL); Frame_size = Avpicture_get_size (pcodecctx_video->pix_fmt, Pcodecctx_video->width, PCodecCtx_Video->height );//Apply 30 Frame Cache Fifo_video = Av_fifo_alloc (* avpicture_get_size (av_pix_fmt_yuv420p, Pcodecctx_video->width, Pcodecctx_video->height)); return 0;} Static char *dup_wchar_to_utf8 (wchar_t *w) {char *s = null;int L = WideCharToMultiByte (Cp_utf8, 0, W,-1, 0, 0, 0, 0); s = ( char *) Av_malloc (L), if (s) widechartomultibyte (Cp_utf8, 0, W,-1, S, l, 0, 0); return s;} int Openaudiocapture () {//Lookup input mode Avinputformat *paudioinputfmt = Av_find_input_format ("DShow");//Open the device in direct show mode, and associates the input method to the format context char * Psdevname = Dup_wchar_to_utf8 (L "audio= microphone (Realtek high Definition Au); if (Avformat_open_input (&A Mp;pformatctx_audio, Psdevname, Paudioinputfmt,null) < 0) {printf ("couldn ' t open input stream. (Unable to turn on audio input streams) \ n"); return-1;} if (Avformat_find_stream_info (pformatctx_audio,null) <0) return-1; if (pformatctx_audio->streams[0]->codec->codec_type! = Avmedia_type_audio) {printf ("couldn ' t find video Stream information (unable to get audio stream information) \ n "); return-1;} Avcodec *tmpcodec = Avcodec_find_decoder (pformatctx_audio->streams[0]->codec->codec_id); if (0 > Avcodec_ Open2 (Pformatctx_audio->streams[0]->codec, Tmpcodec, NULL)) {printf ("Can not find or open Audio decoder!\n");} return 0;} int Openoutput () {Avstream *pvideostream = NULL, *paudiostream = null;const char *outfilename = "Test.mp4"; avformat_alloc_ OUTPUT_CONTEXT2 (&p formatctx_out, NULL, NULL, outfilename); if (Pformatctx_video->streams[0]->codec->codec_type = = AVMEDIA_ Type_video) {Avcodeccontext *videocodecctx; Videoindex = 0;pvideostream = Avformat_new_stream (Pformatctx_out, NULL), if (!pvideostream) {printf ("can not new stream For output!\n "); return-1;} Set Codec Context Parampvideostream->codec->codec = Avcodec_find_encoder (AV_CODEC_ID_MPEG4);p videostream- >codec->height = Pformatctx_video->streams[0]->codec->height;pvideostream->codec->width = Pformatctx_video->streams[0]->codec->width;pvideostream->codec->time_base = pFormatCtx_Video-> Streams[0]->codec->time_base;pvideostream->codec->sample_aspect_ratio = PFormatCtx_Video->streams [0]->codec->sample_aspect_ratio;//take first format from List of supported formatspvideostream->codec-> PIX_FMT = Pformatctx_out->streams[videoindex]->codec->codec->pix_fmts[0];//open Encoderif (! Pvideostream->codec->codec) {printf ("Can not find the encoder!\n"); return-1;} if (Pformatctx_out->oformat->flags & Avfmt_globalheader) pvideostream->codec->flags |= CODEC_FLAG_ Global_header;if ((Avcodec_open2 (Pvideostream->codec, Pvideostream->codec->codec, NULL)) < 0) {printf (" Can not open the encoder\n "); return-1;}} if (Pformatctx_audio->streams[0]->codec->codec_type = = Avmedia_type_audio) {Avcodeccontext * Poutputcodecctx; Audioindex = 1;paudiostream = Avformat_new_stream (pformatctx_out, NULL);p Audiostream->codec->codec = avcodec_ Find_encoder (pformatctx_out->oformat->audio_codec);p outputcodecctx = paudiostream->codec; Poutputcodecctx->sample_rate = pformatctx_audio->streams[0]->codec->sample_rate;poutputcodecctx-> Channel_layout = Pformatctx_out->streams[0]->codec->channel_layout;poutputcodecctx->channels = av_get_ Channel_layout_nb_channels (paudiostream->codec->channel_layout); if (poutputcodecctx->channel_layout = = 0 ) {PoutputcodecCtx->channel_layout = Av_ch_layout_stereo;poutputcodecctx->channels = Av_get_channel_layout_nb_channels ( Poutputcodecctx->channel_layout);} POUTPUTCODECCTX-&GT;SAMPLE_FMT = paudiostream->codec->codec->sample_fmts[0]; Avrational time_base={1, paudiostream->codec->sample_rate};p audiostream->time_base = time_base;//  audiocodecctx->time_base = Time_base;poutputcodecctx->codec_tag = 0; if (Pformatctx_out->oformat->flags & Avfmt_globalheader) poutputcodecctx->flags |= CODEC_FLAG_GLOBAL_ Header;if (Avcodec_open2 (poutputcodecctx, Poutputcodecctx->codec, 0) < 0) {//Encoder open failed, exit program return-1;}} if (! ( Pformatctx_out->oformat->flags & Avfmt_nofile) {if (Avio_open (&AMP;PFORMATCTX_OUT-&GT;PB, OutFileName, Avio_flag_write) < 0) {printf ("Can not open output file handle!\n"); return-1;}} if (Avformat_write_header (Pformatctx_out, NULL) < 0) {printf ("Can not write the header of the output file!\n"); return-1; }return 0;} int _tmain (int argc, _tchar* argV[]) {av_register_all (); Avdevice_register_all (); if (Openvideocapture () < 0) {return-1;} if (openaudiocapture () < 0) {return-1;} if (Openoutput () < 0) {return-1;} InitializeCriticalSection (&videosection); initializecriticalsection (&audiosection); Avframe *picture = Av_frame_alloc (); int size = Avpicture_get_size (pformatctx_out->streams[videoindex]->codec- &GT;PIX_FMT, Pformatctx_out->streams[videoindex]->codec->width, pformatctx_out->streams[videoindex]- >codec->height);p icture_buf = new Uint8_t[size];avpicture_fill ((Avpicture *) picture, picture_buf, pFormatCtx_ OUT-&GT;STREAMS[VIDEOINDEX]-&GT;CODEC-&GT;PIX_FMT, Pformatctx_out->streams[videoindex]->codec->width, pformatctx_out->streams[videoindex]->codec->height);//star cap Screen threadcreatethread (NULL, 0, Screencapthreadproc, 0, 0, null);//star cap Audio Threadcreatethread (NULL, 0, audiocapthreadproc, 0, 0, null); int64_t cur _pts_v=0,cur_pts_a=0;int videoframeindex = 0, Audioframeindex = 0;while (1) {if (_kbhit () = 0 && bCap) {bCap = false; Sleep (2000);//simply use sleep to wait for the capture thread to close}if (Fifo_audio && fifo_video) {int sizeaudio = av_audio_fifo_size (Fifo_audio) ; int sizevideo = Av_fifo_size (Fifo_video);//end loop If cache data is finished (Av_audio_fifo_size (fifo_audio) <= pformatctx_out-> Streams[audioindex]->codec->frame_size && av_fifo_size (fifo_video) <= frame_size &&!bCap) { Break;}} if (Av_compare_ts (Cur_pts_v, Pformatctx_out->streams[videoindex]->time_base, cur_pts_a,pformatctx_out-> Streams[audioindex]->time_base) <= 0) {//read data from fifoif (Av_fifo_size (Fifo_video) < Frame_size & &!bcap) {cur_pts_v = 0x7fffffffffffffff;} if (Av_fifo_size (fifo_video) >= size) {entercriticalsection (&videosection); Av_fifo_generic_read (Fifo_video, Picture_buf, size, NULL); LeaveCriticalSection (&videosection); Avpicture_fill (avpicture *) picture, picture_buf, pformatctx_out-> STREAMS[VIDEOINDEX]-&GT;CODEC-&GT;PIX_FMT, Pformatctx_out->stReams[videoindex]->codec->width, pformatctx_out->streams[videoindex]->codec->height);//pts = n * (1 /timbase)/fps);p icture->pts = Videoframeindex * ((pformatctx_video->streams[0]->time_base.den/pformatctx_ video->streams[0]->time_base.num), int got_picture = 0; Avpacket Pkt;av_init_packet (&pkt);p kt.data = Null;pkt.size = 0;int ret = Avcodec_encode_video2 (pFormatCtx_Out-> Streams[videoindex]->codec, &pkt, picture, &got_picture); if (Ret < 0) {//Encode error, ignore this frame continue;} if (got_picture==1) {pkt.stream_index = Videoindex;pkt.pts = Av_rescale_q_rnd (pkt.pts, pformatctx_video->streams[0 ]->time_base, Pformatctx_out->streams[videoindex]->time_base, (avrounding) (AV_ROUND_NEAR_INF|  Av_round_pass_minmax)); Pkt.dts = Av_rescale_q_rnd (Pkt.dts, Pformatctx_video->streams[0]->time_base, pFormatCtx_Out->streams[ Videoindex]->time_base, (avrounding) (av_round_near_inf|  Av_round_pass_minmax)); Pkt.duration = ((pformatctx_out->strEams[0]->time_base.den/pformatctx_out->streams[0]->time_base.num)/Cur_pts_v = Pkt.pts;ret = av_ Interleaved_write_frame (Pformatctx_out, &AMP;PKT);//delete[] Pkt.data;av_free_packet (&AMP;PKT);} videoframeindex++;}} Else{if (NULL = = Fifo_audio) {continue;//not yet initialized fifo}if (av_audio_fifo_size (Fifo_audio) < Pformatctx_out->streams [Audioindex]->codec->frame_size &&!bcap] {cur_pts_a = 0X7FFFFFFFFFFFFFFF;} if (Av_audio_fifo_size (Fifo_audio) >= (pformatctx_out->streams[audioindex]->codec->frame_size > 0?) pformatctx_out->streams[audioindex]->codec->frame_size:1024)) {Avframe *frame;frame = Av_frame_alloc (); Frame->nb_samples = pformatctx_out->streams[audioindex]->codec->frame_size>0? Pformatctx_out->streams[audioindex]->codec->frame_size:1024;frame->channel_layout = pFormatCtx_Out- >streams[audioindex]->codec->channel_layout;frame->format = pformatctx_out->streams[audioindex]- >codec->sample_fmt; frame->sample_rate = Pformatctx_out->streams[audioindex]->codec->sample_rate;av_frame_get_buffer ( frame, 0); EnterCriticalSection (&audiosection); Av_audio_fifo_read (Fifo_audio, (void * *) Frame->data, (pFormatCtx_Out- >streams[audioindex]->codec->frame_size > 0? pformatctx_out->streams[audioindex]->codec->frame_size:1024)); LeaveCriticalSection (&audiosection); if (pformatctx_out->streams[0]->codec->sample_fmt! = PFormatCtx_ audio->streams[audioindex]->codec->sample_fmt | | Pformatctx_out->streams[0]->codec->channels! = pformatctx_audio->streams[audioindex]->codec-> Channels | | Pformatctx_out->streams[0]->codec->sample_rate! = pformatctx_audio->streams[audioindex]->codec- >sample_rate) {//if the input and output audio formats do not need to be resampled, here is the same as not done}avpacket Pkt_out;av_init_packet (&pkt_out); int got_picture = -1;pkt_out.data = Null;pkt_out.size = 0;frame->pts = Audioframeindex * pformatctx_out->streams[audioindex]->cOdec->frame_size;if (Avcodec_encode_audio2 (Pformatctx_out->streams[audioindex]->codec, &pkt_out, Frame, &got_picture) < 0) {printf ("Can not decoder a frame");} Av_frame_free (&frame); if (got_picture) {pkt_out.stream_index = Audioindex;pkt_out.pts = AudioFrameIndex * Pformatctx_out->streams[audioindex]->codec->frame_size;pkt_out.dts = AudioFrameIndex * pFormatCtx_Out- >streams[audioindex]->codec->frame_size;pkt_out.duration = pformatctx_out->streams[audioindex]-> Codec->frame_size;cur_pts_a = pkt_out.pts;int ret = av_interleaved_write_frame (pformatctx_out, &pkt_out); av_ Free_packet (&pkt_out);} audioframeindex++;}}} Av_write_trailer (pformatctx_out); Avio_close (PFORMATCTX_OUT-&GT;PB); Avformat_free_context (PFormatCtx_Out); if ( Pformatctx_video! = null) {Avformat_free_context (pformatctx_video);p formatctx_video = null;} if (Pformatctx_audio! = null) {Avformat_free_context (pformatctx_audio);p formatctx_audio = null;} return 0;} DWORD WINAPI ScreenCapThreadProc (LPVOID lpparam) {avpacket *packet = (Avpacket *) av_malloc (sizeof (avpacket)); int got_picture; Avframe*pframe;pframe=avcodec_alloc_frame (); Avframe *picture = Avcodec_alloc_frame (); int size = Avpicture_get_size (pformatctx_out->streams[videoindex]-> CODEC-&GT;PIX_FMT, Pformatctx_out->streams[videoindex]->codec->width, pFormatCtx_Out->streams[ videoindex]->codec->height);p icture_buf = new Uint8_t[size];avpicture_fill ((Avpicture *) picture, PICTURE_BUF, PFORMATCTX_OUT-&GT;STREAMS[VIDEOINDEX]-&GT;CODEC-&GT;PIX_FMT, pformatctx_out->streams[videoindex]->codec- >width, Pformatctx_out->streams[videoindex]->codec->height); FILE *p = Null;p = fopen ("Proc_test.yuv", "wb+"); int height = pformatctx_out->streams[videoindex]->codec-> Height;int width = pformatctx_out->streams[videoindex]->codec->width;int y_size=height*width;while (bCap) { if (Av_read_frame (pformatctx_video, packet) < 0) {continue;} if (Packet->stream_index = = 0) {if (avcodEc_decode_video2 (Pcodecctx_video, Pframe, &got_picture, packet) < 0) {printf ("Decode error. (decoding errors) \ n"); continue ;} if (got_picture) {Sws_scale (Img_convert_ctx, (const uint8_t* const*) Pframe->data, pframe->linesize, 0, Pformatctx_out->streams[videoindex]->codec->height, Picture->data, picture->linesize); if (av_fifo_ Space (Fifo_video) >= size) {entercriticalsection (&videosection); Av_fifo_generic_write (Fifo_video, picture- >data[0], y_size, null); Av_fifo_generic_write (Fifo_video, picture->data[1], Y_SIZE/4, NULL); av_fifo_generic_ Write (Fifo_video, picture->data[2], Y_SIZE/4, NULL); LeaveCriticalSection (&videosection);}}} Av_frame_free (&pframe); Av_frame_free (&picture);d elete[] Picture_buf;return 0;} DWORD WINAPI Audiocapthreadproc (lpvoid lpparam) {Avpacket pkt; Avframe *frame;frame = Av_frame_alloc (); int Gotframe;while (BCAP) {if (Av_read_frame (PFORMATCTX_AUDIO,&AMP;PKT) < 0) {continue;} if (Avcodec_decode_audio4 (PFORMATCTX_AUDIO-&GT;STREAMS[0]-&GT;codec, Frame, &gotframe, &AMP;PKT) < 0) {Av_frame_free (&frame);p rintf ("Can not decoder a frame"); Av_free_packet (&AMP;PKT); if (!gotframe) {continue;//did not get to data, continue next}if (NULL = = Fifo_audio) {Fifo_audio = Av_audio_fifo_ Alloc (PFORMATCTX_AUDIO-&GT;STREAMS[0]-&GT;CODEC-&GT;SAMPLE_FMT, pformatctx_audio->streams[0]->codec-> Channels, * frame->nb_samples);} int buf_space = Av_audio_fifo_space (Fifo_audio), if (Av_audio_fifo_space (fifo_audio) >= frame->nb_samples) { EnterCriticalSection (&audiosection); Av_audio_fifo_write (Fifo_audio, (void * *) Frame->data, frame->nb_ samples); LeaveCriticalSection (&audiosection);}} Av_frame_free (&frame); return 0;}
3. Project Address http://download.csdn.net/detail/dancing_night/8855409

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

FFmpeg Realization Recording screen + record

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.