音視頻處理 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.pswp.cn/news/446034.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/446034.shtml
英文地址,請注明出處:http://en.pswp.cn/news/446034.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python非阻塞多線程socket_Python實現web服務器之 單進程單線程非阻塞實現并發及其原理...

在Python實現web服務器入門學習多進程、多線程實現并發HTTP服務器中&#xff0c;我們知道可以分別通過多進程、多線程的方式實現并發服務器&#xff0c;那么&#xff0c;是否可以通過單進程單線程的程序實現類似功能呢?實際上&#xff0c;在Python多任務學習分別通過yield關鍵…

企業知識庫與知識管理:如何統一戰略與實踐

在知識密集型的現代企業中&#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)在條碼打印軟件中設計好標簽之后&#…

python安裝scrapy_Python安裝Scrapy的種種

這幾天沒什么事&#xff0c;決定把自己抓代理的小工具用scrapy改寫。然而安裝的時候卻出現以下問題&#xff0c;反復失敗&#xff1a;Unable to find vcvarsall.bat經過一番查找&#xff0c;找到了這個文件&#xff1a;\Lib\distutils\_msvccompiler.py它里邊長這樣&#xff1a…

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…