实验一 利用ffmpeg进行视音频信息提取 |音视频技术

FFmpeg代码实现抽取音频、视频数据 今天开始撸代码,首先使用FFmpeg的API抽取一个MP4文件的音频数据。 阅读详情

实验一 利用ffmpeg进行视音频信息提取 |音视频技术

一、实验目的

1、深入掌握视音频的基本参数信息
2、掌握ffmpeg编译环境配置
3、掌握和熟悉提取视音频文件的基本方法

二、实验要求

1、对ffmpeg的编译环境进行配置;
2、对一个视频文件,提取基本信息(例如,封装格式,码流,视频编码方式,音频编码方式,分辨率,帧率,时长等等),并输出为txt文档。结果与MediaInfo的信息对比,并截图;
3、对该视频文件,提取视频信息,保存为yuv格式。结果利用yuv播放器播放并截图;
4、对该视频文件,提取音频信息,保存为wav格式。结果利用adobe audition播放并截图。

1、环境配置
项目文件夹下在这里插入图片描述在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

2、提取基本信息并且对比存储
在这里插入图片描述
在这里插入图片描述
3、对该视频文件,提取视频信息,保存为yuv格式。结果利用yuv播放器播放并截图
在这里插入图片描述
在这里插入图片描述
4、对该视频文件,提取音频信息,保存为wav格式。结果利用adobe audition播放并截图

在这里插入图片描述

三、实验代码
#include <stdio.h>

#define __STDC_CONSTANT_MACROS

#ifdef _WIN32
 //Windows
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libswresample/swresample.h"
#include <libavutil/opt.h>
#include <libavutil/channel_layout.h>
#include <libavutil/samplefmt.h>
};
#else
 //Linux...
#ifdef __cplusplus
extern "C"
{
#endif
#include <libavformat/avformat.h>
#ifdef __cplusplus
};
#endif
#endif


//'1': Use H.264 Bitstream Filter 
#define USE_H264BSF 1
#define MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio  

typedef struct WAVE_HEADER {//共占12字节
	char         fccID[4]; //4bytes  RIFF
	unsigned   long    dwSize; //文件字节数-8    8=fccID(4)+dwSize(4)
	char         fccType[4]; //4bytes WAVE
}WAVE_HEADER;

typedef struct WAVE_FMT {//共占24字节
	char         fccSub1ID[4]; //4bytes "fmt "后面是个空格
	unsigned   long       dwSub1Size;//16,存储该子块的字节数(不含fccSub1ID和dwSub1Size这8个字节)
	unsigned   short     wFormatTag;//存储音频文件的编码格式,例如若为PCM则其存储值为1,若为其他非PCM格式的则有一定的压缩。
	unsigned   short    numChannels;//通道数,单通道(Mono)值为1,双通道(Stereo)值为2,等等
	unsigned   long     sampleRate;//采样率,如8k,44.1k等
	unsigned   long      byteRate;//每秒存储的字节数,其值=SampleRate * NumChannels * BitsPerSample/8
	unsigned   short     wBlockAlign;//块对齐大小,其值=NumChannels * BitsPerSample/8
	unsigned   short     uiBitsPerSample;//每个采样点(sample)的bit数,一般为8,16,32等。
}WAVE_FMT;

typedef struct WAVE_DATA {//共占8个字节
	char       fccSub2ID[4];//4bytes "data"
	unsigned long dwSub2Size;//内容为接下来的正式的数据部分的字节数,其值=NumSamples * NumChannels * BitsPerSample/8
}WAVE_DATA;

//wav文件大小字节数=dwSize+8=44+dwSub2Size  => dwSize=dwSub2Size+36

#define SIZE_WAV_HEADER 12
#define SIZE_WAV_FMT 24
#define SIZE_WAV_DATA 8


