文章目录:
ffmpeg 代码是不是完全开源
是的
本开源代码播放器使用的音视频解码代码来源于ffmpeg-0.6.3(),
jni衔接代码和java层代码来源于havlenapetr()。
移植ffmpeg到android的常规关键点网上有很多的帖子可以参考,也可以用文件夹比较工具比较一下,看看添加修改删除了那些文件。
本开源代码的编译环境
1: Android SDK 2.2版,
2: NDK r4版,注意要导出NDK宏,
3: IDE开发环境是 eclips 3.5 版
4: libffplay.so是在Android 2.2版源码目录树中编译出来的,使用Ubuntu10.04和VMware7.1.1版,目前源码不公开
5: libffmpeg.so编译步骤,cd /cygwin/c/ffplay, ./config_r4.sh, $NDK/ndk-build
6: PC主机开发环境是windows xp。
特别注意,此demo只能在 Android SDK 2.2版上使用,其他版本有修改源码,重新编译才行。
此开源代码解决了几个特别关键点,达到实用水平。几个关键点如下:
1:arm汇编代码编译支持,主要是在几个.mk文件中添加LOCAL_ARM_MODE := arm语句,
在config_r4.sh文件中添加--arch=armv5te和--enable-asm 等开关。
2:在ffmpeg config_r4.sh配置文件中关闭了一些不用的选项后,连接时总是报一些莫名其妙的连接错误,
本开源代码给出终极解决方案(在/jni/jni/Android.mk文件中添加 LOCAL_LDLIBS += C:/ffplay/bin/ndk/local/armeabi/libavcodec.a等语句)。
3:修改havlenapetr中的视频显示错误bug,经测试havlenapetr原始代码在模拟器设置为320x480时显示正确,在更大的分辨率下显示错误,
本开源代码已修改好此bug,现在无论什么分辨率都可以正确显示。
此开源代码其他注意事项:
1:jni衔接代码相比havlenapetr精简了几个数量级,更方便网友们研习。
2:此开源代码不包括play,pause,stop,seek和视音频同步等功能实现代码,这部分代码不开源。
3:Android jni层直接输出音频示例,Android jni层直接输出视频示例,基于ffmpeg的Android播放器开源代码,三个工程使用相同的库,相同的方法和技巧,可相互参考。
在moto defy me525上测试通过。
如何用ffmpeg将rtsp视频流录制成mp4文件?
ffmpeg -y -i rtsp:\\192.168.1.188:8089\test -vcodec copy -acodec copy -f mp4 e:\x.mp4
windows php怎么使用ffmpeg
Windows下FFmpeg快速入门
FFmpeg简介
FFmpeg是什么?
FFmpeg是用于录制、转换和流化音频和视频的完整解决方案, 包括 libavcodec ,一套领先的音/视频编解码类库。FFmpeg 在Linux上开发,当可以在大多数操作系统下编译,包括Windows。
Note
FFmpeg对GCC的依赖很强,所以就算是在Windows上, 用VC编译FFmpeg也不是一件轻松的事情。请尽量使用 GCC来编译FFmpeg,比较事半功倍。
FFmpeg的组成结构
FFmpeg主要由一下几个部分组成:
libavcodec: 一个包含了所有FFmpeg音视频编解码器的库。 为了保证最优性能和高可复用性,大多数编解码器从头开发的。
libavformat: 一个包含了所有的普通音视格式的解析器和 产生器的库。
ffmpeg:命令行的视频格式转换程序。
ffplay:视频播放程序。(需要SDL支持)
ffserver:多媒体服务器
三个实例程序,这三个实例较为复杂,基本可以作为API使用手册:
了解完组成结构后,你会发现,如果你在寻找一种视频格式转换 的方式,那FFmpeg绝对是你的第一选择,libavcodec 则又是重 中之重。如果遇上API不会使用的情况,可以参考ffmpeg.c、ffplay.c、 ffserver.c、apiexample.c(解码)和output_example.c(编码)。
FFmpeg的编译
要使用FFmpeg,第一步就是编译,编译FFmpeg是一个复杂的过程,如果你想加快速度,领略FFmpeg 的风采,则可以跳过这一步,直接进入下一章节。
FFmpeg的SDK
FFmpeg是一个复杂的工程,第一步编译,特别是Windows下的编译 过程,更是复杂。 因此,好心的网友提供了Windows下编译好的 dll和lib库文件,以及相关的头文件。新手们则可直接下载,并开始编写 FFmpeg库的程序了。
以上两者已经足以完成FFmpeg的入门,最新的SDK版本是3.0, 对应于FFmpeg的版本是 r10087。新手们可以从编译源代码库中的 output_example.c开始,同时参考 SDK入门宝典 。
编译output_example.c的时候需要注意以下问题:
VC的是不支持C语言中的inline,所以可以把相关的inline删除。
对于snprintf的支持,可以考虑下载 snprintf.h和snprintf.c放入工程中。
求ffmpeg音频压缩代码(wav压缩成wma)
这个简单。大致的思路是
1.打开wav文件
2.打开要输出的wma文件
3.不停的读取数据帧
4.读取以后解码并写入wma
5.关闭wav文件
6.关闭wma文件
重新写例子太麻烦贴点代码吧
#include "Debug.h"
#include "FFMpegAVFileReader.h"
#include "FFMpegAVFileReaderFactory.h"
#include sstream
#include "yk_convert.h"
static char h264_head[4] = {(char)0x00,(char)0x00,(char)0x00,(char)0x01};
namespace YK
{
FFMpegAVFileReader::FFMpegAVFileReader()
{
ffmpeg_avcodec_init();
ffmpeg_av_register_all();
av_log_set_callback(ffmpeg_log_callback);
m_format_context = 0;
m_input_format = 0;
m_format_parameters = 0;
m_packet = (AVPacket*)av_mallocz(sizeof(AVPacket));
}
FFMpegAVFileReader::~FFMpegAVFileReader()
{
Close();
av_free(m_packet);
}
avfile_reader_param_t* FFMpegAVFileReader::GetParam()
{
//YK::AutoLock l(m_lock);
return m_param;
}
void FFMpegAVFileReader::Seek(int pts)
{
YK::AutoLock l(m_lock);
int ret = av_seek_frame(m_format_context,-1,(YK::int64_t)pts * (YK::int64_t)1000,AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY);
//if(ret = 0)
//{
// for(int i = 0; i m_format_context-nb_streams; i++)
// {
// avcodec_flush_buffers( m_format_context-streams[i]-codec );
// }
//}
//std::stringstream ss;
//ss "pts = " pts
// " ret = " ret std::endl;
//OutputDebugString(ss.str().data());
}
void FFMpegAVFileReader::GetDuration(double start,double end)
{
//YK::AutoLock l(m_lock);
start = (double)(m_start_time / 1000000);
end = start + (double)(m_duration / 1000000);
}
service_error_t FFMpegAVFileReader::Open(int time_out)
{
YK::AutoLock l(m_lock);
service_error_t service_error;
// 打开文件
if (av_open_input_file(m_format_context,TToANSI(m_param.input_file_path).data(),m_input_format,0,m_format_parameters) 0)
{
service_error.init(service_error_type_failed,"av_open_input_file failed");
return service_error;
}
// 查询流信息
if(av_find_stream_info(m_format_context) 0)
{
service_error.init(service_error_type_failed,"av_find_stream_info failed");
return service_error;
}
m_start_time = m_format_context-start_time;
m_duration = m_format_context-duration;
#ifdef _DEBUG
pFile = fopen("D:/1.out","w+b");
#endif
// 保存流信息
av_stream_info_t av_stream_info;
for(unsigned int i = 0; i m_format_context-nb_streams; i++)
{
AVStream *st = m_format_context-streams[i];
AVCodecContext *enc = st-codec;
if(enc-codec_type == AVMEDIA_TYPE_AUDIO)
{
// 音频
av_stream_info.av_stream_info_type = av_stream_info_type_audio;
av_stream_info.codec_id = codec_id_none;
//channel_layout = enc-channel_layout;
av_stream_info.audio_channels = enc-channels;
av_stream_info.audio_samplepersec = enc-sample_rate;
av_stream_info.audio_bitpersample = yk_sample_format(enc-sample_fmt);
//audio_sample_fmt = enc-sample_fmt;
//input_codecs[nb_icodecs++] = avcodec_find_decoder_by_name(audio_codec_name);
av_stream_info.codec_id = yk_code_id(enc-codec_id);
av_stream_info.extradata_size = enc-extradata_size;
if(av_stream_info.extradata_size)
memcpy(av_stream_info.extradata,enc-extradata,enc-extradata_size);
if(av_stream_info.codec_id == codec_id_mp3)
{
av_stream_info.extradata_size = sizeof(mpeg1_waveformat_extradata);
mpeg1_waveformat_extradata* pMpeg1WaveFormat = (mpeg1_waveformat_extradata*)av_stream_info.extradata;
pMpeg1WaveFormat-dwHeadBitrate = enc-bit_rate;
pMpeg1WaveFormat-dwPTSHigh = 0;
pMpeg1WaveFormat-dwPTSLow = 0;
pMpeg1WaveFormat-fwHeadFlags = 25;
pMpeg1WaveFormat-fwHeadLayer = ACM_MPEG_LAYER3;
pMpeg1WaveFormat-fwHeadMode = ACM_MPEG_STEREO;
pMpeg1WaveFormat-fwHeadModeExt = 1;
pMpeg1WaveFormat-wHeadEmphasis = 1;
}
AddStreamInfo(av_stream_info);
m_stream_audio_index = i;
}
else if(enc-codec_type == AVMEDIA_TYPE_VIDEO)
{
// 视频
av_stream_info.av_stream_info_type = av_stream_info_type_video;
av_stream_info.codec_id = codec_id_none;
av_stream_info.video_width = enc-width;
av_stream_info.video_height = enc-height;
av_stream_info.video_profile = enc-profile;
av_stream_info.video_level = enc-level;
if(av_stream_info.video_profile 0)
{
av_stream_info.video_profile = 77;
}
if(av_stream_info.video_level 0)
{
av_stream_info.video_level = 30;
}
av_stream_info.extradata_size =
time_out) { YK::AutoLock l(m_lock); service_error_t service_error; // 打开文件 if (av_open_input_file(m_format_context
nfo.extradata_size) memcpy(av_stream_info.extradata,enc-extradata,enc-extradata_size); if(av_stream_info.codec_id == c