音视频处理 ffmpeg中级开发 视频转图片

操作流程

  • 目的:使用FFmpeg将视频的每一帧数据转换为图片
  • 1,打开输入的多媒体文件,检索多媒体文件中的流信息
  • 2,查找视频流的索引号,通过索引号获取数据流;通过解析视频流中的编码参数得到解码器ID,进一步通过编码器ID获取编码器
  • 3,创建输出上下文环境,并将视频流中的编解码参数拷贝到输出上下文环境中(结构体)
  • 4,循环读取视频流中的每一帧数据进行解码
  • 5,将解码后的数据进行图像色彩的空间转换、分辨率的缩放、前后图像滤波处理等,涉及到sws_getContext()、sws_scale()、sws_freeContext()这三个函数,分别进行初始化、转换、释放。
  • 转换后 加入 图片的头部信息进行保存
  • 参考链接:
  • FFmpeg将视频转为图片 - 简书                                                                     未成功
  • FFmpeg代码实现视频转jpg图片_Geek.Fan的博客-CSDN博客_ffmpeg jpg  成功
  • 1).打开视频文件;(2)获取视频流;(3)找到对应的解码器;(4).初始化解码器上下文;(5).设置编解码器参数;(6)打开解码器;(7)读取视频帧;(8)发送等待解码帧;(9).接收解码帧数据;

补充链接

  • #pragma pack(2)意义与用法_Toryci的博客-CSDN博客_#pragma pack(2)
  • FFmpeg新旧接口对照使用一览 - schips - 博客园
  • FFmpeg: Image related  官方文档:av_image_get_buffer_size
  • av_image_get_buffer_size 与 av_image_fill_arrays_jackuylove的博客-程序员宅基地_av_image_get_buffer_size - 程序员宅基地

补充知识

两台Ubuntu之间通过scp进行数据的传输

  • 协议 传输的文件 接收端的账户 接收端的ip地址 文件的存储路径
  • scp test.mp4 root@192.168.253.131:/home/chy-cpabe/Videos 
  • 输入密码

avpicture_get_size

  • avpicture_get_size已经被弃用,现在改为使用av_image_get_size()
  • 具体用法如下:
    • old: avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
    • new: //最后一个参数align这里是置1的,具体看情况是否需要置1
    • av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1);

avpicture_fill

  • avpicture_fill已经被弃用,现在改为使用av_image_fill_arrays
  • 具体用法如下:
    • old: avpicture_fill((AVPicture *)pFrame, buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
    • new: //最后一个参数align这里是置1的,具体看情况是否需要置1
    • av_image_fill_arrays(pFrame->data, pFrame->linesize, buffer,  AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height,1);

avcodec_decode_video2

  • 原本的解码函数被拆解为两个函数avcodec_send_packet()和avcodec_receive_frame()
  • 具体用法如下:
    • old: avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, pPacket);
    • new: avcodec_send_packet(pCodecCtx, pPacket); avcodec_receive_frame(pCodecCtx, pFrame);
ret = avcodec_send_packet(pCodecCtx, packet);got_picture = avcodec_receive_frame(pCodecCtx, pFrame); //got_picture = 0 success, a frame was returned//注意:got_picture含义相反或者:int ret = avcodec_send_packet(aCodecCtx, &pkt);if (ret != 0){prinitf("%s/n","error");return;}while( avcodec_receive_frame(aCodecCtx, &frame) == 0){//读取到一帧音频或者视频//处理解码后音视频 frame}

代码