/*
numSamples:单个通道的总采样点数的总和值
return wav的文件头部指针
*/
char* set_wav_parm(int numSamples) {
	WAVE_HEADER* wavHEADER;
	WAVE_FMT* wavFMT;
	WAVE_DATA* wavDATA;

	wavHEADER = (WAVE_HEADER*)malloc(SIZE_WAV_HEADER);
	char* p = wavHEADER->fccID;
	wavFMT = (WAVE_FMT*)(p + SIZE_WAV_HEADER);
	wavDATA = (WAVE_DATA*)(p + SIZE_WAV_HEADER + SIZE_WAV_FMT);

	//head
	memcpy(wavHEADER->fccID, "RIFF", 4);
	memcpy(wavHEADER->fccType, "WAVE", 4);

	//fmt
	memcpy(wavFMT->fccSub1ID, "fmt ", 4);

	wavFMT->dwSub1Size = 16;
	wavFMT->wFormatTag = 1;
	wavFMT->numChannels = 2;
	wavFMT->sampleRate = 44100;
	wavFMT->uiBitsPerSample = 16;
	wavFMT->byteRate = (wavFMT->sampleRate * wavFMT->numChannels * wavFMT->uiBitsPerSample) / 8;
	wavFMT->wBlockAlign = (wavFMT->numChannels * wavFMT->uiBitsPerSample) / 8;

	//data
	memcpy(wavDATA->fccSub2ID, "data", 4);
	wavDATA->dwSub2Size = (numSamples * wavFMT->numChannels * wavFMT->uiBitsPerSample) / 8;

	wavHEADER->dwSize = wavDATA->dwSub2Size + 36;

	return p;


}

int main(int argc, char* argv[])
{
	AVFormatContext* ifmt_ctx = NULL;
	AVCodecContext* ifmt_CodecCtx = NULL;
	AVCodec* pCodec;
	AVFrame* pFrame, * pFrameYUV;
	uint8_t* out_buffer;
	AVPacket pkt;
	int ret, i, got_picture;
	int videoindex = -1, audioindex = -1;
	struct SwsContext* img_convert_ctx;
	const char* in_filename = "Titanic.ts";//Input file URL
	const char* out_filename_v = "Titanic.h264";//Output file URL
	const char* out_filename_yuv = "Titanic.yuv";
	const char* out_filename_a = "Titanic.mp3";

	av_register_all();
	avcodec_register_all();
	avformat_network_init();
	ifmt_ctx = avformat_alloc_context();
	//Input
	if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {
		printf("Could not open input file.");
		return -1;
	}
	if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {
		printf("Failed to retrieve input stream information");
		return -1;
	}

	videoindex = -1;
	for (i = 0; i < ifmt_ctx->nb_streams; i++) {
		if (ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
			videoindex = i;
		}
		else if (ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
			audioindex = i;
		}
	}
	//Dump Format------------------
	printf("\nInput Video===========================\n");
	av_dump_format(ifmt_ctx, 0, in_filename, 0);
	printf("\n======================================\n");

	FILE* fp_audio = fopen(out_filename_a, "wb+");
	FILE* fp_video = fopen(out_filename_v, "wb+");
	FILE* fp_video_yuv = fopen(out_filename_yuv, "wb+");
	ifmt_CodecCtx = ifmt_ctx->streams[videoindex]->codec;

	//查找解码器
	pCodec = avcodec_find_decoder(ifmt_CodecCtx->codec_id);
	if (pCodec == NULL) {
		printf("Codec not found.\n");
		return -1;
	}

	//打开解码器
	if (avcodec_open2(ifmt_CodecCtx, pCodec, NULL) < 0) {
		printf("Could not open codec.\n");
		return -1;
	}

	
	//文件流形式输入到output.txt文本里
	FILE* fp = fopen("output.txt", "wb+");
	fprintf(fp, "封装格式:%s\n", ifmt_ctx->iformat->name);
	fprintf(fp, "宽高:%d * %d\n", ifmt_ctx->streams[videoindex]->codec->width, ifmt_ctx->streams[videoindex]->codec->height);//videoindex是从上面for循环遍历得到的视频流的索引,一般来说视频流索引为0,音频为1
	fprintf(fp, "时长: %d秒\n", ifmt_ctx->duration / 1000000);
	fprintf(fp, "码率: %d\n", ifmt_ctx->bit_rate);
	fprintf(fp, "封装格式的名称: %s\n", ifmt_ctx->iformat->name);
	fprintf(fp, "封装格式的长名称: %s\n", ifmt_ctx->iformat->long_name);
	fprintf(fp, "封装格式的扩展名: %s\n", ifmt_ctx->iformat->extensions);
	fprintf(fp, "输入视频的AVStream个数: %d\n", ifmt_ctx->nb_streams);
	fprintf(fp, "输入视频的AVStream序号: %d\n", ifmt_ctx->streams[videoindex]->id);
	fprintf(fp, "输入视频的AVStream的时基: %d\n", ifmt_ctx->streams[videoindex]->time_base);
	fprintf(fp, "输入视频的AVStream的帧率: %d\n", ifmt_ctx->streams[videoindex]->r_frame_rate);
	fprintf(fp, "视频像素格式: %s\n", ifmt_ctx->streams[videoindex]->codec->pix_fmt);
	fprintf(fp, "编解码器名称: %s\n", ifmt_ctx->streams[videoindex]->codec->codec->name);
	fprintf(fp, "编解码器长名称: %s\n", ifmt_ctx->streams[videoindex]->codec->codec->long_name);
	fprintf(fp, "编解码器类型: %s\n", ifmt_ctx->streams[videoindex]->codec->codec->type);
	fprintf(fp, "编解码器ID: %d\n", ifmt_ctx->streams[videoindex]->codec->codec->id);
	fprintf(fp, "音频采样率: %d\n", ifmt_ctx->streams[audioindex]->codec->sample_rate);
	fprintf(fp, "音频声道数: %d\n", ifmt_ctx->streams[audioindex]->codec->channels);
	fprintf(fp, "音频采样格式: %d\n", ifmt_ctx->streams[audioindex]->codec->sample_fmt);
	fclose(fp);

	/*
	FIX: H.264 in some container format (FLV, MP4, MKV etc.) need
	"h264_mp4toannexb" bitstream filter (BSF)
	  *Add SPS,PPS in front of IDR frame
	  *Add start code ("0,0,0,1") in front of NALU
	H.264 in some container (MPEG2TS) don't need this BSF.
	*/
	pFrame = av_frame_alloc();
	pFrameYUV = av_frame_alloc();
	out_buffer = (uint8_t*)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, ifmt_CodecCtx->width, ifmt_CodecCtx->height));
	avpicture_fill((AVPicture*)pFrameYUV, out_buffer, PIX_FMT_YUV420P, ifmt_CodecCtx->width, ifmt_CodecCtx->height);
	img_convert_ctx = sws_getContext(ifmt_CodecCtx->width, ifmt_CodecCtx->height, ifmt_CodecCtx->pix_fmt,
		ifmt_CodecCtx->width, ifmt_CodecCtx->height, PIX_FMT_YUV420P, 4, NULL, NULL, NULL);
	

