ffmpeg实现视频切割合并
ffmpeg实现视频切割:
http://blog.csdn.net/dancing_night/article/details/45720255
1、概述
本程序实现把一个视频切割为2个视频,不涉及编解码,最难理解的地方在于pts和dts的计算,要好好看看,不够完美的地方在于没有按照关键帧切割,所以会在切割点花屏,以后改善。
*注:只处理一个视频流和一个音频流,若流多了,估计会crash。
简单说下流程:
打开输入---->打开输出---->根据输入来创建流---->拷贝流设置---->循环读帧---->判断时间点是否到达切割点,并做设置---->设置pts和dts---->写入---->善后
2、代码
- /*
- *最简单的视频切割
- *缪国凯 Mickel
- *821486004@qq.com
- *本程序实现把一个视频切割为2个视频,不涉及编解码,最难理解的地方在于pts和dts的计算,要好好看看
- *不够完美的地方在于没有按照关键帧切割,所以会在切割点花屏,以后改善
- *注:只处理一个视频流和一个音频流,若流多了,估计会crash
- *2015-5-14
- */
- #include "stdafx.h"
- #ifdef __cplusplus
- extern"C"
- {
- #endif
- #include <libavformat/avformat.h>
- #include "libavcodec/avcodec.h"
- #include "libavfilter/avfiltergraph.h"
- #include "libavfilter/buffersink.h"
- #include "libavfilter/buffersrc.h"
- #include "libavutil/avutil.h"
- #include "libavutil/opt.h"
- #include "libavutil/pixdesc.h"
- #include "libswresample\swresample.h"
- #include "libavutil\fifo.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, "postproc.lib")
- #pragma comment(lib, "swresample.lib")
- //#pragma comment(lib, "swscale.lib")
- #ifdef __cplusplus
- };
- #endif
- int _tmain(int argc, _TCHAR* argv[])
- {
- if(argc < 3)
- {
- printf("no input file!\n");
- return -1;
- }
- AVFormatContext *ifmt_ctx = NULL, *ofmt1_ctx = NULL, *ofmt2_ctx = NULL;
- AVStream *out1_vstream = NULL, *out1_astream = NULL;
- AVStream *out2_vstream = NULL, *out2_astream = NULL;
- char str_out1_filename[10];
- char str_out2_filename[10];
- sprintf(str_out1_filename, "test1.%s", argv[2]);
- sprintf(str_out2_filename, "test2.%s", argv[2]);
- int inVideo_StreamIndex = -1,inAudio_StreamIndex = -1;
- int ret;
- av_register_all();
- if ((ret = avformat_open_input(&ifmt_ctx, argv[1], NULL, NULL)) < 0)
- {
- printf("can not open the in put file format context!\n");
- return -1;
- }
- if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0)
- {
- printf("can not find the input stream info!\n");
- goto end;
- }
- avformat_alloc_output_context2(&ofmt1_ctx, NULL, NULL, str_out1_filename);
- if (!ofmt1_ctx)
- {
- printf( "Could not create output1 context\n");
- ret = AVERROR_UNKNOWN;
- goto end;
- }
- avformat_alloc_output_context2(&ofmt2_ctx, NULL, NULL, str_out2_filename);
- if (!ofmt2_ctx)
- {
- printf( "Could not create output2 context\n");
- ret = AVERROR_UNKNOWN;
- goto end;
- }
- for (int i = 0; i < ifmt_ctx->nb_streams; i++)
- {
- if (ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
- {
- inVideo_StreamIndex = i;
- out1_vstream = avformat_new_stream(ofmt1_ctx, NULL);
- out2_vstream = avformat_new_stream(ofmt2_ctx, NULL);
- //open decoder
- if(0 > avcodec_open2(ifmt_ctx->streams[i]->codec, avcodec_find_decoder(ifmt_ctx->streams[i]->codec->codec_id), NULL))
- {
- printf("can not find or open video decoder!\n");
- goto end;
- }
- if (!out1_vstream)
- {
- printf("Failed allocating output1 video stream\n");
- ret = AVERROR_UNKNOWN;
- goto end;
- }
- else
- {
- //copy the settings of AVCodecContext;
- if (avcodec_copy_context(out1_vstream->codec, ifmt_ctx->streams[i]->codec) < 0)
- {
- printf( "Failed to copy context from input to output stream codec context\n");
- goto end;
- }
- out1_vstream->codec->codec_tag = 0;
- if(ofmt1_ctx->oformat->flags & AVFMT_GLOBALHEADER)
- {
- out1_vstream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
- }
- }
- if (!out2_vstream)
- {
- printf("Failed allocating output1 video stream\n");
- ret = AVERROR_UNKNOWN;
- goto end;
- }
- else
- {
- //copy the settings of AVCodecContext;
- if (avcodec_copy_context(out2_vstream->codec, ifmt_ctx->streams[i]->codec) < 0)
- {
- printf( "Failed to copy context from input to output stream codec context\n");
- goto end;
- }
- out2_vstream->codec->codec_tag = 0;
- if(ofmt2_ctx->oformat->flags & AVFMT_GLOBALHEADER)
- {
- out2_vstream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
- }
- }
- }
- else if (ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
- {
- inAudio_StreamIndex = i;
- out1_astream = avformat_new_stream(ofmt1_ctx, NULL);
- out2_astream = avformat_new_stream(ofmt2_ctx, NULL);
- if (!out1_astream)
- {
- printf("Failed allocating output1 video stream\n");
- ret = AVERROR_UNKNOWN;
- goto end;
- }
- else
- {
- //copy the settings of AVCodecContext;
- if (avcodec_copy_context(out1_astream->codec, ifmt_ctx->streams[i]->codec) < 0)
- {
- printf( "Failed to copy context from input to output stream codec context\n");
- goto end;
- }
- out1_astream->codec->codec_tag = 0;
- if(ofmt1_ctx->oformat->flags & AVFMT_GLOBALHEADER)
- {
- out1_astream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
- }
- }
- if (!out2_astream)
- {
- printf("Failed allocating output1 video stream\n");
- ret = AVERROR_UNKNOWN;
- goto end;
- }
- else
- {
- //copy the settings of AVCodecContext;
- if (avcodec_copy_context(out2_astream->codec, ifmt_ctx->streams[i]->codec) < 0)
- {
- printf( "Failed to copy context from input to output stream codec context\n");
- goto end;
- }
- out2_astream->codec->codec_tag = 0;
- if(ofmt2_ctx->oformat->flags & AVFMT_GLOBALHEADER)
- {
- out2_astream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
- }
- }
- }
- }
- //Dump Format------------------
- printf("\n==============Input Video=============\n");
- av_dump_format(ifmt_ctx, 0, argv[1], 0);
- printf("\n==============Output1============\n");
- av_dump_format(ofmt1_ctx, 0, str_out1_filename, 1);
- printf("\n==============Output2============\n");
- av_dump_format(ofmt2_ctx, 0, str_out1_filename, 1);
- printf("\n======================================\n");
- //open output1 file
- if (!(ofmt1_ctx->oformat->flags & AVFMT_NOFILE))
- {
- if (avio_open(&ofmt1_ctx->pb, str_out1_filename, AVIO_FLAG_WRITE) < 0)
- {
- printf( "Could not open output file '%s'", str_out1_filename);
- goto end;
- }
- }
- //open output2 file
- if (!(ofmt2_ctx->oformat->flags & AVFMT_NOFILE))
- {
- if (avio_open(&ofmt2_ctx->pb, str_out2_filename, AVIO_FLAG_WRITE) < 0)
- {
- printf( "Could not open output file '%s'", str_out2_filename);
- goto end;
- }
- }
- //write out 1 file header
- if (avformat_write_header(ofmt1_ctx, NULL) < 0)
- {
- printf( "Error occurred when opening video output file\n");
- goto end;
- }
- //write out 2 file header
- if (avformat_write_header(ofmt2_ctx, NULL) < 0)
- {
- printf( "Error occurred when opening video output file\n");
- goto end;
- }
- int splitPtsV = 0;//the real split video pts
- int splitDtsV = 0;
- int splitPtsA = 0;//the real split audio pts
- int splitDtsA = 0;
- int videoIndex = 0;//the real video index
- int splitTime = 30;//the split time (sec)
- AVPacket pkt;
- while(1)
- {
- AVFormatContext *ofmt_ctx;
- AVStream *in_stream, *out_stream;
- if (av_read_frame(ifmt_ctx, &pkt) < 0)
- {
- break;
- }
- in_stream = ifmt_ctx->streams[pkt.stream_index];
- if (pkt.stream_index == inVideo_StreamIndex)
- {
- videoIndex++;
- int time = pkt.pts * (((float)in_stream->time_base.num) / ((float)in_stream->time_base.den));
- if (time <= splitTime)
- {
- splitPtsV = pkt.pts;
- splitDtsV = pkt.dts;
- out_stream = ofmt1_ctx->streams[pkt.stream_index];
- ofmt_ctx = ofmt1_ctx;
- }
- else
- {
- pkt.pts = pkt.pts - splitPtsV;
- pkt.dts = pkt.dts - splitDtsV;
- out_stream = ofmt2_ctx->streams[pkt.stream_index];
- ofmt_ctx = ofmt2_ctx;
- }
- }
- else if (pkt.stream_index == inAudio_StreamIndex)
- {
- int time = pkt.pts * (((float)in_stream->time_base.num) / ((float)in_stream->time_base.den));
- if (time <= splitTime)
- {
- splitPtsA = pkt.pts;
- splitDtsA = pkt.dts;
- out_stream = ofmt1_ctx->streams[pkt.stream_index];
- ofmt_ctx = ofmt1_ctx;
- }
- else
- {
- pkt.pts = pkt.pts - splitPtsA;
- pkt.dts = pkt.dts - splitDtsA;
- out_stream = ofmt2_ctx->streams[pkt.stream_index];
- ofmt_ctx = ofmt2_ctx;
- }
- }
- pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
- pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
- pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
- pkt.pos = -1;
- //write into file
- if (av_interleaved_write_frame(ofmt_ctx, &pkt) < 0)
- {
- printf( "Error muxing packet\n");
- break;
- }
- av_free_packet(&pkt);
- }
- av_write_trailer(ofmt1_ctx);
- av_write_trailer(ofmt2_ctx);
- end:
- avformat_close_input(&ifmt_ctx);
- /* close output */
- if (ofmt1_ctx && !(ofmt1_ctx->oformat->flags & AVFMT_NOFILE))
- avio_close(ofmt1_ctx->pb);
- avformat_free_context(ofmt1_ctx);
- /* close output */
- if (ofmt2_ctx && !(ofmt2_ctx->oformat->flags & AVFMT_NOFILE))
- avio_close(ofmt2_ctx->pb);
- avformat_free_context(ofmt2_ctx);
- return 0;
- }
3、下载地址
http://download.csdn.net/detail/dancing_night/8699109
ffmpeg实现视频合并
http://blog.csdn.net/dancing_night/article/details/45724215
1、概述
简单说下流程:
打开输入---->打开输出---->根据输入来创建流---->拷贝流设置---->循环读帧---->判断第一个读完,改输入为第二个---->设置pts和dts---->写入---->善后
2、代码
- /*
- *最简单的视频合并
- *缪国凯 Mickel
- *821486004@qq.com
- *本程序实现把2个视频合并为一个视频,不涉及编解码,但是对视频源有要求,必须是相同的参数
- *着重理解第二个视频开始的时候的pts和dts计算
- *注:只处理一个视频流和一个音频流,若流多了,估计会crash
- *2015-5-14
- */
- #include "stdafx.h"
- #ifdef __cplusplus
- extern"C"
- {
- #endif
- #include <libavformat/avformat.h>
- #include "libavcodec/avcodec.h"
- #include "libavfilter/avfiltergraph.h"
- #include "libavfilter/buffersink.h"
- #include "libavfilter/buffersrc.h"
- #include "libavutil/avutil.h"
- #include "libavutil/opt.h"
- #include "libavutil/pixdesc.h"
- #include "libswresample\swresample.h"
- #include "libavutil\fifo.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, "postproc.lib")
- #pragma comment(lib, "swresample.lib")
- //#pragma comment(lib, "swscale.lib")
- #ifdef __cplusplus
- };
- #endif
- AVFormatContext *in1_fmtctx = NULL, *in2_fmtctx = NULL, *out_fmtctx = NULL;
- AVStream *out_video_stream = NULL, *out_audio_stream = NULL;
- int video_stream_index = -1, audio_stream_index = -1;
- int open_input(const char * in1_name, const char * in2_name)
- {
- int ret = -1;
- if ((ret = avformat_open_input(&in1_fmtctx, in1_name, NULL, NULL)) < 0)
- {
- printf("can not open the first input context!\n");
- return ret;
- }
- if ((ret = avformat_find_stream_info(in1_fmtctx, NULL)) < 0)
- {
- printf("can not find the first input stream info!\n");
- return ret;
- }
- if ((ret = avformat_open_input(&in2_fmtctx, in2_name, NULL, NULL)) < 0)
- {
- printf("can not open the first input context!\n");
- return ret;
- }
- if ((ret = avformat_find_stream_info(in2_fmtctx, NULL)) < 0)
- {
- printf("can not find the second input stream info!\n");
- return ret;
- }
- }
- int open_output(const char * out_name)
- {
- int ret = -1;
- if ((ret = avformat_alloc_output_context2(&out_fmtctx, NULL, NULL, out_name)) < 0)
- {
- printf("can not alloc context for output!\n");
- return ret;
- }
- //new stream for out put
- for (int i = 0; i < in1_fmtctx->nb_streams; i++)
- {
- if (in1_fmtctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
- {
- video_stream_index = i;
- out_video_stream = avformat_new_stream(out_fmtctx, NULL);
- if (!out_video_stream)
- {
- printf("Failed allocating output1 video stream\n");
- ret = AVERROR_UNKNOWN;
- return ret;
- }
- if ((ret = avcodec_copy_context(out_video_stream->codec, in1_fmtctx->streams[i]->codec)) < 0)
- {
- printf("can not copy the video codec context!\n");
- return ret;
- }
- out_video_stream->codec->codec_tag = 0;
- if(out_fmtctx->oformat->flags & AVFMT_GLOBALHEADER)
- {
- out_video_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
- }
- }
- else if (in1_fmtctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
- {
- audio_stream_index = i;
- out_audio_stream = avformat_new_stream(out_fmtctx, NULL);
- if (!out_audio_stream)
- {
- printf("Failed allocating output1 video stream\n");
- ret = AVERROR_UNKNOWN;
- return ret;
- }
- if ((ret = avcodec_copy_context(out_audio_stream->codec, in1_fmtctx->streams[i]->codec)) < 0)
- {
- printf("can not copy the video codec context!\n");
- return ret;
- }
- out_audio_stream->codec->codec_tag = 0;
- if(out_fmtctx->oformat->flags & AVFMT_GLOBALHEADER)
- {
- out_audio_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
- }
- }
- }
- //open output file
- if (!(out_fmtctx->oformat->flags & AVFMT_NOFILE))
- {
- if ((ret = avio_open(&out_fmtctx->pb, out_name, AVIO_FLAG_WRITE)) < 0)
- {
- printf("can not open the out put file handle!\n");
- return ret;
- }
- }
- //write out file header
- if ((ret = avformat_write_header(out_fmtctx, NULL)) < 0)
- {
- printf( "Error occurred when opening video output file\n");
- return ret;
- }
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- if(argc < 4)
- {
- printf("no input file!\n");
- return -1;
- }
- char out_name[20];
- sprintf(out_name, "combine.%s", argv[3]);
- av_register_all();
- if (0 > open_input(argv[1], argv[2]))
- {
- goto end;
- }
- if(0 > open_output(out_name))
- {
- goto end;
- }
- AVFormatContext *input_ctx = in1_fmtctx;
- AVPacket pkt;
- int pts_v, pts_a, dts_v, dts_a;
- while(1)
- {
- if(0 > av_read_frame(input_ctx, &pkt))
- {
- if (input_ctx == in1_fmtctx)
- {
- float vedioDuraTime, audioDuraTime;
- //calc the first media dura time
- vedioDuraTime = ((float)input_ctx->streams[video_stream_index]->time_base.num /
- (float)input_ctx->streams[video_stream_index]->time_base.den) * ((float)pts_v);
- audioDuraTime = ((float)input_ctx->streams[audio_stream_index]->time_base.num /
- (float)input_ctx->streams[audio_stream_index]->time_base.den) * ((float)pts_a);
- //calc the pts and dts end of the first media
- if (audioDuraTime > vedioDuraTime)
- {
- dts_v = pts_v = audioDuraTime / ((float)input_ctx->streams[video_stream_index]->time_base.num /
- (float)input_ctx->streams[video_stream_index]->time_base.den);
- dts_a++;
- pts_a++;
- }
- else
- {
- dts_a = pts_a = vedioDuraTime / ((float)input_ctx->streams[audio_stream_index]->time_base.num /
- (float)input_ctx->streams[audio_stream_index]->time_base.den);
- dts_v++;
- pts_v++;
- }
- input_ctx = in2_fmtctx;
- continue;
- }
- break;
- }
- if (pkt.stream_index == video_stream_index)
- {
- if (input_ctx == in2_fmtctx)
- {
- pkt.pts += pts_v;
- pkt.dts += dts_v;
- }
- else
- {
- pts_v = pkt.pts;
- dts_v = pkt.dts;
- }
- }
- else if (pkt.stream_index == audio_stream_index)
- {
- if (input_ctx == in2_fmtctx)
- {
- pkt.pts += pts_a;
- pkt.dts += dts_a;
- }
- else
- {
- pts_a = pkt.pts;
- dts_a = pkt.dts;
- }
- }
- pkt.pts = av_rescale_q_rnd(pkt.pts, input_ctx->streams[pkt.stream_index]->time_base,
- out_fmtctx->streams[pkt.stream_index]->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
- pkt.dts = av_rescale_q_rnd(pkt.dts, input_ctx->streams[pkt.stream_index]->time_base,
- out_fmtctx->streams[pkt.stream_index]->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
- pkt.pos = -1;
- if (av_interleaved_write_frame(out_fmtctx, &pkt) < 0)
- {
- printf( "Error muxing packet\n");
- //break;
- }
- av_free_packet(&pkt);
- }
- av_write_trailer(out_fmtctx);
- end:
- avformat_close_input(&in1_fmtctx);
- avformat_close_input(&in2_fmtctx);
- /* close output */
- if (out_fmtctx && !(out_fmtctx->oformat->flags & AVFMT_NOFILE))
- avio_close(out_fmtctx->pb);
- avformat_free_context(out_fmtctx);
- return 0;
- }
3、下载地址
ffmpeg实现视频切割合并相关推荐
- 【ffmpeg裁剪视频faster rcnn自动检测 via】全自动实现ffmpeg将视频切割为图片帧,再使用faster rcnn将图片中的人检测出来,最后将检测结果转化为via可识别的csv格式
目录 前言 一,ffmpeg 自动裁剪 1.1 目录结构 1.2 cutVideoToImage.sh 1.2 myVideo 1.3 myVideo15mins 1.5 myFrames 1.6 运 ...
- java使用ffmpeg视频切割聚合截图
环境信息: 操作系统:centos7 编程语言:java 安装ffmpeg # 安装epel扩展源 sudo yum install -y epel-release # 安装Nux Dextop Yu ...
- ffmpeg 将一个视频裁剪多个部分,然后合并所有的裁剪为一个视频
如果你想利用 ffmpeg 将一个视频裁剪为多个部分,然后合并所有的裁剪为一个视频, 那么你可以执行 : ffmpeg -i input -filter_complex "[0:v:0]se ...
- Java使用ffmpeg进行视频格式转换、音视频合并、播放、截图
封装类: ffplay.ffmpeg.ffprobe是安装的ffmpeg路径. import java.io.BufferedReader; import java.io.File; import j ...
- FFmpeg:视频转码、剪切、合并、播放速调整
安装 去官网按提示安装即可,支持三大操作系统.唯一要吐槽的是,Ubuntu 14.04 等较新的版本,从默认软件列表里移除了 ffmpeg,转而支持 libav,可是 libav 又没弄好,很难用-- ...
- python ffmpeg剪辑视频_用ffmpeg快速剪切和合并视频
如果直接找视频剪切和合并视频的软件,通常出来的都是大的视频编辑软件或者是有图形界面的剪切软件,大型一点的功能太多安装麻烦,小型一点的功能可能不齐全. 只是简单的剪切或者一下合并一下,还是ffmpeg这 ...
- 使用ffmpeg从视频文件中提取音频文件、视频抽帧和切割视频
目录 ffmpeg下载 使用ffmpeg从视频文件中提取音频文件 批量提取文件夹下多个视频文件的音频 使用ffmpeg从视频文件中提取视频帧 使用ffmpeg将按固定时长将视频切割成多个小片段 将分割 ...
- C++ 调用 ffmpeg.exe 执行音视频混流合并;
ffmpeg.exe文件可以去官网下载:FFmpeg 官网似乎不提供32位dll文件的下载了,但是可以下载exe文件来直接调用: #include <iostream> #include ...
- python使用danmaku2ass 将xml字幕转换成ass字幕+ffmpeg将ass字幕合并成含有字幕的视频
文章目录 配置 说明: 一.使用danmaku2ass 将xml字幕转换成ass字幕 项目地址(记得给人家点个赞,我已经默默的点过了): 使用步骤: 1.将项目下载下来, 2.保留danmaku2as ...
- FFMPEG将视频切片成ts文件并对ts文件进行ASE加密,并合并成M3U8操作方法
环境:centos7 开发语言:php 框架:视频转码服务系统 生成ASE加密文件需要用到的命令: #!/bin/sh BASE_URL=${1:-'.'} openssl rand 16 > ...
最新文章
- Array 数组去重 总结10方法(7)
- 如何在ROS中使用PCL—数据格式(1)
- [JAVA] java仿windows 字体设置选项卡
- AAAI 2020 | 滴滴东北大学提出自动结构化剪枝压缩算法框架,性能提升高达120倍...
- LCS005标准版部署之三
- git关闭密码自动存储_RobotFramework实战篇PC端web自动化demo及持续集成
- 谁说男生不能美美哒?2020中国男士美妆市场洞察报告.pdf(附下载链接)
- 谁说数学好编程就好了?MIT告诉你:不对!
- [译]git fetch
- 17 java 存在的问题(转)
- 前端----HTML
- You must install signalwire-client-c to build mod_signalwire
- MySQL做学生考勤系统_Jsp+Ssh+Mysql实现的Java Web学生考勤管理系统
- 学报格式和论文格式一样吗_求《浙江大学学报》的论文格式要求 - 论文投稿 - 小木虫 - 学术 科研 互动社区...
- 网络安全攻防实验室通关教程-注入关
- search_web_resources
- 将STM32 Flash的一部分虚拟为大容量存储设备 USB_Device
- MaximalRectangle
- 天耀18期 – 03.Java基本语法【作业】.
- mysql存储过程 根据查询的结果集向表中插入数据
热门文章
- 资阳停车场系统推荐_专业停车场系统维护业务广泛
- 拨号不能建立远程计算机的连接,彻底解决Win8、Win10系统宽带拨号出现“错误720:不能建立到远程计算机的连接”的问题...
- php图片加密管理系统,8tupian图片加密平台 v3.0
- 什么是m叉树_C#的λ表达式树(LambdaExpression)保姆级超详细简单入门教程
- C# 高并发场景下 共享内存 Actor并发模型到底哪个快?
- 公网ip经常变动的解决方法
- linux 备份 网络配置,如何备份已经配置好的虚拟机linux系统的网络..._网络编辑_帮考网...
- 订单业务中如何保证接口的幂等性
- html暴风粒子代码,魔兽世界课物品代码及gm指令大全(全部整理自网上).doc
- 电脑计算机睡眠和休眠模式区别,电脑休眠和睡眠的区别?