|
发表于 2023-2-1 18:06:04
|
显示全部楼层
我又来了,这一次不贴图片了,贴视频,^_^
使用了ffmpeg这个库,目前只实现了视频,音频部分的代码还没写
要实现烟花动画,那就找一个烟花的视频
另外,有屏幕的地方就有BadApple对吧,^_^
怎么做呢?简单,把BadApple.mp4改成test.mp4,然后放到这个exe文件所在的目录,运行这个exe就可以了
论坛限制,发不了gif动画效果,那就贴几个图片吧
【视频素材】顶级烟花视频素材包无版权无水印[1080p HD]:https://www.bilibili.com/video/B ... 7311a641effed03ee60
- #include <stdio.h>
- #include <windows.h>
- #include <libavformat/avformat.h>
- #include <libavcodec/avcodec.h>
- #include <libswscale/swscale.h>
- #include <libavutil/time.h>
- #define SCREEN_WIDTH 1860
- #define SCREEN_HEIGHT 930
- void output_audio_frame(const AVFrame *frame) {
- }
- void write_frame(const AVFrame *frame) {
- HBITMAP img = CreateBitmap(frame->width, frame->height, 1, 32, frame->data[0]);
- HWND hwnd = GetConsoleWindow();
- HDC hdc_cmd = GetDC(hwnd);
- HDC hdc_img = CreateCompatibleDC(NULL);
- HGDIOBJ obj_hdc = SelectObject(hdc_img, img);
- BITMAP bm; GetObject(img, sizeof(BITMAP), &bm);
- BitBlt(hdc_cmd, 0, 0, bm.bmWidth, bm.bmHeight, hdc_img, 0, 0, SRCCOPY);
- SelectObject(hdc_img, obj_hdc);
- DeleteDC(hdc_img);
- ReleaseDC(hwnd, hdc_cmd);
- DeleteObject(img);
- }
- void output_video_frame(const AVFrame *frame) {
- int width = frame->width;
- int height = frame->height;
- struct SwsContext *sws_ctx = sws_getContext(width, height, frame->format, SCREEN_WIDTH, SCREEN_HEIGHT, \
- AV_PIX_FMT_BGRA, SWS_FAST_BILINEAR, NULL, NULL, NULL);
- AVFrame *frame_bgra = av_frame_alloc();
- frame_bgra->format = AV_PIX_FMT_BGRA;
- frame_bgra->width = SCREEN_WIDTH;
- frame_bgra->height = SCREEN_HEIGHT;
- av_frame_get_buffer(frame_bgra, 4);
- sws_scale(sws_ctx, (const uint8_t *const *)frame->data, frame->linesize, 0, height, frame_bgra->data, \
- frame_bgra->linesize);
- write_frame(frame_bgra);
- av_frame_free(&frame_bgra);
- sws_freeContext(sws_ctx);
- }
- void decode_packet(AVCodecContext *dec_ctx, const AVPacket *packet) {
- avcodec_send_packet(dec_ctx, packet);
- AVFrame *frame = av_frame_alloc();
- while(!avcodec_receive_frame(dec_ctx, frame)) {
- if(dec_ctx->codec->type == AVMEDIA_TYPE_AUDIO) output_audio_frame(frame);
- if(dec_ctx->codec->type == AVMEDIA_TYPE_VIDEO) output_video_frame(frame);
- av_frame_unref(frame);
- }
- av_frame_free(&frame);
- }
- int main(void) {
- const char *filename = "test.mp4";
- AVFormatContext *fmt_ctx = NULL;
- avformat_open_input(&fmt_ctx, filename, NULL, NULL);
- avformat_find_stream_info(fmt_ctx, NULL);
- av_dump_format(fmt_ctx, 0, filename, 0);
- int audio_stream_idx = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
- int video_stream_idx = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
- AVStream *audio_stream = fmt_ctx->streams[audio_stream_idx];
- AVStream *video_stream = fmt_ctx->streams[video_stream_idx];
- const AVCodec *audio_dec = avcodec_find_decoder(audio_stream->codecpar->codec_id);
- const AVCodec *video_dec = avcodec_find_decoder(video_stream->codecpar->codec_id);
- AVCodecContext *audio_dec_ctx = avcodec_alloc_context3(audio_dec);
- AVCodecContext *video_dec_ctx = avcodec_alloc_context3(video_dec);
- avcodec_parameters_to_context(audio_dec_ctx, audio_stream->codecpar);
- avcodec_parameters_to_context(video_dec_ctx, video_stream->codecpar);
- avcodec_open2(audio_dec_ctx, audio_dec, NULL);
- avcodec_open2(video_dec_ctx, video_dec, NULL);
- AVPacket *packet = av_packet_alloc();
- int64_t start_time = av_gettime();
- while(!av_read_frame(fmt_ctx, packet)) {
- AVCodecContext *dec_ctx = NULL;
- int stream_idx = packet->stream_index;
- dec_ctx = stream_idx == audio_stream_idx ? audio_dec_ctx : dec_ctx;
- dec_ctx = stream_idx == video_stream_idx ? video_dec_ctx : dec_ctx;
- if(dec_ctx) decode_packet(dec_ctx, packet);
- int64_t pts = av_rescale_q(packet->pts, fmt_ctx->streams[stream_idx]->time_base, \
- av_make_q(1, AV_TIME_BASE));
- int64_t now_time = av_gettime() - start_time;
- if(pts > now_time) av_usleep(pts - now_time);
- av_packet_unref(packet);
- }
- decode_packet(audio_dec_ctx, NULL);
- decode_packet(video_dec_ctx, NULL);
- av_packet_free(&packet);
- avcodec_free_context(&video_dec_ctx);
- avcodec_free_context(&audio_dec_ctx);
- avformat_close_input(&fmt_ctx);
- return 0;
- }
复制代码
|
|