#if USE_H264BSF
	AVBitStreamFilterContext* h264bsfc = av_bitstream_filter_init("h264_mp4toannexb");
#endif
	int frame_cnt = 0;
	while (av_read_frame(ifmt_ctx, &pkt) >= 0) {
		if (pkt.stream_index == videoindex) {
#if USE_H264BSF
			av_bitstream_filter_filter(h264bsfc, ifmt_ctx->streams[videoindex]->codec, NULL, &pkt.data, &pkt.size, pkt.data, pkt.size, 0);
#endif
			printf("Write Video Packet. size:%d\tpts:%lld\n", pkt.size, pkt.pts);
			fwrite(pkt.data, 1, pkt.size, fp_video);
			//解码一帧压缩数据
			ret = avcodec_decode_video2(ifmt_CodecCtx, pFrame, &got_picture, &pkt);//YUV
			if (got_picture) {
				sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, ifmt_CodecCtx->height,
					pFrameYUV->data, pFrameYUV->linesize);
				printf("Decoded frame index: %d\n", frame_cnt);

				fwrite(pFrameYUV->data[0], 1, ifmt_CodecCtx->width * ifmt_CodecCtx->height, fp_video_yuv);
				fwrite(pFrameYUV->data[1], 1, ifmt_CodecCtx->width * ifmt_CodecCtx->height / 4, fp_video_yuv);
				fwrite(pFrameYUV->data[2], 1, ifmt_CodecCtx->width * ifmt_CodecCtx->height / 4, fp_video_yuv);

				frame_cnt++;

			}
		}
		else if (pkt.stream_index == audioindex) {
			/*
			AAC in some container format (FLV, MP4, MKV etc.) need to add 7 Bytes
			ADTS Header in front of AVPacket data manually.
			Other Audio Codec (MP3...) works well.
			*/
			printf("Write Audio Packet. size:%d\tpts:%lld\n", pkt.size, pkt.pts);
			fwrite(pkt.data, 1, pkt.size, fp_audio);
		}
		av_free_packet(&pkt);
	}

	const char* input_file = "Titanic.mp3";
	av_register_all();
	avformat_network_init();
	AVFormatContext* pFormatCtx = avformat_alloc_context();

	if (avformat_open_input(&pFormatCtx, input_file, 0, 0) != 0) {
		printf("Couldn't open input stream.\n");
		return -1;
	}

	if (avformat_find_stream_info(pFormatCtx, 0) < 0) {
		printf("Couldn't find stream information.\n");
		return -1;
	}
	//av_dump_format(pFormatCtx, 0, input_file, false);
	//获取音频流索引位置
	int j = 0, audio_stream_idx = -1;
	for (; j < pFormatCtx->nb_streams; j++) {
		if (pFormatCtx->streams[j]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
			audio_stream_idx = j;
			break;
		}
	}
	if (audio_stream_idx == -1) {
		printf("Didn't find a audio stream.\n");
		return -1;
	}

	AVCodecContext* codecCtx = pFormatCtx->streams[audio_stream_idx]->codec;
	AVCodec* codec = avcodec_find_decoder(codecCtx->codec_id);
	if (codec == NULL) {
		printf("Codec not found.\n");
		return -1;
	}

	if (avcodec_open2(codecCtx, codec, NULL) < 0) {
		printf("Could not open codec.\n");
		return -1;
	}

	AVSampleFormat in_sample_fmt = codecCtx->sample_fmt;//输入的采样格式
	int in_sample_rate = codecCtx->sample_rate;//输入的采样率
	int channels = codecCtx->channels;


	printf("采样率:%d ,声道数:%d\n", in_sample_rate, channels);

	//重采样设置参数
	AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16; //输出采样格式16bit PCM
	//输出采样率
	int out_sample_rate = 44100;
	//输出的声道布局(立体声)
	uint64_t out_ch_layout = AV_CH_LAYOUT_STEREO;
	SwrContext* swrCtx = swr_alloc();
	swrCtx = swr_alloc_set_opts(swrCtx,
		out_ch_layout, out_sample_fmt, out_sample_rate,
		av_get_default_channel_layout(codecCtx->channels), in_sample_fmt, in_sample_rate,
		0, NULL);
	/*
	av_opt_set_int(swrCtx, "in_channel_layout", AV_CH_LAYOUT_MONO, 0);
	av_opt_set_int(swrCtx, "in_sample_rate", in_sample_rate, 0);
	av_opt_set_sample_fmt(swrCtx, "in_sample_fmt", in_sample_fmt, 0);
	av_opt_set_int(swrCtx, "out_channel_layout", out_ch_layout, 0);
	av_opt_set_int(swrCtx, "out_sample_rate", out_sample_rate, 0);
	av_opt_set_sample_fmt(swrCtx, "out_sample_fmt", out_sample_fmt, 0);*/
	swr_init(swrCtx);

	//输出的声道个数
	int out_channel_nb = av_get_channel_layout_nb_channels(out_ch_layout);

	printf("输出pcm: 采样率:%d , 声道数:%d\n", out_sample_rate, out_channel_nb);

	const char* output_wav = "Titanic.wav";
	FILE* fp_wav = fopen(output_wav, "wb+");

	//16bit 44100 PCM 数据
	uint8_t* out_buffer1 = (uint8_t*)av_malloc(MAX_AUDIO_FRAME_SIZE * 2);
	int got_frame = 0, framecnt = 0;
	AVPacket* packet = (AVPacket*)av_malloc(sizeof(AVPacket));
	av_init_packet(packet);
	AVFrame* frame = av_frame_alloc();

	int totalsamples = 0;
	fseek(fp_wav, SIZE_WAV_HEADER + SIZE_WAV_FMT + SIZE_WAV_DATA, 1);
	while (av_read_frame(pFormatCtx, packet) >= 0) {

		if (packet->stream_index == audio_stream_idx) {
			//解码
			avcodec_decode_audio4(codecCtx, frame, &got_frame, packet);
			if (got_frame > 0) {
				//解码得到的Frame数据,转成PCM
				swr_convert(swrCtx, &out_buffer1, MAX_AUDIO_FRAME_SIZE, (const uint8_t**)frame->data, frame->nb_samples);
				//printf("index:%5d\t pts:%lld\t packet size:%d\n", framecnt, packet->pts, packet->size);
				//Write PCM

				totalsamples += frame->nb_samples;
				//音频文件字节大小= 采用率*时长*通道数*采样位数/8
				//计算一帧音频帧占用的字节数  通道数 * 采样点数* 采样位数/8 
				int out_buffer_size = av_samples_get_buffer_size(NULL, out_channel_nb,
					frame->nb_samples, out_sample_fmt, 1);
				//frame->nb_samples 当前帧的一个通道的采样点数(经测试,可能有的帧值不等) 和codecCtx->frame_size(音频帧的一个通道的采样点数,是固定值)  
				//虽然两者都是表示音频的采样点数,但是我的理解,这里用frame->nb_samples更加科学。
				fwrite(out_buffer1, 1, out_buffer_size, fp_wav);

				framecnt++;

			}
		}

		av_free_packet(packet);
	}
	swr_free(&swrCtx);
	av_frame_free(&frame);
	av_free(out_buffer1);

	char* p = set_wav_parm(totalsamples);
	rewind(fp_wav);//文件指针回到头部
	fwrite(p, 1, SIZE_WAV_HEADER + SIZE_WAV_FMT + SIZE_WAV_DATA, fp_wav);//size取1个字节没问题,可能跟p是char类型有关,取大了,报错
	fclose(fp_wav);
	printf("success");
	avcodec_close(codecCtx);
	avformat_close_input(&pFormatCtx);