#include <cstdio>
#include <cstdlib>
#include <cstring>extern "C" {
#include <libavformat/avformat.h>
#include<libavcodec/avcodec.h>
#include<libswscale/swscale.h>
#include <libavutil/imgutils.h>
}int SavePicture(AVFrame* pFrame,char* out_name){int width = pFrame->width;int height = pFrame->height;AVCodecContext *pCodeCtx = nullptr;AVFormatContext *pFormatCtx = avformat_alloc_context();// 设置输出文件格式pFormatCtx->oformat = av_guess_format("mjpeg",NULL,NULL);// 创建并初始化输出AVIOContextif (avio_open(&pFormatCtx->pb,out_name,AVIO_FLAG_READ_WRITE) < 0){printf("Couldn't open output file.");return -1;}//create streamAVStream *pAVStream = avformat_new_stream(pFormatCtx,0);if (pAVStream == NULL){return -1;}AVCodecParameters *parameters = pAVStream->codecpar;parameters->codec_id = pFormatCtx->oformat->video_codec;parameters->codec_type = AVMEDIA_TYPE_VIDEO;parameters->format = AV_PIX_FMT_YUV420P;parameters->width = pFrame->width;parameters->height = pFrame->height;AVCodec *pCodec = const_cast<AVCodec *>(avcodec_find_encoder(pAVStream->codecpar->codec_id));if (!pCodec){printf("Could not find encoder\n");return -1;}pCodeCtx = avcodec_alloc_context3(pCodec);if (!pCodeCtx){fprintf(stderr,"Could not allocate video codec context\n");exit(1);}if ((avcodec_parameters_to_context(pCodeCtx,pAVStream->codecpar)) < 0){fprintf(stderr,"Failed to copy %s codec parameters to decoder context\n",av_get_media_type_string(AVMEDIA_TYPE_VIDEO));return -1;}pCodeCtx->time_base = (AVRational){1,25};if (avcodec_open2(pCodeCtx,pCodec,NULL) < 0){printf("Could not open codec.");return -1;}int ret = avformat_write_header(pFormatCtx,NULL);if (ret < 0){printf("Write_header fail\n");return -1;}int y_size = width * height;//Encode//给AVPacket分配足够大的空间AVPacket pkt;av_new_packet(&pkt,y_size*3);//encode dataret = avcodec_send_frame(pCodeCtx,pFrame);if (ret < 0){printf("Could not avcodec_send_frame");return -1;}//得到编码后数据ret = avcodec_receive_packet(pCodeCtx,&pkt);if (ret < 0){printf("Could not avcodec_receive_packet");return -1;}ret = av_write_frame(pFormatCtx,&pkt);if (ret < 0){printf("Could not av_write_frame");return -1;}av_packet_unref(&pkt);av_write_trailer(pFormatCtx);avcodec_close(pCodeCtx);avio_close(pFormatCtx->pb);avformat_free_context(pFormatCtx);return 0;
}int main(int argc,char** argv){int ret = 0;const char* in_filename,*out_filename;AVFormatContext *fmt_ctx = NULL;const AVCodec *codec;AVCodecContext *codeCtx = NULL;AVStream *stream = NULL;int stream_index = 0;AVPacket avpkt;AVFrame *frame;int frame_count = 0;if (argc <= 2){printf("Usage:%s <input file> <output file>\n",argv[0]);exit(0);}in_filename = argv[1];out_filename = argv[2];if (avformat_open_input(&fmt_ctx,in_filename,NULL,NULL) < 0){printf("Could not open source file %s \n",in_filename);exit(1);}if (avformat_find_stream_info(fmt_ctx,NULL)<0){printf("Could not find stream information\n");exit(1);}av_dump_format(fmt_ctx,0,in_filename,0);av_init_packet(&avpkt);avpkt.data = NULL;avpkt.size = 0;stream_index = av_find_best_stream(fmt_ctx,AVMEDIA_TYPE_VIDEO,-1,-1,NULL,0);if (stream_index < 0){fprintf(stderr,"Could not find %s stream in input file '%s'\n",av_get_media_type_string(AVMEDIA_TYPE_VIDEO),in_filename);return stream_index;}stream = fmt_ctx->streams[stream_index];codec = avcodec_find_decoder(stream->codecpar->codec_id);if (!codec){return -1;}codeCtx = avcodec_alloc_context3(NULL);if (!codeCtx){fprintf(stderr,"Could not allocate video codec context\n");exit(1);}if (avcodec_parameters_to_context(codeCtx,stream->codecpar)<0){fprintf(stderr,"Failed to copy %s codec parameters to decoder context\n",av_get_media_type_string(AVMEDIA_TYPE_VIDEO));return -1;}avcodec_open2(codeCtx,codec,NULL);frame = av_frame_alloc();if (!frame){fprintf(stderr,"Could not allocate video frame\n");exit(1);}char buf[1024];while(av_read_frame(fmt_ctx,&avpkt) >= 0){if (avpkt.stream_index == stream_index){ret = avcodec_send_packet(codeCtx,&avpkt);if (ret < 0){continue;}while (avcodec_receive_frame(codeCtx,frame) == 0){snprintf(buf,sizeof (buf),"%s/picture-%d.jpg",out_filename,frame_count);SavePicture(frame,buf);}frame_count++;}av_packet_unref(&avpkt);}return 0;
}

