网站建设一龙条seo站群系统

当前位置: 首页 > news >正文

网站建设一龙条,seo站群系统,设计类专业必须要美术生吗,专业网站建设微信网站定制从视频中获取图片是一个比较直观的例子#xff0c;这里从一个基础的例子来查看FFmpeg相关api的使用#xff0c;从mp4文件中获取一帧图像#xff0c;保存为jpeg格式图片#xff0c;mp4文件比较好准备#xff0c;一般手机录屏文件就是mp4格式。 原理还是比较清楚#xff0…从视频中获取图片是一个比较直观的例子这里从一个基础的例子来查看FFmpeg相关api的使用从mp4文件中获取一帧图像保存为jpeg格式图片mp4文件比较好准备一般手机录屏文件就是mp4格式。 原理还是比较清楚得到一个AVFrame后再使用jpeg的编码器来转换 int getpic() {std::string filename test.mp4; // 输入MP4文件名std::string outputFilename output.jpg; // 输出图片文件名int targetSecond 1; // 目标秒数AVFormatContext* formatContext nullptr;if (avformat_open_input(formatContext, filename.c_str(), nullptr, nullptr) ! 0) {std::cerr Error opening input file std::endl;return -1;}if (avformat_find_stream_info(formatContext, nullptr) 0) {std::cerr Error finding stream information std::endl;avformat_close_input(formatContext);return -1;}const AVCodec* codec nullptr;int videoStreamIndex -1;for (unsigned int i 0; i formatContext-nb_streams; i) {if (formatContext-streams[i]-codecpar-codec_type AVMEDIA_TYPE_VIDEO) {videoStreamIndex i;codec avcodec_find_decoder(formatContext-streams[i]-codecpar-codec_id);break;}}if (videoStreamIndex -1 || codec nullptr) {std::cerr Error finding video stream or decoder std::endl;avformat_close_input(formatContext);return -1;}AVCodecContext* codecContext avcodec_alloc_context3(codec);if (codecContext nullptr) {std::cerr Error allocating codec context std::endl;avformat_close_input(formatContext);return -1;}if (avcodec_parameters_to_context(codecContext, formatContext-streams[videoStreamIndex]-codecpar) 0) {std::cerr Error setting codec parameters std::endl;avcodec_free_context(codecContext);avformat_close_input(formatContext);return -1;}if (avcodec_open2(codecContext, codec, nullptr) 0) {std::cerr Error opening codec std::endl;avcodec_free_context(codecContext);avformat_close_input(formatContext);return -1;}AVPacket packet;av_init_packet(packet);// 计算目标时间戳int64_t targetTimestamp targetSecond * AV_TIME_BASE;// 查找目标时间戳所对应的帧AVFrame* frame av_frame_alloc();bool foundTargetFrame false;int count 0;while (av_read_frame(formatContext, packet) 0) {if (packet.stream_index videoStreamIndex) {int response avcodec_send_packet(codecContext, packet);if (response 0) {std::cerr Error sending packet to decoder std::endl;break;}count;response avcodec_receive_frame(codecContext, frame);if (response AVERROR(EAGAIN) || response AVERROR_EOF) {continue;}else if (response 0) {std::cerr Error receiving frame from decoder std::endl;break;}// 检查帧的时间戳是否接近目标时间戳/if (frame-pts targetTimestamp - (AV_TIME_BASE / 2) frame-pts targetTimestamp (AV_TIME_BASE / 2)) {foundTargetFrame true;break;}/if (count 20) {foundTargetFrame true;char outname[] out.jpg; // savePicture(frame, outname);break;}}av_packet_unref(packet);}if (!foundTargetFrame) {std::cerr Target frame not found std::endl;av_frame_free(frame);avcodec_free_context(codecContext);avformat_close_input(formatContext);return -1;}// 将帧的数据保存为JPEG图片AVFrame* rgbFrame av_frame_alloc();if (rgbFrame nullptr) {std::cerr Error allocating RGB frame std::endl;av_frame_free(frame);avcodec_free_context(codecContext);avformat_close_input(formatContext);return -1;}/struct SwsContext swsContext sws_getContext(codecContext-width, codecContext-height, codecContext-pix_fmt,codecContext-width, codecContext-height, AV_PIX_FMT_RGB24,SWS_BILINEAR, nullptr, nullptr, nullptr);if (swsContext nullptr) {std::cerr Error creating SwsContext std::endl;av_frame_free(frame);av_frame_free(rgbFrame);avcodec_free_context(codecContext);avformat_close_input(formatContext);return -1;}// 分配RGB帧的缓冲区int numBytes av_image_get_buffer_size(AV_PIX_FMT_RGB24, codecContext-width, codecContext-height, 1);uint8_t* buffer (uint8_t*)av_malloc(numBytes * sizeof(uint8_t));av_image_fill_arrays(rgbFrame-data, rgbFrame-linesize, buffer, AV_PIX_FMT_RGB24, codecContext-width, codecContext-height, 1);// 将解码后的帧转换为RGB格式sws_scale(swsContext, frame-data, frame-linesize, 0, codecContext-height, rgbFrame-data, rgbFrame-linesize);/// 保存RGB帧为JPEG图片const AVCodec jpegCodec avcodec_find_encoder(AV_CODEC_ID_MJPEG);if (jpegCodec nullptr) {std::cerr Error finding JPEG encoder std::endl;av_frame_free(frame);av_frame_free(rgbFrame);avcodec_free_context(codecContext);avformat_close_input(formatContext);return -1;}AVCodecContext* jpegCodecContext avcodec_alloc_context3(jpegCodec);if (jpegCodecContext nullptr) {std::cerr Error allocating JPEG codec context std::endl;av_frame_free(frame);av_frame_free(rgbFrame);avcodec_free_context(codecContext);avformat_close_input(formatContext);return -1;}jpegCodecContext-pix_fmt AV_PIX_FMT_YUVJ420P;jpegCodecContext-width codecContext-width;jpegCodecContext-height codecContext-height;// 设置编码器时间基jpegCodecContext-time_base { 1, 25 };//formatContext-streams[videoStreamIndex]-time_base;if (avcodec_open2(jpegCodecContext, jpegCodec, nullptr) 0) {std::cerr Error opening JPEG codec std::endl;av_frame_free(frame);av_frame_free(rgbFrame);avcodec_free_context(codecContext);avcodec_free_context(jpegCodecContext);avformat_close_input(formatContext);return -1;}AVPacket jpegPacket;av_init_packet(jpegPacket);jpegPacket.data nullptr;jpegPacket.size 0;if (avcodec_send_frame(jpegCodecContext, frame) 0) {//rgbFramestd::cerr Error sending frame to JPEG encoder std::endl;av_frame_free(frame);av_frame_free(rgbFrame);avcodec_free_context(codecContext);avcodec_free_context(jpegCodecContext);avformat_close_input(formatContext);return -1;}if (avcodec_receive_packet(jpegCodecContext, jpegPacket) 0) {std::cerr Error receiving packet from JPEG encoder std::endl;av_frame_free(frame);av_frame_free(rgbFrame);avcodec_free_context(codecContext);avcodec_free_context(jpegCodecContext);avformat_close_input(formatContext);return -1;}// 保存JPEG图像到文件FILE* outputFile fopen(outputFilename.c_str(), wb);if (outputFile nullptr) {std::cerr Error opening output file std::endl;av_frame_free(frame);av_frame_free(rgbFrame);avcodec_free_context(codecContext);avcodec_free_context(jpegCodecContext);avformat_close_input(formatContext);return -1;}fwrite(jpegPacket.data, 1, jpegPacket.size, outputFile);fclose(outputFile);// 清理资源av_frame_free(frame);av_frame_free(rgbFrame);av_packet_unref(packet);av_packet_unref(jpegPacket);avcodec_free_context(codecContext);return 1; } 获取的图片看上去不是太清晰字有些糊掉了 从AVFrame保存为jpg图片的处理可以有另外的一个方式有些差异 int savePicture(AVFrame* pFrame, char* out_name) {//编码保存图片int width pFrame-width;int height pFrame-height;AVCodecContext* pCodeCtx NULL;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(Couldnt open output file.);return -1;}// 构建一个新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_YUVJ420P;parameters-width pFrame-width;parameters-height pFrame-height;const AVCodec* pCodec avcodec_find_encoder(pAVStream-codecpar-codec_id); //查找编码器if (!pCodec) {printf(Could not find encoder\n);return -1;}pCodeCtx avcodec_alloc_context3(pCodec); //为AVCodecContext分配内存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;}// AVRational tmp { 1, 25 };pCodeCtx-time_base { 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);// 编码数据ret 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);//Write Trailerav_write_trailer(pFormatCtx);avcodec_close(pCodeCtx);avio_close(pFormatCtx-pb);avformat_free_context(pFormatCtx);return 0; }参考资料 FFmpeg将视频转换成一帧一帧的jpeg图片(代码实现)_ffmpeg把视频转为一帧帧图片-CSDN博客