#if USE_H264BSF
	av_bitstream_filter_close(h264bsfc);
#endif

	fclose(fp_video);
	fclose(fp_video_yuv);
	fclose(fp_audio);
	avformat_close_input(&ifmt_ctx);

	if (ret < 0){
		printf("Error occurred.\n");
		return -1;
	}

	
	return 0;
}

Android 利用 FFmpeg 解码音视频数据 在 avcodec_send_packet与avcodec_receive_frame应该是异步操作的,avcodec_send_packet 会将 AvPacket 放入到缓存队列中去解码,avcodec_receive_frame初次被调用时因为异步的原因可能没有获取到,也有可能可以获取多个 AvFrame,主要还是依赖解码的速度,因此通过循环去调用 avcodec_receive_frame 是比较妥当的做法。本文是基于之前写的几篇文章的,因此之前描述过的内容,在本文就不再重复了。 阅读详情

相关推荐

FFmpeg简易播放器的实现-音视频播放

本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10235926.html 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文件解码和调用SDL播放两大部分。 前面三个实验分别实现了最简播放、视频播放和音频播放,本次实验将视频播放和音频播放结合在一起。 FFmpeg简易播放器系列文章如下: [1]. FFmpeg简易播放器的...

叶余的博客 7510

ffmpeg从MP4中取出wav音频