运行结果

错误代码

#include <cstdio>
#include <cstdlib>
#include <cstring>extern "C" {#include <libavformat/avformat.h>#include<libavcodec/avcodec.h>#include<libswscale/swscale.h>#include <libavutil/imgutils.h>
}#define INBUF_SIZE 4096#define WORD uint16_t
#define DWORD uint32_t
#define LONG int32_t#pragma pack(2)
// 位图文件头(bitmap-file header)包含了图像类型、图像大小、图像数据存放地址和两个保留未使用的字段
typedef struct tagBITMAPFILEHEADER{WORD bfType;DWORD bfSize;WORD bfReserved1;WORD bfReserved2;DWORD bfOffBits;
}BITMAPFILEHEADER,*PBITMAPFILEHEADER;
// 位图信息头(bitmap-information header)包含了位图信息头的大小、图像的宽高、图像的色深、压缩说明图像数据的大小和其他一些参数。
typedef struct tagBITMAPINFOHEADER{DWORD biSize;LONG  biWidth;LONG  biHeight;LONG  biPlans;LONG  biBitCount;DWORD biCompression;DWORD biSizeImage;LONG  biXPelsPerMeter;LONG  biYPelsPerMeter;DWORD biClrUsed;DWORD biClrImportant;
}BITMAPINFOHEADER,*PBITMAPINFOHEADER;
//图片转换并保存
void saveBMP(struct SwsContext* img_convert_ctx,AVFrame* frame,char* filename){//1 先进行转换,  YUV420=>RGB24:int w = frame->width;int h = frame->height;int numBytes = av_image_get_buffer_size(AV_PIX_FMT_BGR24,w,h,1);uint8_t *buffer = (uint8_t *) av_malloc(numBytes * sizeof (uint8_t));AVFrame *pFrameRGB = av_frame_alloc();//buffer is going to be written to rawvideo file,no alignmentav_image_fill_arrays(pFrameRGB->data,pFrameRGB->linesize,buffer,AV_PIX_FMT_BGR24,w,h,1);/*进行转换frame->data和pFrameRGB->data分别指输入和输出的bufframe->linesize和pFrameRGB->linesize可以看成是输入和输出的每列的byte数第4个参数是指第一列要处理的位置第5个参数是source slice 的高度*/sws_scale(img_convert_ctx,frame->data,frame->linesize,0,h,pFrameRGB->data,pFrameRGB->linesize);//2 create BITMAPINFOHEADERBITMAPINFOHEADER header;header.biSize = sizeof (BITMAPINFOHEADER);header.biWidth = w;header.biHeight = h*(-1);header.biBitCount = 24;header.biSizeImage = 0;header.biClrImportant = 0;header.biClrUsed = 0;header.biXPelsPerMeter = 0;header.biYPelsPerMeter = 0;header.biPlans = 1;//3 create file headerBITMAPFILEHEADER bmpFileHeader = {0,};//HANDLE hFILE = NULL;DWORD dwTotalWriten = 0;DWORD dwWriten;bmpFileHeader.bfType = 0x4d42;//'BM'bmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) + numBytes;bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER);FILE *pf = fopen(filename,"wb");fwrite(&bmpFileHeader,sizeof (BITMAPFILEHEADER),1,pf);fwrite(&header,sizeof (BITMAPINFOHEADER),1,pf);fwrite(pFrameRGB->data[0],1,numBytes,pf);fclose(pf);//4 释放资源//av_free(buffer);av_free(&pFrameRGB[0]);av_free(pFrameRGB);
}static void pgm_save(unsigned char* buf,int wrap,int x_size,int y_size,char* filename){FILE *f;int i;f = fopen(filename,"w");fprintf(f,"P5\n%d %d\n%d\n",x_size,y_size,255);for (i = 0; i < y_size; ++i) {fwrite(buf+i*wrap,1,x_size,f);}fclose(f);
}//对数据进行解码
static int decode_write_frame(const char* outfilename,AVCodecContext *avctx,struct SwsContext* img_convert_ctx,AVFrame *frame,int* frame_count,AVPacket *pkt,int last){int ret,got_frame;char buf[1024];// 对数据进行解码,avctx是编解码器上下文,解码后的帧存放在frame,通过got_frame获取解码后的帧,pkt是输入包ret = avcodec_send_packet(avctx,pkt);if (ret < 0){fprintf(stderr,"Error while decoding frame %d\n",*frame_count);return ret;}got_frame = avcodec_receive_frame(avctx,frame);// 解码成功if (got_frame){printf("Saving %s frame %3d\n",last?"last":" ",*frame_count);fflush(stdout);//The picture is allocated by the decoder,no need to free itsnprintf(buf,sizeof (buf),"%s-%d.bmp",outfilename,*frame_count);//解码后的数据帧保存rgb图片saveBMP(img_convert_ctx,frame,buf);(*frame_count)++;}return 0;
}int main(int argc,char** argv){int ret;FILE *f;// 输入、输出文件路径const char* filename,*outfilename;// 格式上下文环境(输入文件的上下文环境)AVFormatContext *fmt_ctx = nullptr;// 编解码器const AVCodec *codec;// 编解码器上下文环境(输出文件的上下文环境)AVCodecContext *codec_context = nullptr;// 多媒体文件中的流AVStream *stream = nullptr;// 流的indexint stream_index= 0;int frame_count;// 原始帧AVFrame *frame;// 图片处理的上下文struct SwsContext* img_convert_ctx;//uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];AVPacket avPacket;if (argc < 2){fprintf(stderr,"Usage: %s <input file> <out file>\n",argv[0]);exit(0);}filename =    argv[1];outfilename = argv[2];// 打开输入文件,创建格式上下文环境if (avformat_open_input(&fmt_ctx,filename,NULL,NULL) < 0){fprintf(stderr,"Could not open source file %s\n",filename);exit(1);}// 检索多媒体文件中的流信息if (avformat_find_stream_info(fmt_ctx,NULL) < 0){fprintf(stderr,"Could not find stream information\n");exit(1);}// 打印输入文件的详细信息av_dump_format(fmt_ctx,0,filename,0);av_init_packet(&avPacket);// 查找视频流,返回值ret是流的索引号ret = av_find_best_stream(fmt_ctx,AVMEDIA_TYPE_VIDEO,-1,-1,NULL,0);if (ret < 0){fprintf(stderr,"Could not find %d stream in input file '%s'\n",av_get_media_type_string(AVMEDIA_TYPE_VIDEO),filename);return ret;}// 根据索引号获取流stream_index = ret;stream = fmt_ctx->streams[stream_index];// 根据流中编码参数中的解码器ID查找解码器codec = avcodec_find_encoder(stream->codecpar->codec_id);if (!codec){fprintf(stderr,"Failed to find %s codec\n",av_get_media_type_string(AVMEDIA_TYPE_VIDEO));return AVERROR(EINVAL);}// 分配输出文件的上下文环境codec_context = avcodec_alloc_context3(codec);if (!codec_context){fprintf(stderr,"Could not allocate video codec context\n");exit(1);}// 将视频流的编解码参数直接拷贝到输出上下文环境中if (avcodec_parameters_to_context(codec_context,stream->codecpar) < 0){fprintf(stderr,"Failed to copy %s codec parameters to decoder context\n",av_get_media_type_string(AVMEDIA_TYPE_VIDEO));return ret;}// 打开解码器if (avcodec_open2(codec_context,codec,NULL)<0){fprintf(stderr,"Could not open codec\n");exit(1);}/*初始化图片转换上下文环境sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat,int dstW, int dstH, enum AVPixelFormat dstFormat,int flags, SwsFilter *srcFilter,SwsFilter *dstFilter, const double *param);srcW/srcH/srcFormat分别为原始图像数据的宽高和数据类型,数据类型比如AV_PIX_FMT_YUV420、PAV_PIX_FMT_RGB24dstW/dstH/dstFormat分别为输出图像数据的宽高和数据类型flags是scale算法种类;SWS_BICUBIC、SWS_BICUBLIN、SWS_POINT、SWS_SINC等最后3个参数不用管,都设为NULL*/img_convert_ctx = sws_getContext(codec_context->width,codec_context->height,codec_context->pix_fmt,codec_context->width,codec_context->height,AV_PIX_FMT_BGR24,SWS_BICUBIC,NULL,NULL,NULL);if (img_convert_ctx == NULL){fprintf(stderr,"cannot initialize the conversion context\n");exit(1);}frame = av_frame_alloc();if (!frame){fprintf(stderr,"Could not allocate video frame\n");exit(1);}// 循环从多媒体文件中读取一帧一帧的数据while (av_read_frame(fmt_ctx,&avPacket) >= 0){// 如果读取到的数据包的stream_index和视频流的stream_index一致就进行解码if (avPacket.stream_index == stream_index){if (decode_write_frame(outfilename,codec_context,img_convert_ctx,frame,&frame_count,&avPacket,0) < 0){exit(1);}}av_packet_unref(&avPacket);}/* Some codecs, such as MPEG, transmit the I- and P-frame with alatency of one frame. You must do the following to have achance to get the last frame of the video. */avPacket.data = NULL;avPacket.size = 0;decode_write_frame(outfilename,codec_context,img_convert_ctx,frame,&frame_count,&avPacket,1);fclose(f);avformat_close_input(&fmt_ctx);sws_freeContext(img_convert_ctx);avcodec_free_context(&codec_context);av_frame_free(&frame);return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/446034.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

企业知识库与知识管理:如何统一战略与实践

在知识密集型的现代企业中&#xff0c;知识已经成为了一种宝贵的资产。如何有效地管理和利用这一资产&#xff0c;成为企业持续发展与创新的关键。企业知识库与知识管理作为知识经济的两大支柱&#xff0c;它们的重要性不言而喻。但很多时候&#xff0c;我们发现企业的知识管理…

音视频处理 ffmpeg中级开发 AAC编码

介绍 编码流程类似于视频编码&#xff0c;1&#xff0c;查找编码器&#xff1b;2&#xff0c;设定参数&#xff0c;打开编码器&#xff1b;3&#xff0c;数据编码编码函数 avcodec_encode_audio2 已经被弃用FFmpeg 过时 Api 汇总整理 - 灰色飘零 - 博客园 未成功使用 旧版本i…

虚拟机为Ubuntu分配空间

当虚拟机里面的创建的ubuntu镜像需要更大的空间&#xff0c;将ubuntu关掉之后&#xff0c;对应调整硬盘的空间大小&#xff0c;由先前的20G上调至50G&#xff0c;但是先前的20G内存空间映射的位置是/dev/sda&#xff0c;后面增加的这段内存空间30G映射到/dev/sda1因此&#xff…

为什么人会摆高姿态_Yo , 你为什么喜欢冲浪?

“你为什么喜欢冲浪&#xff1f;” 那天木木突然问我。我愣住了。此时一道碧波恰从防泼堤&#xff08;jetty&#xff09;的那头升起&#xff0c;木木转头望去&#xff0c;视线追着那道浪缓缓向西&#xff0c;直至它破碎成白色的浪花。我瞥见他眼神中的光亮&#xff0c;就和小孩…

音视频处理 ffmpeg初级开发 命令行工具-实用命令

参考链接 ffmpeg Documentation作者&#xff1a;smallest_one 链接&#xff1a;FFmpeg命令行工具-实用命令 - 简书 目录 1&#xff0c;help命令使用 1.1 ffmpeg命令的语法结构1.2 获取详细的help信息1.3 打印帮助或者支持能力的信息1.4 全局选项1.5 文件选项1.6 视频/音频/字…

不同的电脑打印预览不同怎么解决_条码打印软件中标签预览正常打印无反应怎么解决...

在使用条码打印软件制作标签时&#xff0c;有客户反馈,标签打印预览正常的&#xff0c;但是打印无反应&#xff0c;咨询是怎么回事?今天针对这个情况&#xff0c;可以参考以下方法进行解决。一、预览正常情况下&#xff0c;打印没反应(1)在条码打印软件中设计好标签之后&#…

MP4文件格式的相关内容

参考链接 FFmpeg中mp4的demuxer(mov.c)代码阅读 - 简书mp4文件格式解析 - 简书mp4封装格式各box类型讲解及IBP帧计算_青丶空゛的博客-CSDN博客5分钟入门MP4文件格式 - 程序猿小卡 - 博客园​关于M4A文件的随机访问 - 云社区 - 腾讯云 MP4文件格式相关内容 MP4文件由许多box组…

华三交换机如何进入配置_学校机房项目交换机的如何配置,理解这篇,交换机配置不再难...

弱电项目中&#xff0c;交换机的配置是无法避免的&#xff0c;大部分的项目都有可能会涉及到&#xff0c;尤其是机房等网络项目&#xff0c;本期我们就通过一个实际项目案例来详细了解交换机在项目中的应用配置&#xff0c;如果我们平时对交换机配置不熟&#xff0c;这个案例可…

百度地图迁徙大数据_百度地图大数据:五一高速拥堵不似预期,广深成热门迁出入地...

五一假期在即&#xff0c;你是否做好了“出行功课”&#xff1f;高速拥堵水平降低、公众出门不出城、公园成踏青赏景热门目的地……在全国疫情防控仍未松懈的时刻&#xff0c;2020年的五一或许注定与往年不同。近日&#xff0c;百度地图发布2020五一假期安全出行大数据&#xf…

音视频的基础知识 视频播放器原理/封装格式/视频音频编码数据/视频像素数据/音频采样数据

参考链接 FFMpeg视频播放器的制作-雷霄骅&#xff08;去除电流音版本&#xff09;_哔哩哔哩_bilibili 视频播放器原理 播放视频文件的流程YUV是一张屏幕中像素点的数值封装格式 MP4 RMVB TS FLV AVI将视频和音频码流按照一定的格式存储在一个文件中封装格式分析工具&#xf…

科立捷7代写频软件_天大厦大“两硕士论文雷同”通报,代写买卖论文

澎湃新闻记者 薛莎莎天津大学、厦门大学7月10日晚就“两硕士论文雷同”一事&#xff0c;分别发出调查处理通报。通报称&#xff0c;涉事两名学生存在由他人代写、买卖论文的学术作假的行为&#xff0c;均撤销其所获硕士学位&#xff0c;收回、注销硕士学位证书。澎湃新闻注意到…

FFMpeg命令行基础

参考链接 FFMpeg视频播放器的制作-雷霄骅&#xff08;去除电流音版本&#xff09;_哔哩哔哩_bilibili音视频处理 ffmpeg初级开发 命令行工具-实用命令_MY CUP OF TEA的博客-CSDN博客 介绍 FFMpeg是视频播放和转码的内核 使用 win中ffmpeg.exe用于视频转码简单命令&#xff1…

悲观锁和乐观锁_面试必备之乐观锁与悲观锁

何谓悲观锁与乐观锁乐观锁对应于生活中乐观的人总是想着事情往好的方向发展&#xff0c;悲观锁对应于生活中悲观的人总是想着事情往坏的方向发展。这两种人各有优缺点&#xff0c;不能不以场景而定说一种人好于另外一种人。大家可以点击加群【JAVA架构知识学习讨论群】47398464…

Microsoft Visual Studio2019环境下搭建FFmpeg开发环境

参考链接 《基于 FFmpeg SDL 的视频播放器的制作》课程的视频_雷霄骅的博客-CSDN博客_雷霄骅ffmpeg视频教程小学期课程资料 - 基于FFmpegSDL的视频播放器的制作.zip_免费高速下载|百度网盘-分享无限制辅助参考链接使用VS2019创建项目&#xff0c;添加文件和库地址_MY CUP OF …

vue process.env获取不到_从文档开始,重学vue(下)源码级别

此篇文章主要是从应用及源码层面讲解vue部分常用api,阅读起来可能略有难度,新手可以看《从文档开始,重学vue(上)》示例代码均在vue-cli3中完成Vue.extend()可以使用 extend 创建一个子类,该方法通常用于构建全局组件,如弹框组件等,下面我们就用它来制作个全局alert组件吧首先我…

Microsoft Visual Studio2019环境下搭建SDL开发环境

参考链接 《基于 FFmpeg SDL 的视频播放器的制作》课程的视频_雷霄骅的博客-CSDN博客_雷霄骅ffmpeg视频教程小学期课程资料 - 基于FFmpegSDL的视频播放器的制作.zip_免费高速下载|百度网盘-分享无限制辅助参考链接VS自动链接到Windows上随vcpkg安装的SDL2库 | 码农俱乐部 - G…

不关注公众号可以获取openid吗_微信公众号粉丝迁移

目录 [toc] 微信公众号迁移 正常的公众号迁移直接通过微信操作就可以&#xff0c;如下图。但是因为udb数据里面存的是迁移前公众号的openid以及unionid,需要自行获取新旧openid以及unionid。 旧的用户信息要在迁移之前获取&#xff0c;第三步点击同意之后就公众号的接口就调不通…

建筑专业规范大全 2020版_房屋建筑工程现行规范标准目录汇编(2020版)—建筑电气...

房屋建筑工程现行规范标准目录汇编(2020版)建筑电气规范编号规范名称GB 50034-2013建筑照明设计标准GB 50052-2009供配电系统设计规范GB 50053-201320kV及以下变电所设计规范GB 50057-2010建筑物防雷设计规范GB 50147-2010电气装置安装工程 高压电器施工及验收规范GB 50148-201…

基于Microsoft Visual Studio2019环境编写ffmpeg视频解码代码

旧代码 旧代码使用了很多过时的API&#xff0c;这些API使用后&#xff0c;vs会报编译器警告 (级别 3) C4996的错误即 函数被声明为已否决 报 C4996的错误 // test_ffmpeg.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #define SDL_MAIN_HANDLED …

16进制转double dotnet_终于把计算机进制弄明白了!

And theres one thing that I need from you我只需要你为我做一-件事Can you come through, through待在我的身边就好Through, yeah你可以抚慰一切不满And theres one thing that I need from you你可以过来Can you come through?待在我的身边吗-comethruJeremy Zucker进制进制…