导航到 FFmpeg 的安装目录:在命令提示符窗口中,使用 “cd” 命令导航到你解压缩 FFmpeg 工具的目录。下载后,解压缩到一个方便的位置。查找提取后的音频文件:提取完成后,你可以在 FFmpeg 的安装目录中找到提取后的 WAV 音频文件 “output.wav”。打开命令提示符:按下 Win + R 键,在运行对话框中输入 “cmd”,然后按下 Enter 键,以打开命令提示符窗口。上述命令中,“input.mp4” 是要提取音频的输入文件名,“output.wav” 是提取后的输出文件名。

Liberty1010的博客 3724

FFmpeg学习6:视音频同步

在上一篇文章中,视频和音频是各自独立播放的,并不同步。本文主要描述了如何以音频的播放时长为基准,将视频同步到音频上以实现视音频的同步播放的。主要有以下几个方面的内容 * 视音频同步的简单介绍 * DTS 和 PTS * 计算视频中Frame的显示时间 * 获取Audio clock(audio的播放时长) * 将视频同步到音频上,实现视音频同步播放视音频同步简单介绍一般来说,视频同步指的

BrookIcv的博客 1310

ffmpeg提取音频数据

学习就是要学习基础,学习原理。 所以大家想学习下面的内容,最好看下下面几篇我写的文章,然后再看下面的内容就会so easy. https://blog.youkuaiyun.com/qq_15255121/article/details/115168456 https://blog.youkuaiyun.com/qq_15255121/article/details/115301516 https://blog.youkuaiyun.com/qq_15255121/article/details/115348454 抽取音频数据

qq_15255121的专栏 1258

使用FFmpeg解析视频文件信息(音视频)

总结来说,通过使用FFmpeg库,我们可以方便地解析视频文件的信息。无论是获取视频的时长、分辨率,还是音频的编码格式和通道数,FFmpeg提供了强大的功能来满足我们的需求。通过FFmpeg,我们可以轻松地解析视频文件的信息,包括音频和视频的参数、格式、时长等。首先,我们需要安装FFmpeg,并确保它已经正确地配置在系统的环境变量中。然后,我们解析输出结果,提取视频的参数信息,并将其存储在一个字典中返回。开头的行,我们可以提取视频的编码格式和分辨率。开头的行,我们可以提取视频的时长。上述代码中,我们使用。

EtwCpp的博客 449

使用FFmpeg API开发视音频信息读取工具 MediaFileInfoList

FFmpeg是一个强大的多媒体处理框架,它提供了一系列编程接口(APIs),使得开发者能够处理几乎所有与媒体相关的任务,包括流处理、多媒体文件的转码与封装等。在本章中,我们将对FFmpeg API进行一个总体的介绍,包括其设计目标、主要功能以及一些基础的使用方法。FFmpeg最初是由Fabrice Bellard在2000年开发,现在是一个开源项目,主要用于处理音频和视频的录制、转换和流化。API是应用程序接口的缩写,它为开发者提供了一种编程的方式与FFmpeg库进行交互。

weixin_34779181的博客 1191

我的开源视音频项目汇总

本文汇总一下自己视音频编解码学习方面的开源项目。这些开源项目大体上可以分成专业领域程序,FFmpeg示例程序,FFmpeg移植程序,多媒体项目示例程序,视音频编解码原理学习工程几个类别。

雷霄骅(leixiaohua1020)的专栏 16万+

利用ffmpeg进行视音频信息提取

一、实验目的 1、深入掌握视音频的基本参数信息 2、掌握ffmpeg编译环境配置 3、掌握和熟悉提取视音频文件的基本方法 二、实验要求 1、对ffmpeg的编译环境进行配置; 2、对一个视频文件,提取基本信息(例如,封装格式,码流,视频编码方式,音频编码方式,分辨率,帧率,时长等等),并输出为txt文档。结果与MediaInfo的信息对比,并截图; 3、对该视频文件,提取视频信息,保存为yuv格式。结果利用yuv播放器播放并截图; 4、对该视频文件,提取音频信息,保存为wav格式。结果利用adobe audition播放并截图。

深入掌握视音频信息提取:FFmpeg实战指南

深入掌握视音频信息提取:FFmpeg实战指南 去发现同类优质开源项目:https://gitcode.com/ 项目介绍 在多媒体处理领域,FFmpeg无疑是一个强大的工具,广泛应用于视音频文件的处理、转换和信息提取。本项目旨在帮助用户深入掌握视音频的基本参数信息,并通过实际操作掌握FFmpeg的编译环境配置及视音频文件的提取方法。通过本项目,用户不仅能够了解视音频文件的基本参数,如封装格式、码流...

gitblog_09806的博客 691

Java服务端实现Google Pay支付功能

全网最全代码、最清晰服务端处理Google Pay,最清晰讲解Google Pay集成逻辑。

jack2350536098的博客 1万+

实战分享:如何用Dify和MaxKb实现文档智能切分与高效检索(附代码解析)

本文详细介绍了如何结合Dify和MaxKB构建文档智能切分与高效检索系统。针对传统全文检索的不足,提出了结构感知的文档切分方案,通过解析文档层级关系并构建标题链,实现了精准的章节级检索。文章包含完整的代码实现,涵盖文档解析、智能切分、向量化策略及双索引优化,并分享了性能调优和生产环境实践经验。

qsc90123456的博客 547

[总结]FFMPEG视音频编解码零基础学习方法

在优快云上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者。在和大家探讨的过程中,我忽然发现了一个问题:在“大神”和初学者之间好像有一个不可逾越的鸿沟。“大神”们水平高超,探讨着深奥的问题;而初学者们还停留在入门阶段。究竟是什么原因造成的这种“两极分化”呢?最后,我发现了问题的关键:FFMPEG难度比较大,却没有一个循序渐进,由简单到复杂的教程...

雷霄骅(leixiaohua1020)的专栏 105万+

Win10+pycharm+conda 配置Siammask 过程记录(新手向)

我们跑动demo 需要配置两个相关的文件这两个文件需要用 git 进行下载,对于不熟悉git的小伙伴 我这里给出连接,大家可以直接下载即可,并将其配置在 experiments文件夹下然后大家再需要在设置参数参数这里给出了。

C1137577723的博客 551

[总结]视音频编解码技术零基础学习方法

一直想把视音频编解码技术做一个简单的总结,可是苦于时间不充裕,一直没能完成。今天有着很大的空闲,终于可以总结一个有关视音频技术的入门教程,可以方便更多的人学习从零开始学习视音频技术。需要注意的是,本文所说的视音频技术,指的是理论层面的视音频技术,并不涉及到编程相关的东西。   0. 生活中的视音频技术 平时我们打开电脑中自己存电影的目录的话,一般都会如下图所示,一大堆五花八门的电影。(其实...

雷霄骅(leixiaohua1020)的专栏 1万+

微信小程序返回按钮的隐藏玩法:用onShow实现数据自动刷新(附完整代码)

本文深入探讨了微信小程序中用户点击返回按钮后,如何利用onShow生命周期函数实现页面数据的自动刷新。文章对比了onLoad与onShow的差异,提供了从基础的本地存储标记到进阶的EventChannel事件通信,再到状态管理库的多种解决方案,并附有完整的代码示例,帮助开发者构建流畅的用户体验。

agile9scrum的博客 925

ESP32蓝牙广播数据自定义指南:让你的设备更容易被手机发现

本文详细介绍了如何通过自定义ESP32蓝牙广播数据提升设备在手机端的可发现性。从广播数据结构、扫描响应优化到跨平台兼容性设置,提供了全面的技术指南和实战代码示例,帮助开发者解决智能硬件开发中的蓝牙连接难题。

weixin_29172201的博客 272

江南大学数字媒体技术大三上作业整理——顾清宇

文章目录前言数字音视频技术人工智能互动媒体技术游戏程序设计数字图像处理技术人机交互技术智能算法专题设计 前言 大三上圆满结束了,想到自己每次做作业都是自己从零开始,还挺痛苦的,所以想着把自己的作业都整理一下,放到优快云上面来,供以后的学弟学妹们学习,也供自己以后回顾。不过只能是上传源代码和实验报告了,让我重新总结是不可能的了,哈哈。 数字音视频技术 实验一: 实验二: 实验三: 人工智能 大作业...

A_Ainley的博客 4156

手把手教你用Matlab实现Copula函数:从理论到代码的完整指南

本文提供了一份在MATLAB中实现Copula函数的完整实战指南。从理解Sklar定理和常见Copula家族(如高斯、t、Clayton)的核心概念出发,详细讲解了数据预处理、边缘分布拟合、概率积分变换等关键步骤。通过具体代码示例,手把手演示了Copula模型的拟合、评估、蒙特卡洛模拟,并进阶应用于金融风险度量(如VaR计算)和条件分布分析,帮助读者掌握这一强大的多变量依赖建模工具。

y9z0a1b的博客 953

FFmpeg学习:视音频同步

视频和音频是各自独立播放的,并不同步。本文主要描述了如何以音频的播放时长为基准,将视频同步到音频上以实现视音频的同步播放的。主要有以下几个方面的内容 视音频同步简单介绍一般来说,视频同步指的是视频和音频同步,也就是说播放的声音要和当前显示的画面保持一致。想象以下,看一部电影的时候只看到人物嘴动没有声音传出;或者画面是激烈的战斗场景,而声音不是枪炮声却是人物说话的声音,这是非常差的一种体验。 在视频流和音频流中已包含了其以怎样的速度播放的相关数据,视频的帧率(Frame Rate)指示视频一秒显示的帧数(图像

qq_40170041的博客 1624

013 PID参数整定:Ziegler-Nichols法

几年前在调试一台伺服压机,客户要求位置精度±0.01mm,响应时间小于50ms。我按照教科书上的经验值设了P=1.5,I=0.02,D=0.01,结果电机一启动就开始尖叫,位置超调直接干到0.3mm,然后开始震荡,像极了喝醉的舞者。现场工程师看我的眼神,就像在看一个刚毕业的实习生。那次之后我明白了一个道理:PID参数不是靠猜的,也不是靠经验公式硬套的。你需要一个系统的方法,而Ziegler-Nichols法就是那个让你从“瞎调”走向“有章可循”的起点。

m0_50546716的博客 101

DeepFashion 服装识别:基于 YOLOv10 的深度学习实现与 UI 界面开发

随着深度学习的发展,目标检测算法在服装识别任务中表现出色,特别是 YOLO(You Only Look Once)系列模型。服装识别(Fashion Recognition)是计算机视觉领域的重要任务,广泛应用于。已提供,可用于服装分类、款式识别、虚拟试衣等应用。训练服装识别模型,并开发。

YOLO 803

最简单的基于FFmpeg的封装格式处理:视音频分离器简化版(demuxer-simple)

最近打算记录一下基于FFmpeg的视音频分离,复用,封装格式转换相关的例子。有关封转格式转换的例子在之前的文章:《最简单的基于FFMPEG的封装格式转换器(无编解码)》中已经有过记录,不再重复。因此计划写3篇文章分别记录视频的复用器(Muxer)和分离器(Demuxer)。这是第1篇。本文记录一个基于FFmpeg的视音频分离器简单版(Simplest FFmpeg Demuxer Simple)。视音频分离器(Demuxer)即是将封装格式数据(例

雷霄骅(leixiaohua1020)的专栏 3万+

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Android FFMPEG音视频开发(一)

本文参考:https://blog.youkuaiyun.com/leixiaohua1020/article/details/18893769 突然想学习Android音视频领域,所以在网上疯狂找博客看,遇见了上面这篇博客,通读了一遍,写的真好。又翻看了作者其它的博客,很厉害。 淡泊明志 宁静致远 虽然作者已经写的很好了,但我还是想参考作者的再写一遍,一来是关注点不一样,二来是由于我的学习方法——费曼学习法...

WillScorpio 2071

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

FFmpeg视音频同步

FFmpeg学习6:视音频同步 原文地址:https://blog.youkuaiyun.com/weixin_33724059/article/details/86226463 在上一篇文章中,视频和音频是各自独立播放的,并不同步。本文主要描述了如何以音频的播放时长为基准,将视频同步到音频上以实现视音频的同步播放的。主要有以下几个方面的内容 视音频同步的简单介绍 DTS 和 PTS 计算视频中Frame的显示时间 获取Audio clock(audio的播放时长) 将视频同步到音频上,实现视音频同步播放

hyl999的专栏 395

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

上一篇: Blender学习笔记(4)材质配色和打光渲染|blender
下一篇: matlab快捷键自动对齐|小知识
LLLLQZ
博客等级 码龄7年 308粉丝 51原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值