个人ffmpeg笔记(一)
环境安装
QT环境安装
- 运行qt…run安装
下载地址:https://download.qt.io/archive/qt/
下载地址:https://download.qt.io/archive/qt/5.12/5.12.10/
-
sudo apt install --reinstall libxcb-xinerama0 解决xcb问题
-
Ubuntu16.04打开Qt显示/home/user/.config/QtProject/qtcreator/qtversion.xml :Permission denied
权限不够所导致,执⾏命令 sudo chown -R user:user ~/.config/ 即可解决
ffmpeg环境安装
apt安装:
sudo apt-get update
sudo apt-get install -y \autoconf \automake \build-essential \cmake \git-core \libass-dev \libfreetype6-dev \libsdl2-dev \libtool \libva-dev \libvdpau-dev \libvorbis-dev \libxcb1-dev \libxcb-shm0-dev \libxcb-xfixes0-dev \libfdk-aac-dev \libfaad-dev \pkg-config \texinfo \wget \zlib1g-devsudo apt-get install -y \nasm \yasm \libx264-dev \libx265-dev \libnuma-dev \libvpx-dev \libfdk-aac-dev \libmp3lame-dev \libopus-dev
apt安装:
sudo apt install ffmpeg
vi ~/.bashrc
export PATH="/usr/bin:$PATH"
source ~/.bashrc
源码安装:
一、创建目录
在home目录下创建
ffmpeg_sources:用于下载源文件
ffmpeg_build: 存储编译后的库文件
bin:存储二进制文件(ffmpeg,ffplay,ffprobe,X264,X265等)
cd ~
mkdir ffmpeg_sources ffmpeg_build bin二、安装依赖
sudo apt-get update
sudo apt-get -y install \
autoconf \
automake \
build-essential \
cmake \
git-core \
libass-dev \
libfreetype6-dev \
libsdl2-dev \
libtool \
libva-dev \
libvdpau-dev \
libvorbis-dev \
libxcb1-dev \
libxcb-shm0-dev \
libxcb-xfixes0-dev \
pkg-config \
texinfo \
wget \
zlib1g-devNASM使用源码进行安装
cd ~/ffmpeg_sources && \
wget https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.bz2 && \
tar xjvf nasm-2.14.02.tar.bz2 && \
cd nasm-2.14.02 && \
./autogen.sh && \
PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" &&
\
make && \
make installYasm使用源码进行安装:
cd ~/ffmpeg_sources && \
wget -O yasm-1.3.0.tar.gz https://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz && \
tar xzvf yasm-1.3.0.tar.gz && \
cd yasm-1.3.0 && \
./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" && \
make && \
make installlibx264
H.264视频编码器。更多信息和使用范例参考H.264 Encoding Guide
要求编译ffmpeg时配置:--enable-gpl --enable-libx264.
使用源码进行编译:
cd ~/ffmpeg_sources && \
git -C x264 pull 2> /dev/null || git clone --depth 1 https://gitee.com/ibaoger/x264.git && \
cd x264 && \
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" && \
./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --enable-static --enable-pic && \
PATH="$HOME/bin:$PATH" make && \
make installlibx265
H.265/HEVC 视频编码器, 更多信息和使用范例参考H.265 Encoding Guide。
要求编译ffmpeg时配置:--enable-gpl --enable-libx265.
使用源码进行编译:
sudo apt-get install mercurial libnuma-dev && \
cd ~/ffmpeg_sources && git clone https://gitee.com/mirrors_videolan/x265.git && \
cd x265/build/linux && \
PATH="$HOME/bin:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg_build" -DENABLE_SHARED=off ../../source && \
PATH="$HOME/bin:$PATH" make && \
make installlibvpx
VP8/VP9视频编解码器。 更多信息和使用范例参考VP9 Video Encoding Guide 。
要求编译ffmpeg时配置: --enable-libvpx.
使用源码进行编译:
cd ~/ffmpeg_sources && \
git -C libvpx pull 2> /dev/null || git clone --depth 1 https://github.com/webmproject/libvpx.git && \
cd libvpx && \
PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" --disable-examples --disable-unit-tests --enable-vp9-highbitdepth --as=yasm --enable-pic && \
PATH="$HOME/bin:$PATH" make && \
make installlibfdk-aac
AAC音频编码器. 更多信息和使用范例参考AAC Audio Encoding Guide。
要求编译ffmpeg时配置:--enable-libfdk-aac ( 如果你已经配置了 --enable-gpl则需要加上--enablenonfree).
使用源码进行编译:
cd ~/ffmpeg_sources && \
git -C fdk-aac pull 2> /dev/null || git clone --depth 1 https://github.com/mstorsjo/fdk-aac && \
cd fdk-aac && \
autoreconf -fiv && \
./configure CFLAGS=-fPIC --prefix="$HOME/ffmpeg_build" && \
make && \
make installlibmp3lame
MP3音频编码器.
要求编译ffmpeg时配置:--enable-libmp3lame.
使用源码进行编译:
cd ~/ffmpeg_sources && \
git clone --depth 1 https://gitee.com/qingfuliao/lame && \
cd lame && \
PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --enable-nasm --with-pic && \
PATH="$HOME/bin:$PATH" make && \
make installlibopus
Opus音频编解码器.
要求编译ffmpeg时配置:--enable-libopus.
使用源码进行编译:
cd ~/ffmpeg_sources && \
git -C opus pull 2> /dev/null || git clone --depth 1 https://gitee.com/ttsu00/opus.git && \
cd opus && \
./autogen.sh && \
./configure --prefix="$HOME/ffmpeg_build" -with-pic&& \
make && \
make installFFmpeg
cd ~/ffmpeg_sources && \
wget -O ffmpeg-4.2.1.tar.bz2 https://ffmpeg.org/releases/ffmpeg-4.2.1.tar.bz2 && \
tar xjvf ffmpeg-4.2.1.tar.bz2 && \
cd ffmpeg-4.2.1 && \
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" CFLAGS="-O3 -fPIC" ./configure \
--prefix="$HOME/ffmpeg_build" \
--pkg-config-flags="--static" \
--extra-cflags="-I$HOME/ffmpeg_build/include" \
--extra-ldflags="-L$HOME/ffmpeg_build/lib" \
--extra-libs="-lpthread -lm" \
--bindir="$HOME/bin" \
--enable-gpl \
--enable-libass \
--enable-libfdk-aac \
--enable-libfreetype \
--enable-libmp3lame \
--enable-libopus \
--enable-libvorbis \
--enable-libvpx \
--enable-libx264 \
--enable-libx265 \
--enable-openssl \
--enable-pic \
--enable-shared \
--enable-nonfree \
--enable-debug=3 \
--disable-optimizations \
--disable-asm \
--disable-stripping && \
PATH="$HOME/bin:$PATH" make && \
make install && \
hash -r
然后重新登录系统或者在当前shell会话执行如下命令以识别新安装ffmpeg的位置:
source ~/.profile
现在已经完成编译和安装ffmpeg (also ffplay, ffprobe, lame, x264, & x265) 。该文档剩余章节主要讲如何更新和删除ffmepg。
编译完成后,ffmpeg_build ffmpeg_sources bin目录的大体情况加入命令:
vi ~/.bashrc
export PATH="$PATH:/usr/local/bin" 这里需要写入正确路径
source ~/.bashrc
环境使用
Cmake
cmake_minimum_required(VERSION 3.10)
project(ffmpeg_test)# 设置C标准
set(CMAKE_C_STANDARD 99)# 查找FFmpeg库
find_package(PkgConfig REQUIRED)
pkg_check_modules(AVFORMAT REQUIRED libavformat)
pkg_check_modules(AVCODEC REQUIRED libavcodec)
pkg_check_modules(AVUTIL REQUIRED libavutil)
pkg_check_modules(AVDEVICE REQUIRED libavdevice)
pkg_check_modules(AVFILTER REQUIRED libavfilter)
pkg_check_modules(POSTPROC REQUIRED libpostproc)
pkg_check_modules(SWRESAMPLE REQUIRED libswresample)
pkg_check_modules(SWSCALE REQUIRED libswscale)find_package(SDL2 REQUIRED)
link_libraries(SDL2)# 包含FFmpeg头文件路径
include_directories(${AVFORMAT_INCLUDE_DIRS})
include_directories(${AVCODEC_INCLUDE_DIRS})
include_directories(${AVUTIL_INCLUDE_DIRS})
include_directories(${AVDEVICE_INCLUDE_DIRS})
include_directories(${AVFILTER_INCLUDE_DIRS})
include_directories(${POSTPROC_INCLUDE_DIRS})
include_directories(${SWRESAMPLE_INCLUDE_DIRS})
include_directories(${SWSCALE_INCLUDE_DIRS})# 添加可执行文件
add_executable(ffmpeg_test main.cpp)# 链接FFmpeg库
target_link_libraries(ffmpeg_muxmp4 ${AVFORMAT_LIBRARIES} ${AVCODEC_LIBRARIES} ${AVUTIL_LIBRARIES} ${AVDEVICE_LIBRARIES} ${AVFILTER_LIBRARIES} ${POSTPROC_LIBRARIES} ${SWRESAMPLE_LIBRARIES} ${SWSCALE_LIBRARIES} )
QT
CONFIG += link_pkgconfig
PKGCONFIG += sdl2LIBS += -L/home/enpht/sdk/ffmpeg4/ffmpeg_build/lib/ -lavcodec -lavformat -lavutil -lswscale -lavfilter -lavdevice -lswresample -lfdk-aac
INCLUDEPATH += /home/enpht/sdk/ffmpeg4/ffmpeg_build/include
DEPENDPATH += /home/enpht/sdk/ffmpeg4/ffmpeg_build/include
TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qtSOURCES += main.cpp \muxer.cpp \audioencoder.cpp \videoencoder.cpp \audioresampler.cppwin32 {
INCLUDEPATH += $$PWD/ffmpeg-4.2.1-win32-dev/include
LIBS += $$PWD/ffmpeg-4.2.1-win32-dev/lib/avformat.lib \$$PWD/ffmpeg-4.2.1-win32-dev/lib/avcodec.lib \$$PWD/ffmpeg-4.2.1-win32-dev/lib/avdevice.lib \$$PWD/ffmpeg-4.2.1-win32-dev/lib/avfilter.lib \$$PWD/ffmpeg-4.2.1-win32-dev/lib/avutil.lib \$$PWD/ffmpeg-4.2.1-win32-dev/lib/postproc.lib \$$PWD/ffmpeg-4.2.1-win32-dev/lib/swresample.lib \$$PWD/ffmpeg-4.2.1-win32-dev/lib/swscale.lib
}linux{
INCLUDEPATH += /usr/include/x86_64-linux-gnu/libavcodec /usr/include/x86_64-linux-gnu/libavformat /usr/include/x86_64-linux-gnu/libavutil /usr/include/x86_64-linux-gnu/libswscaleLIBS += -lavcodec -lavformat -lavutil -lswscale}HEADERS += \muxer.h \audioencoder.h \videoencoder.h \audioresampler.h
源码编译:
下载源码:
mkdir ffmpeg && cd ffmpeg/
wget https://ffmpeg.org/releases/ffmpeg-4.3.1.tar.bz2
tar xvf ffmpeg-4.3.1.tar.bz2
cd ffmpeg-4.3.1/
配置:
./configure --enable-gpl \--enable-libass \--enable-libfdk-aac \--enable-libfreetype \--enable-libopus \--enable-libvorbis \--enable-libvpx \--enable-libx264 \--enable-libx265 \--enable-nonfree
编译:
sudo make -j4 && sudo make install
测试:
ffmpeg -version
零声安装步骤参考:
https://www.yuque.com/linuxer/ffmcy9/pgx8mi
QT使用ffmpeg
pro文件:
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qtSOURCES += \
main.c
INCLUDEPATH += /home/lqf/ffmpeg_build/includeLIBS += /home/lqf/ffmpeg_build/lib/libavcodec.a \
/home/lqf/ffmpeg_build/lib/libavdevice.a \
/home/lqf/ffmpeg_build/lib/libavfilter.a \
/home/lqf/ffmpeg_build/lib/libavformat.a \
/home/lqf/ffmpeg_build/lib/libavutil.a \
/home/lqf/ffmpeg_build/lib/libswresample.a \
/home/lqf/ffmpeg_build/lib/libswscale.a
兼容多个平台:可以参考飞扬青云的playffmpeg
#如果用的是ffmpeg4内核请将ffmpeg3改成ffmpeg4,两种内核不兼容,头文件也不一样
DEFINES += ffmpeg4#ffmpeg4则使用ffmpeg4的目录contains(DEFINES, ffmpeg4) {
strPath = ffmpeg4
} else {
strPath = ffmpeg3
}#表示64位的构建套件
contains(QT_ARCH, x86_64) {
strLib = winlib64
strInclude = include64
} else {
#由于Qt4不支持QT_ARCH所以会执行下面的
#如果用的64位的Qt4则需要自行修改strLib = winlib
strInclude = include
}#表示arm平台构建套件contains(QT_ARCH, arm) {
strInclude = include
}!android {
INCLUDEPATH += $$PWD/$$strPath/$$strInclude
}win32 {
LIBS += -L$$PWD/$$strPath/$$strLib/ -lavcodec -lavfilter -lavformat -lswscale -lavutil -lswresample -lavdevice
}#请自行替换!android {
unix:!macx {
LIBS += -L$$PWD/linuxlib/ -lavfilter -lavformat -lavdevice -lavcodec -lswscale -lavutil -lswresample -lavdevice -lpthread -lm -lz -lrt -ldl
}}#android系统
android {
INCLUDEPATH += $$PWD/androidlib/include
LIBS += -L$$PWD/androidlib/ -lavcodec -lavfilter -lavformat -lswscale -lavutil -lswresample
#将动态库文件一起打包
ANDROID_EXTRA_LIBS += $$PWD/androidlib/libavcodec.so
ANDROID_EXTRA_LIBS += $$PWD/androidlib/libavfilter.so
ANDROID_EXTRA_LIBS += $$PWD/androidlib/libavformat.so
ANDROID_EXTRA_LIBS += $$PWD/androidlib/libavutil.so
ANDROID_EXTRA_LIBS += $$PWD/androidlib/libswresample.so
ANDROID_EXTRA_LIBS += $$PWD/androidlib/libswscale.so
}
pkgconfig查找:
# 使用 pkg-config 查找 FFmpeg 4 的库
CONFIG += link_pkgconfig
PKGCONFIG += libavcodec libavformat libavutil libswscale# 如果需要使用其他 FFmpeg 组件,可以添加它们
# PKGCONFIG += libavfilter libavdevice libavformat libswresample# 添加包含目录
INCLUDEPATH += $$system(pkg-config --cflags-only-I libavcodec libavformat libavutil libswscale)# 添加库目录
LIBS += $$system(pkg-config --libs libavcodec libavformat libavutil libswscale)
我的具体位置:
CONFIG += link_pkgconfig
PKGCONFIG += sdl2LIBS += -L/home/enpht/sdk/ffmpeg4/ffmpeg_build/lib/ -lavcodec -lavformat -lavutil -lswscale -lavfilter -lavdevice -lswresample -lfdk-aac
INCLUDEPATH += /home/enpht/sdk/ffmpeg4/ffmpeg_build/include
DEPENDPATH += /home/enpht/sdk/ffmpeg4/ffmpeg_build/include
头文件导入
//必须加以下内容,否则编译不能通过,为了兼容C和C99标准
#ifndef INT64_C
#define INT64_C
#define UINT64_C
#endif//引入ffmpeg头文件
extern "C" {
#include "libavutil/opt.h"
#include "libavutil/time.h"
#include "libavutil/frame.h"
#include "libavutil/pixdesc.h"
#include "libavutil/avassert.h"
#include "libavutil/imgutils.h"
#include "libavutil/ffversion.h"
#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h"
#include "libswresample/swresample.h"
#include "libavformat/avformat.h"
#include "libavfilter/avfilter.h" #ifdef ffmpegdevice
#include "libavdevice/avdevice.h"
#endif#ifndef gcc45
#include "libavutil/hwcontext.h"
//#include "libavutil/hwcontext_qsv.h"
#endif
}
ffmpeg命令行
主要命令参数:
命令参数 | 内容 | 命令参数 | 内容 |
---|---|---|---|
-version | 显示版本 | -bsfs | 显示可用比特流filter |
-buildconf | 显示编译配置 | -protocols | 显示可用的协议 |
-formats | 显示可用格式 (muxers+demuxers) | -filters | 显示可用的过滤器 |
-muxers | 显示可用复用器 | -pix_fmts | 显示可用的像素格式 |
-demuxers | 显示可用解复用器 | -layouts | 显示标准声道名称 |
-codecs | 显示可用编解码器 (decoders+encoders) | -sample_fmts | 显示可用的音频采样 格式 |
-decoders | 显示可用解码器 | -colors | 显示可用的颜色名称 |
-encoders | 显示可用编码器 |
查看具体所支持的类型:
语法:
ffmepg -h type=name
比如:
ffmpeg -h muxer=flv
ffmpeg -h filter=atempo (atempo调整音频播放速率)
ffmpeg -h encoder=libx264
ffmpeg/ffplay/ffprobe3区别
◼ffmpeg:
Hyper fast Audio and Video encoder
超快音视频编码器(类似爱剪辑)
◼ffplay:
Simple media player简单媒体播放器
◼ffprobe:
Simple multimedia streams analyzer
简单多媒体流分析器
◼基本信息: ffmpeg -h
◼高级信息: ffmpeg -h long
◼所有信息: ffmpeg -h full
ffplay命令
播放命令
选项 | 说明 | 选项 | 说明 |
---|---|---|---|
q, ESC | 退出播放 | t | 循环切换字幕流 |
f | 全屏切换 | c | 循环切换节目 |
p, SPC | 暂停 | w | 循环切换过滤器或显 示模式 |
m | 静音切换 | s | 逐帧播放 |
9, 0 | 9减少音量, 0增加音量 | left/right | 向后/向前拖动10秒 |
/, * | /减少音量, *增加音量 | down/up | 向后/向前拖动1分钟 |
a | 循环切换音频流 | 鼠标右键单击 | 拖动与显示宽度对应 百分比的文件进行播 放 |
v | 循环切换视频流 | 鼠标左键双击 | 全屏切换 |
命令选项
◼ -x width 强制显示宽带。
◼ -y height 强制显示高度。
◼ -video_size size 帧尺寸 设置显示帧存储(WxH格式),仅适用于类似
原始YUV等没有包含帧大小(WxH)的视频。
比如: ffplay -pixel_format yuv420p -video_size 320x240 -framerate 5 yuv420p_320x240.yuv
◼ -pixel_format format 格式设置像素格式。
◼ -fs 以全屏模式启动。
◼ -an 禁用音频(不播放声音)
◼ -vn 禁用视频(不播放视频)
◼ -sn 禁用字幕(不显示字幕)
◼ -ss pos 根据设置的秒进行定位拖动,注意时间单位:比如’55’ 55seconds, ‘12:03:45’ ,12 hours, 03 minutes and 45 seconds, ‘23.189’ 23.189second
◼ -t duration 设置播放视频/音频长度,时间单位如 -ss选项
◼ -bytes 按字节进行定位拖动(0=off 1=on -1=auto)。
◼ -seek_interval interval 自定义左/右键定位拖动间隔(以秒为单位),默认值为10秒(代码没有看到实现)
◼ -nodisp 关闭图形化显示窗口,视频将不显示
◼ -noborder 无边框窗口
◼ -volume vol 设置起始音量。音量范围[0 ~100]
◼ -f fmt 强制使用设置的格式进行解析。比如-f s16le
◼ -window_title title 设置窗口标题(默认为输入文件名)
◼ -loop number 设置播放循环次数
◼ -showmode mode 设置显示模式,可用的模式值: 0 显示视频,1 显示音频波形, 2 显示音频频谱。缺省为0,如果视频不存在则自动选择2
◼ -vf filtergraph 设置视频滤镜
◼ -af filtergraph 设置音频滤镜
◼ -stats 打印多个回放统计信息,包括显示流持续时间,编解码器参数,流中的当前位置,以及音频/视频同步差值。默认情况下处于启用状态,要显式禁用它则需要指定-nostats。。
◼ -fast 非标准化规范的多媒体兼容优化。
◼ -genpts 生成pts。
◼ -sync type 同步类型 将主时钟设置为audio(type=audio), video(type=video)或external(type=ext),默认是audio为主时钟。
◼ -ast audio_stream_specifier 指定音频流索引,比如-ast 3,播放流索引为3的音频流
◼ -vst video_stream_specifier指定视频流索引,比如-vst 4,播放流索引为4的视频流
◼ -sst subtitle_stream_specifier 指定字幕流索引,比如-sst 5,播放流索引为5的字幕流
◼ -autoexit 视频播放完毕后退出。
◼ -exitonkeydown 键盘按下任何键退出播放
◼ -exitonmousedown 鼠标按下任何键退出播放
◼ -codec:media_specifier codec_name 强制使用设置的多媒体解码器,media_specifier可用值为a(音频), v(视频)和s字幕。比如-codec:v h264_qsv 强制视频采用h264_qsv解码
◼ -acodec codec_name 强制使用设置的音频解码器进行音频解码
◼ -vcodec codec_name 强制使用设置的视频解码器进行视频解码
◼ -scodec codec_name 强制使用设置的字幕解码器进行字幕解码
◼ -autorotate 根据文件元数据自动旋转视频。值为0或1 ,默认为1。
◼ -framedrop 如果视频不同步则丢弃视频帧。当主时钟非视频时钟时默认开启。若需禁用则使用 -noframedrop
◼ -infbuf 不限制输入缓冲区大小。尽可能快地从输入中读取尽可能多的数据。播放实时流时默认启用,如果未及时读取数据,则可能会丢弃数据。此选项将不限制缓冲区的大小。若需禁用则使用-noinfbuf
播放例子
◼ 播放本地文件
◼ ffplay -window_title “test time” -ss 2 -t 10 -autoexit test.mp4
◼ ffplay buweishui.mp3
◼ 播放网络流
◼ ffplay -window_title “rtmp stream”
rtmp://202.69.69.180:443/webcast/bshdlive-pc
◼ 强制解码器
◼ mpeg4解码器: ffplay -vcodec mpeg4 test.mp4
◼ h264解码器: ffplay -vcodec h264 test.mp4
◼ 禁用音频或视频
◼ 禁用音频: ffplay test.mp4 -an
◼ 禁用视频: ffplay test.mp4 -vn
◼ 播放YUV数据
◼ ffplay -pixel_format yuv420p -video_size 320x240 -framerate 5
yuv420p_320x240.yuv
◼ 播放RGB数据
◼ ffplay -pixel_format rgb24 -video_size 320x240 -i rgb24_320x240.rgb
◼ ffplay -pixel_format rgb24 -video_size 320x240 -framerate 5 -i rgb24_320x240.rgb
◼ 播放PCM数据
◼ ffplay -ar 48000 -ac 2 -f f32le 48000_2_f32le.pcm
-ar set audio sampling rate (in Hz) (from 0 to INT_MAX) (default 0)
-ac set number of audio channels (from 0 to INT_MAX) (default 0)
过滤器
◼ 视频旋转
ffplay -i test.mp4 -vf transpose=1
◼ 视频反转
ffplay test.mp4 -vf hflip
ffplay test.mp4 -vf vflip
◼ 视频旋转和反转
ffplay test.mp4 -vf hflip,transpose=1
◼ 音频变速播放
ffplay -i test.mp4 -af atempo=2
◼ 视频变速播放
ffplay -i test.mp4 -vf setpts=PTS/2
◼ 音视频同时变速
ffplay -i test.mp4 -vf setpts=PTS/2 -af atempo=2
ffmpeg命令
主要命令
◼ 主要参数:
-i 设定输入流
-f 设定输出格式(format)
-ss 开始时间
-t 时间长度
◼ 视频参数:
-vframes 设置要输出的视频帧数
-b 设定视频码率
-b:v 视频码率
-r 设定帧速率
-s 设定画面的宽与高
-vn 不处理视频
-aspect aspect 设置横纵比 4:3 16:9 或 1.3333 1.7777
-vcodec 设定视频编解码器,如果用copy表示原始编解码数据必须被拷贝
-vf 视频过滤器
◼ 音频参数:
-aframes 设置要输出的音频帧数
-b:a 音频码率
-ar 设定采样率
-ac 设定声音的Channel数
-acodec 设定声音编解码器,如果用copy表示原始编解码数据必须被拷贝。
-an 不处理音频
-af 音频过滤器
例子
修改参数
◼ 修改mp4视频参数,并且转码265:
ffmpeg -i test.mp4 -vframes 300 -b:v 300k -r 30 -s 640x480 -aspect 16:9 -vcodec libx265 out1.mp4
◼ 提取音频:
ffmpeg -i test.mp4 -b:a 192k -ar 48000 -ac 2 -acodec libmp3lame -aframes 200 out2.mp3
◼ 保留封装格式
纯音频:ffmpeg -i test.mp4 -acodec copy -vn audio.mp4
纯视频:ffmpeg -i test.mp4 -vcodec copy -an video.mp4
提取音视频
◼ 提取视频
保留编码格式: ffmpeg -i test.mp4 -vcodec copy -an test_copy.h264
强制格式: ffmpeg -i test.mp4 -vcodec libx264 -an test.h264
◼ 提取音频
保留编码格式: ffmpeg -i test.mp4 -acodec copy -vn test.aac
强制格式: ffmpeg -i test.mp4 -acodec libmp3lame -vn test.mp3
提取YUV和PCM
◼ 提取YUV
提取3秒数据,分辨率和源视频一致
ffmpeg -i test_1280x720.mp4 -t 3 -pix_fmt yuv420p yuv420p_orig.yuv
提取3秒数据,分辨率转为320x240
ffmpeg -i test_1280x720.mp4 -t 3 -pix_fmt yuv420p -s 320x240 yuv420p_320x240.yuv
◼ 提取RGB
提取3秒数据,分辨率转为320x240
ffmpeg -i test.mp4 -t 3 -pix_fmt rgb24 -s 320x240 rgb24_320x240.rgb
RGB和YUV之间的转换
ffmpeg -s 320x240 -pix_fmt yuv420p -i yuv420p_320x240.yuv -pix_fmt rgb24 rgb24_320x240_2.rgb
◼ 提取PCM
ffmpeg -i buweishui.mp3 -ar 48000 -ac 2 -f s16le 48000_2_s16le.pcm
ffmpeg -i buweishui.mp3 -ar 48000 -ac 2 -sample_fmt s16 out_s16.wav
ffmpeg -i buweishui.mp3 -ar 48000 -ac 2 -codec:a pcm_s16le out2_s16le.wav
ffmpeg -i buweishui.mp3 -ar 48000 -ac 2 -f f32le 48000_2_f32le.pcm
ffmpeg -i test.mp4 -t 10 -vn -ar 48000 -ac 2 -f f32le 48000_2_f32le_2.pcm
转封装
◼ 保持编码格式:
ffmpeg -i test.mp4 -vcodec copy -acodec copy test_copy.ts
ffmpeg -i test.mp4 -codec copy test_copy2.ts
◼ 改变编码格式:
ffmpeg -i test.mp4 -vcodec libx265 -acodec libmp3lame out_h265_mp3.mkv
◼ 修改帧率:
ffmpeg -i test.mp4 -r 15 -codec copy output.mp4 (错误命令)
ffmpeg -i test.mp4 -r 15 output2.mp4
◼ 修改视频码率:
ffmpeg -i test.mp4 -b 400k output_b.mkv (此时音频也被重新编码)
◼ 修改视频码率:
ffmpeg -i test.mp4 -b:v 400k output_bv.mkv
◼ 修改音频码率:
ffmpeg -i test.mp4 -b:a 192k output_ba.mp4
如果不想重新编码video,需要加上-vcodec copy
◼ 修改音视频码率:
ffmpeg -i test.mp4 -b:v 400k -b:a 192k output_bva.mp4
◼ 修改视频分辨率:
ffmpeg -i test.mp4 -s 480x270 output_480x270.mp4
◼ 修改音频采样率:
ffmpeg -i test.mp4 -ar 44100 output_44100hz.mp4
裁剪
◼ 找三个不同的视频每个视频截取10秒内容
ffmpeg -i 沙海02.mp4 -ss 00:05:00 -t 10 -codec copy 1.mp4
ffmpeg -i 复仇者联盟3.mp4 -ss 00:05:00 -t 10 -codec copy 2.mp4
ffmpeg -i 红海行动.mp4 -ss 00:05:00 -t 10 -codec copy 3.mp4
如果音视频格式不统一则强制统一为 -vcodec libx264 -acodec aac
◼ 将上述1.mp4/2.mp4/3.mp4转成ts格式
ffmpeg -i 1.mp4 -codec copy -vbsf h264_mp4toannexb 1.ts
ffmpeg -i 2.mp4 -codec copy -vbsf h264_mp4toannexb 2.ts
ffmpeg -i 3.mp4 -codec copy -vbsf h264_mp4toannexb 3.ts
分离某些封装格式(例如MP4/FLV/MKV等)中的H.264的时候,需要首先写入
SPS和PPS,否则会导致分离出来的数据没有SPS、 PPS而无法播放。 H.264码流
的SPS和PPS信息存储在AVCodecContext结构体的extradata中。需要使用ffmpeg
中名称为“h264_mp4toannexb”的bitstream filter处理
◼ 转成flv格式
ffmpeg -i 1.mp4 -codec copy 1.flv
ffmpeg -i 2.mp4 -codec copy 2.flv
ffmpeg -i 3.mp4 -codec copy 3.flv
合并
◼ 以MP4格式进行拼接
方法1: ffmpeg -i “concat:1.mp4|2.mp4|3.mp4” -codec copy out_mp4.mp4
方法2: ffmpeg -f concat -i mp4list.txt -codec copy out_mp42.mp4
◼ 以TS格式进行拼接
方法1: ffmpeg -i “concat:1.ts|2.ts|3.ts” -codec copy out_ts.mp4
方法2: ffmpeg -f concat -i tslist.txt -codec copy out_ts2.mp4
◼ 以FLV格式进行拼接
方法1: ffmpeg -i “concat:1.flv|2.flv|3.flv” -codec copy out_flv.mp4
方法2: ffmpeg -f concat -i flvlist.txt -codec copy out_flv2.mp4
◼ 方法1只适用部分封装格式,比如TS
◼ 建议:
(1)使用方法2进行拼接
(2)转成TS格式再进行拼接
◼ 修改音频编码
ffmpeg -i 2.mp4 -vcodec copy -acodec ac3 -vbsf h264_mp4toannexb 2.ts
ffmpeg -i “concat:1.ts|2.ts|3.ts” -codec copy out1.mp4 结果第二段没有声音
◼ 修改音频采样率
ffmpeg -i 2.mp4 -vcodec copy -acodec aac -ar 96000 -vbsf h264_mp4toannexb 2.ts
ffmpeg -i “concat:1.ts|2.ts|3.ts” -codec copy out2.mp4 第二段播放异常
◼ 修改视频编码格式
ffmpeg -i 1.mp4 -acodec copy -vcodec libx265 1.ts
ffmpeg -i “concat:1.ts|2.ts|3.ts” -codec copy out3.mp4
◼ 修改视频分辨率
ffmpeg -i 1.mp4 -acodec copy -vcodec libx264 -s 800x472 -vbsf h264_mp4toannexb 1.ts
ffmpeg -i “concat:1.ts|2.ts|3.ts” -codec copy out4.mp4
◼ 注意:
◼ 把每个视频封装格式也统一为ts,拼接输出的时候再输出你需要的封装格
式,比如MP4
◼ 视频分辨率可以不同,但是编码格式需要统一
◼ 音频编码格式需要统一,音频参数(采样率/声道等)也需要统一
图片和视频互转
◼ 截取一张图片
ffmpeg -i test.mp4 -y -f image2 -ss 00:00:02 -vframes 1 -s 640x360 test.jpg
ffmpeg -i test.mp4 -y -f image2 -ss 00:00:02 -vframes 1 -s 640x360 test.bmp
-i 输入
-y 覆盖
-f 格式
image2 一种格式
-ss 起始值
-vframes 帧 如果大于1 那么 输出加%03d test%03d.jpg
-s 格式大小size
◼ 转换视频为图片(每帧一张图):
ffmpeg -i test.mp4 -t 5 -s 640x360 -r 15 frame%03d.jpg
◼ 图片转换为视频:
ffmpeg -f image2 -i frame%03d.jpg -r 25 video.mp4
◼ 从视频中生成GIF图片
ffmpeg -i test.mp4 -t 5 -r 1 image1.gif
ffmpeg -i test.mp4 -t 5 -r 25 -s 640x360 image2.gif
◼ 将 GIF 转化为 视频
ffmpeg -f gif -i image2.gif image2.mp4
屏幕录制
◼ 先安装dshow软件 Screen Capturer Recorder,
项目地址: https://sourceforge.net/projects/screencapturer/files/
然后查看可用设备名字: ffmpeg -list_devices true -f dshow -i dummy
◼ 录制视频(默认参数)
桌面: ffmpeg -f dshow -i video=“screen-capture-recorder” v-out.mp4
摄像头: ffmpeg -f dshow -i video=“Integrated Webcam” -y v-out2.flv (要根据自己摄像头名称)
◼ 录制声音(默认参数)
系统声音: ffmpeg -f dshow -i audio=“virtual-audio-capturer” a-out.aac
系统+麦克风声音: ffmpeg -f dshow -i audio=“麦克风 (Realtek Audio)” -f dshow -i audio=“virtual-audio-capturer” -filter_complex amix=inputs=2:duration=first:dropout_transition=2 a-out2.aac
◼ 同时录制声音和视频(默认参数)
ffmpeg -f dshow -i audio=“麦克风 (Realtek Audio)” -f dshow -i audio=“virtualaudio-capturer” -filter_complex amix=inputs=2:duration=first:dropout_transition=2 -f dshow -i video=“screen-capture-recorder” -y av-out.flv
◼ 查看视频录制的可选参数
ffmpeg -f dshow -list_options true -i video=“screen-capture-recorder”
◼ 查看视频录制的可选参数
ffmpeg -f dshow -list_options true -i audio="virtual-audio-capturer“
指定参数录制:
◼ ffmpeg -f dshow -i audio=“麦克风 (Realtek Audio)” -f dshow -i
audio=“virtual-audio-capturer” -filter_complex
amix=inputs=2:duration=first:dropout_transition=2 -f dshow -video_size
1920x1080 -framerate 15 -pixel_format yuv420p -i video=“screen-capturerecorder” -vcodec h264_qsv -b:v 3M -y av-out.flv
◼ ffmpeg -f dshow -i audio=“麦克风 (Realtek Audio)” -f dshow -i
audio=“virtual-audio-capturer” -filter_complex
amix=inputs=2:duration=first:dropout_transition=2 -f dshow -i
video=“screen-capture-recorder” -vcodec h264_qsv -b:v 3M -r 15 -y avout2.mp4
◼ ffmpeg -f dshow -i audio=“麦克风 (Realtek Audio)” -f dshow -i
audio=“virtual-audio-capturer” -filter_complex
amix=inputs=2:duration=first:dropout_transition=2 -f dshow -framerate 15
-pixel_format yuv420p -i video=“screen-capture-recorder” -vcodec
h264_qsv -b:v 3M -r 15 -y av-out3.mp4
推流
◼ 直播拉流
ffplay rtmp://server/live/streamName
ffmpeg -i rtmp://server/live/streamName -c copy dump.flv
对于不是rtmp的协议 -c copy要谨慎使用
◼ 可用地址
HKS: rtmp://live.hkstv.hk.lxdns.com/live/hks2
大熊兔(点播): rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov
CCTV1高清: http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8
ffmpeg -i http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8 -c copy cctv1.ts
ffmpeg -i http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8 cctv1.flv
ffmpeg -i http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8 -acodec aac -vcodec libx264
cctv1-2.flv
CCTV3高清: http://ivi.bupt.edu.cn/hls/cctv3hd.m3u8
CCTV5高清: http://ivi.bupt.edu.cn/hls/cctv5hd.m3u8
CCTV5+高清: http://ivi.bupt.edu.cn/hls/cctv5phd.m3u8
CCTV6高清: http://ivi.bupt.edu.cn/hls/cctv6hd.m3u8
◼ 直播推流
ffmpeg -re -i out.mp4 -c copy flv rtmp://server/live/streamName
-re,表示按时间戳读取文件
◼ rtsp和rtmp推流
// rtsp推流(文件推流)
ffmpeg -re -i test.mp4 -rtsp_transport tcp -c copy -f rtsp rtsp://127.0.0.1:554/live/test// rtsp推流(文件循环推流)
ffmpeg -re -stream_loop -1 -i test.mp4 -rtsp_transport tcp -c copy -f rtsp rtsp://127.0.0.1:554/live/test// rtmp推流(文件推流)
ffmpeg -re -i test.mp4 -vcodec h264_nvenc -acodec aac -f flv rtmp://192.168.1.3:1935/live/test// rtmp推流(文件循环推流)
ffmpeg -re -stream_loop -1 -i test.mp4 -vcodec h264 -acodec aac -f flv rtmp://127.0.0.1:1935/live/test
SDL显示的API
SDL视频显示函数简介
• SDL_Init():初始化SDL系统
• SDL_CreateWindow():创建窗口SDL_Window
• SDL_CreateRenderer():创建渲染器SDL_Renderer
• SDL_CreateTexture():创建纹理SDL_Texture
• SDL_UpdateTexture():设置纹理的数据
• SDL_RenderCopy():将纹理的数据拷贝给渲染器
• SDL_RenderPresent():显示
• SDL_Delay():工具函数,用于延时。
• SDL_Quit():退出SDL系统
SDL中事件和多线程
SDL多线程
• 函数
• SDL_CreateThread():创建一个线程
• SDL_LockMutex(), SDL_UnlockMutex():互斥量操作
• 数据结构
• SDL_Thread:线程的句柄
SDL事件
• 函数
• SDL_WaitEvent():等待一个事件
• SDL_PushEvent():发送一个事件
• SDL_PumpEvents():将硬件设备产生的事件放入事件队列
• SDL_PeepEvents():从事件队列提取一个事件
• 数据结构
• SDL_Event:代表一个事件
ffmpeg的API
参考:FFmpeg架构全面分析 - Coder个人博客 - 博客园 (cnblogs.com)
整体框架
1、AVUtil: 核心工具库,许多其他模块都会依赖该库做一些基本的音视频处理操作,如log信息、版本信息等。
2、AVFormat: 文件格式和协议库,封装了Protocol层和Demuxer、Muxer层。其中实现了目前多媒体领域中的绝大多数媒体封装格式,包括封装和解封装,如MP4、FLV、KV、TS等文件封装格式,RTMP、RTSP、MMS、HLS等网络协议封装格式。FFmpeg是否支持某种媒体封装格式,取决于编译时是否包含了该格式的封装库。根据实际需求,可进行媒体封装格式的扩展,增加自己定制的封装格式,即在AVFormat中增加自己的封装处理模块。
3、AVCodec: 编解码库,封装了Codec库,AVCodec中实现了目前多媒体领域绝大多数常用的编解码格式,即支持编码,也支持解码。AVCodec除了支持MPEG4、AAC、MJPEG等自带的媒体编解码格式之外,还支持第三方的编解码器,如H.264(AVC)编码,需要使用x264编码器;H.265(HEVC)编码,需要使用x264编码器;MP3(mp3lame)编码,需要使用libmp3lame编码器。如果希望增加自己的编码格式,或者硬件编解码,则需要在AVCodec中增加相应的编解码模块。默认不会添加libx264、libfdk_aac等三方库的,但可以插件形式添加,然后提供统一接口。
4、AVFilter: 提供了一个通用的音频、视频、字幕等滤镜处理框架。在AVFilter中,滤镜框架可以有多个输入和多个输出。
5、AVDevice: 输入输出设备库,音/视频的输入输出需要确保该模块已经打开
6、SwrResample: 该模块可用于音频重采样,可以对数字音频进行声道数、数据格式、采样率、等多种基本信息的转换,同时支持音频通道布局转换与布局调整。
7、SWScale: 提供了高级别的图像转换API,例如它允许进行图像缩放和像素格式转换,常见于将图像从1080p转换成720p或者480p等的缩放,或者将图像数据从YUV420p转换成YUYV,或者YUV转RGB等图像格式转换。
8、PostProc: 该模块可用于进行后期处理,当我们使用AVFilter的时 候需要打开该模块的开关,因为Filter中会使用到该模块的一些基础函数。
结构体以及关系
重要结构体
AVFormatContext 封装格式上下文结构体,也是统领全局的结构体,保存了视频文件封装格式相关信息。
• iformat:输入媒体的AVInputFormat,比如指向AVInputFormat ff_flv_demuxer
• nb_streams:输入媒体的AVStream 个数
• streams:输入媒体的AVStream []数组
• duration:输入媒体的时长(以微秒为单位),计算方式可以参考av_dump_format()函数。
• bit_rate:输入媒体的码率
AVCodecContext 编码器上下文结构体
• codec:编解码器的AVCodec,比如指向AVCodec ff_aac_latm_decoder
• width, height:图像的宽高(只针对视频)
• pix_fmt:像素格式(只针对视频)
• sample_rate:采样率(只针对音频)
• channels:声道数(只针对音频)
• sample_fmt:采样格式(只针对音频)
AVCodecParameters 用于存储编码流的属性。在新版本中被设计来替代已废弃的 AVCodecContext
• codectype:编解码器类型,取值为AVMEDIATYPEVIDEO、AVMEDIATYPEAUDIO、 AVMEDIATYPE_SUBTITLE之一。
• codec_id:编解码器的ID,取值为枚举类型AVCodecID中的一种。
• codec_tag:编解码器标签。
• extradata:对于某些编码器(如H.264)需要额外的信息来解码,这些信息称为“extradata”。该成员变量保存了这些额外信息的地址。
• extradata_size:extradata所占用的字节数。
• format:音视频帧的像素或采样格式,例如对于视频来说,可以是AVPIXFMTYUV420P、AVPIXFMTNV12等等。对于音频来说,可以是AVSAMPLEFMTS16、AVSAMPLEFMTFLTP等等。
• bit_rate:比特率,用于描述音视频流的质量,单位为bps。
• bitspercoded_sample:每个编码的样本所占用的位数。
• bitsperraw_sample:每个采样的样本所占用的位数。
• profile:编解码器的协议等级。
• level:编解码器的协议等级。
• width:视频帧宽度。
• height:视频帧高度。
• sample_rate:音频采样率。
• channels:音频声道数。
• samplefmt:音频采样格式,例如AVSAMPLEFMTS16、AVSAMPLEFMT_FLTP等等。
• channellayout:音频声道布局,例如AVCHLAYOUTMONO、AVCHLAYOUT_STEREO等等。
• sampleaspectratio:音视频帧宽高比。
• fpsfirstnum:帧率分子。
• fpssecondnum:帧率分母。
• delay:编码器的编码时延。
• seek_preroll:如果需要进行关键帧的跳转,这个字段表示需要跳过的帧数。
AVStream 视频文件中每个视频(音频)流对应一个该结构体
• index:标识该视频/音频流
• id:流的ID,用于在文件格式中识别流。
• time_base:该流的时基, PTS*time_base=真正的时间(秒)
• avg_frame_rate: 该流的帧率
• duration:该视频/音频流长度
• codecpar:编解码器参数属性
AVPacket 存储一帧压缩编码数据
• pts:显示时间戳
• dts:解码时间戳
• data:压缩编码数据
• size:压缩编码数据大小
• pos:数据的偏移地址
• stream_index:所属的AVStream
AVFrame 存储一帧解码后像素(采样)数据
• data:解码后的图像像素数据(音频采样数据)
• linesize:对视频来说是图像中一行像素的大小;对音频来说是整个音频帧的大小
• width, height:图像的宽高(只针对视频)
• key_frame:是否为关键帧(只针对视频) 。
• pict_type:帧类型(只针对视频) 。例如I, P, B
• sample_rate:音频采样率(只针对音频)
• nb_samples:音频每通道采样数(只针对音频)
• pts:显示时间戳
AVCodec 每种视频(音频)编解码器(例如H.264解码器)对应一个该结构体
• name:编解码器名称
• type:编解码器类型
• id:编解码器ID
• 一些编解码的接口函数,比如int (*decode)()
AVOutputFormat 和 AVInputFormat ffmpeg内部使用
• name:封装格式名称
• extensions:封装格式的扩展名
• id:封装格式ID
• 一些封装格式处理的接口函数,比如read_packet()
AVCodecParameters
• codec_type:媒体类型,比如AVMEDIA_TYPE_VIDEO AVMEDIA_TYPE_AUDIO等
• codec_id:编解码器类型, 比如AV_CODEC_ID_H264 AV_CODEC_ID_AAC等。
AVDictionary
简单的key/value存储,经常使用AVDictionary设置或读取内部参数。声明如下,具体实现在libavutil模块中的dict.c/h,提供此结构体是为了与libav兼容,但它实现效率低下,在FFmpeg 4.1.3版本中已弃用(deprecated),推荐使用libavutil模块中的tree.c/h来替代
AVDictionary* dict = nullptr;
av_dict_set(&dict, “max_delay”, “100”, 0); // 设置
很多地方需要参数的时候都会使用。也可以自行打印:
AVDictionaryEntry* t = nullptr;
while (t = av_dict_get(dict , “”, t, AV_DICT_IGNORE_SUFFIX)) {
fprintf(stdout, “key: %s, value: %s\n”, t->key, t->value); // iterate over all entries in d
}
av_dict_free(&dict); // 释放
AVFilter 过滤器
const char *name; // overlay
const AVFilterPad *inputs;
const AVFilterPad *outputs;
AVFilterContext 过滤器上下文
AVFilterGraph 过滤器图,对整个过滤器进行管道拼接和管理
struct AVFilterGraph
{
AVFilterContext **filters;
unsigned nb_filters;
}
AVFilterLink 两个过滤器之间的连接
struct AVFilterLink
{
AVFilterContext *src;
AVFilterPad *srcpad;
AVFilterContext *dst;
AVFilterPad *dstpad;
struct AVFilterGraph *graph;
}
重要结构体关系
-
AVFormatContext和AVInputFormat之间的关系
AVFormatContext API调用
AVInputFormat 主要是FFMPEG内部调用 -
AVCodecContext和AVCodec之间的关系
AVCodecContext 编码器上下文结构体
AVCodec 每种视频(音频)编解码器
-
AVFormatContext、AVStream和AVCodecContext之间的关系
-
AVFormatContext
是最顶层的结构,代表整个多媒体文件。 -
AVStream
是AVFormatContext
的一部分,代表文件中的单个媒体流。 -
AVCodecContext
是与AVStream
相关联的,代表单个媒体流的编解码器上下文。
-
AVPacket和AVFrame之间的关系
AVPacket是AVFrame编码后的数据。
-
AVFilterContext,AVFilterGraph,和AVFilter的关系:
AVFilter是具体的各个过滤器,有不同功能。AVFilterContext是各个AVFilter的上下文,用于后期拼接,以及参数设置,管理filter与外部的联系 。AVFilterGraph是整个过滤器管理器,类似gstreamer的插件管道,用于初始化和开启过滤器。
内存模型
内部使用AVBuffer保存数据,内部有一个引用计数来保证内存正确释放。
引用计数原理:
◼ 对于多个AVPacket共享同一个缓存空间, FFmpeg使用的引用计数的机制(reference-count) :
- 初始化引用计数为0,只有真正分配AVBuffer的时候,引用计数初始化为1;
- 当有新的Packet引用共享的缓存空间时, 就将引用计数+1;
- 当释放了引用共享空间的Packet,就将引用计数-1;引用计数为0时,就释放掉引用的缓存空间AVBuffer。
- AVFrame也是采用同样的机制。
所以,从现有的Packet拷贝一个新Packet的时候,有两种情况:
• ①两个Packet的buf引用的是同一数据缓存空间,这时候要注意数据缓存空间的释放问题;
• ②两个Packet的buf引用不同的数据缓存空间,每个Packet都有数据缓存空间的copy;
AVPacket:
函数 | 说明 |
---|---|
AVPacket *av_packet_alloc(void); | 分配AVPacket 这个时候和buffer没有关系 |
void av_packet_free(AVPacket **pkt); | 释放AVPacket 和_alloc对应 |
void av_init_packet(AVPacket *pkt); | 初始化AVPacket 只是单纯初始化pkt字段 |
int av_new_packet(AVPacket *pkt, int size); | 给AVPacket的buf分配内存, 引 用计数初始化为1 |
int av_packet_ref(AVPacket *dst, const AVPacket *src); | 增加引用计数 |
void av_packet_unref(AVPacket *pkt); | 减少引用计数 |
void av_packet_move_ref(AVPacket *dst, AVPacket *src); | 转移引用计数 |
AVPacket av_packet_clone(const AVPacket *src); | 等于 av_packet_alloc()+av_packet_ref() |
int av_write_frame(AVFormatContext *s, AVPacket *pkt); | 顺序写帧。将编码数据包写入到多媒体容器格式中 |
void av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt); | 交替写帧。用于视频和音频同时存在的场景 |
void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt); | 打印pts,dts,duration等信息 |
AVFrame:
函数 | 说明 |
---|---|
AVFrame *av_frame_alloc(void); | 分配AVFrame |
void av_frame_free(AVFrame **frame); | 释放AVFrame |
int av_frame_ref(AVFrame *dst, const AVFrame *src); | 增加引用计数 |
void av_frame_unref(AVFrame *frame); | 减少引用计数 |
void av_frame_move_ref(AVFrame *dst, AVFrame *src); | 转移引用计数 |
int av_frame_get_buffer(AVFrame *frame, int align); | 根据AVFrame分配内存 |
AVFrame *av_frame_clone(const AVFrame *src); | 等于 av_frame_alloc()+av_frame_ref() |
播放器框架:
函数用处
初始化
◼ av_register_all(): 注册所有组件,4.0已经弃用
◼ avdevice_register_all()对设备进行注册,比如V4L2等
◼ avformat_network_init();初始化网络库以及网络加密协议相关的库(比如openssl)
上下文相关
◼ avcodec_parameters_from_context(AVCodecParameters *par, const AVCodecContext *codec):将AVCodecContext结构体中码流参数拷⻉到AVCodecParameters结构体中 。
封装
◼ avformat_write_header(); 写媒体头
◼ av_write_frame/av_interleaved_write_frame: 写packet
◼ av_write_trailer():写媒体尾
◼ avformat_alloc_context();负责申请一个AVFormatContext结构的内存,并进行简单初始化
◼ avformat_free_context();释放该结构里的所有东西以及该结构本身
◼ avformat_close_input();关闭解复用器。关闭后就不再需要使用avformat_free_context 进行释放。
◼ avformat_open_input();打开输入视频文件
◼ avformat_find_stream_info(): 获取音视频文件信息
◼ av_read_frame(); 读取音视频包
◼ avformat_seek_file(); 定位文件
◼ av_seek_frame():定位文件,也可以移动播放位置
编码
◼ avcodec_register_all(); 注册所有可用的编解码器和格式。
◼ avcodec_find_encoder(); 根据ID创建编码器
◼ avcodec_find_encoder_by_name(); 根据名字查找并创建编码器
◼ avcodec_alloc_context3(); 分配并初始化 AVCodecContext 结构,存储编码器或解码器的参数
◼ avcodec_open2(); 打开指定的编码器或解码器,初始化它的上下文。需要在编码或解码前调用
◼ avcodec_send_frame(); 发送frame到编码器
◼ avcodec_receive_packet(); 接收编码后的packet
◼ av_rescale_q(); 改变时间基
◼ av_image_fill_arrays(); 填充图片数据
◼ avcodec_flush_buffers(); 用于清空编码器或解码器的缓冲区。这在处理流式数据时非常有用,比如在开始处理新的视频流时,确保先前的帧数据被清除
◼ avcodec_close(); 关闭
◼ avcodec_free_context();
◼
◼
解码
◼ avcodec_register_all(); 注册所有可用的编解码器和格式。
◼ avcodec_find_decoder(); 根据ID创建解码器
◼ avcodec_find_decoder_by_name(); 根据名字查找并创建编码器
◼ avcodec_alloc_context3(); 分配并初始化 AVCodecContext 结构,存储编码器或解码器的参数
◼ avcodec_open2(); 打开指定的编码器或解码器,初始化它的上下文。需要在编码或解码前调用
◼ avcodec_send_packet(); 发送packet到编码器
◼ avcodec_receive_frame(); 接收编码后的frame
◼ avcodec_flush_buffers(); 用于清空编码器或解码器的缓冲区。这在处理流式数据时非常有用,比如在开始处理新的视频流时,确保先前的帧数据被清除
◼ avcodec_close(); 关闭
◼ avcodec_free_context();
◼
◼
音频重采样
从uint_8 *data 的音频数据,转为AVFrame * 数据。
#include "libswresample/swresample.h"
重要结构体:SwrContext
◼ swr_alloc_set_opts(SwrContext *s , …); 根据设置的输出和输入的采样参数,创建上下文
◼ swr_convert(SwrContext *s, …); 重采样,根据上下文,将uint8_t *音频数据转换为AVFrame.data里面去。
◼ swr_init(SwrContext ctx); 初始化
◼ swr_free(SwrContext **ss);
◼
◼
过滤器
//#include <libavfilter/avfiltergraph.h>
#include <libavfilter/avfilter.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
◼ avfilter_register_all(); 注册过滤器
◼ avfilter_get_by_name(const char name); 根据名字创建过滤器
◼ av_buffersrc_add_frame(AVFilterContext ctx, AVFrame frame); 往源过滤器输入数据
◼ av_buffersink_get_frame(AVFilterContext ctx, AVFrame frame); 从终点过滤器中获取数据
◼ avfilter_graph_alloc(); 创建⼀个滤波器图实例 AVFilterGraph*
◼ avfilter_graph_parse2(); 根据 传递的字符串语法来创建一个或者多个滤镜上下文,多个滤镜会根据语法自动连接。同时会把新创建的滤镜上下文放进去滤镜容器。
◼ avfilter_graph_create_filter(…); 创建某个滤波器实例AVFilterContext(如果之前是空指针),设置参数并添加到AVFilterGraph中
◼ avfilter_graph_get_filter(); 根据名称获取 滤镜容器内部的某个滤镜上下文。
◼ avfilter_link(); 连接两个过滤器。从上一个过滤器的某个输出点,连接到下一个过滤器的某个输入点
◼ avfilter_graph_config(); 检查过滤器图,并且开启
◼ avfilter_graph_dump(); 将过滤器图导出txt
◼ avfilter_graph_free(); 释放内存,包括过滤器和上下文
◼ avfilter_init_str(); 使用提供的参数,初始化过滤器
相关文章:
个人ffmpeg笔记(一)
环境安装 QT环境安装 运行qt…run安装 下载地址:https://download.qt.io/archive/qt/ 下载地址:https://download.qt.io/archive/qt/5.12/5.12.10/ sudo apt install --reinstall libxcb-xinerama0 解决xcb问题 Ubuntu16.04打开Qt显示/home/user/.co…...
Python的3D可视化库【vedo】2-3 (plotter模块) 增删物体、控制相机
文章目录 4 Plotter类的方法4.3 渲染器内的物体操作4.3.1 添加物体4.3.2 移除物体4.3.3 渲染器的内容列表 4.4 相机控制4.4.1 访问相机对象4.4.2 重置相机状态4.4.3 移动相机位置4.4.4 改变相机焦点4.4.5 改变相机朝向的平面4.4.5 旋转相机4.4.6 对齐相机的上朝向4.4.7 缩放 ve…...
关于QMessageBox的一些使用总结和避坑指南
参考学习 Qt中QMessageBox的用法—看这一篇就够了 Qt:使用QMessageBox弹出标准对话框 QMessageBox模态与非模态及QT中的exec() 如何调整QMessageBox的大小 QSS 自定义QMessageBox python QMessageBox设置标签和按钮居中、中文按钮 使用建议 经过查看多方的资料&…...
LearnOpenGL学习(高级OpenGL -> 高级GLSL,几何着色器,实例化)
高级GLSL 内建变量 顶点着色器 gl_PointSoze : float 输出变量,用于控制渲染 GL_POINTS 型图元时,点的大小。可用于粒子系统。将其设置为 gl_Position.z 时,可以使点的距离越远,大小越大。创建出类似近视眼看远处灯光的效果 gl…...
for X_batch, y_batch in dataloader ,其中y_batch想转成list
for X_batch, y_batch in dataloader ,其中y_batch想转成list for X_batch, y_batch in dataloader:# y_batch数据类型的是 tensor组成的list# 初始化一个空列表来存储展平后的数据y_batch_flat []# 遍历y_batch 这个list中的每个张量for tensor in y_batch:# 展平…...
Kruskal最小生成树算法正确性证明
Kruskal: 每次考虑最短一条边, 如果会形成回路则不选择该边, 如果不会形成回路则选择该边, 直到选出了n-1条边 要点: 每次都选择不会形成回路的最短边 数学归纳法 ① n<2时, 显然成立 ② 设n k时成立, 则当n k1时: 将图划分为 子图A(k) 和 B(1) ∵ n k时成立 ∴ A(k)可…...
操作系统(12)内存分配
前言 操作系统内存分配是操作系统内存管理的重要组成部分,涉及将物理内存分配给各个程序以使用的过程。 一、内存分配的基本概念 内存分配指的是操作系统将物理内存分配给程序以使用。操作系统通过内存分配,确保每个程序都能获得足够的内存资源来执行其任…...
oracle client linux服务器安装教程
p13390677_112040_Linux-x86-64_4of7.zip 安装前,确认/etc/hosts文件已配置正确 cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 10.2…...
生信技能65 - SRA数据库公共数据自动化下载及SRA批量自动化拆分
根据NCBI Metadata数据表,实现SRA数据库公共数据自动化下载及SRA批量自动化拆分。 1. 程序逻辑 根据SraRunTable.csv自动从公共数据库下载SRA文件 ;模式0(默认)为下载模式,模式1为拆分模式,拆分支持进度显示;提取Metadata关键信息数据,重新写入新的文本文件。2. 运行示…...
ubuntu+ros新手笔记(五):初探anaconda+cuda+pytorch
深度学习三件套:初探anacondacudapytorch 系统ubuntu22.04 ros2 humble 1.初探anaconda 1.1 安装 安装过程参照【详细】Ubuntu 下安装 Anaconda 1.2 创建和删除环境 创建新环境 conda create -n your_env_name pythonx.x比如我创建了一个名为“py312“的环境…...
下载红米Note 9 Pro5G对应的LineageOS代码下载及编译
构建 LineageOS 进入网站:Info about gauguin | LineageOS Wiki,点击:Build for yourself,里面有详细的教程,我这里就按照Note 9 Pro 5G来。 机器环境 Ubuntu环境为:20.04.6LinagesOS版本:21-…...
数据链路层(Java)(MAC与IP的区别)
以太网协议: "以太⽹" 不是⼀种具体的⽹络, ⽽是⼀种技术标准; 既包含了数据链路层的内容, 也包含了⼀些物理 层的内容. 例如: 规定了⽹络拓扑结构, 访问控制⽅式, 传输速率等; 例如以太⽹中的⽹线必须使⽤双绞线; 传输速率有10M, 100M, 1000M等; 以太…...
Unity中Mesh重叠顶点合并参考及其应用
在Unity中,如果将一个模型文件(比如从max里面导出一个fbx文件)导入到编辑器中之后,Unity会把所有在原来在面列表中公用的顶点复制一份,保证每个三角形使用的顶点都是单独的,不与其它三角形共用顶点…...
Day3——墨刀原型设计
墨刀介绍 墨刀(Mockplus)是一款流行的在线原型设计和协作工具,适用于网页和移动应用的设计。以下是墨刀的一些主要特点和功能: 主要特点: 快速原型设计:墨刀提供了一系列的设计工具和组件,可…...
【JAVA】Java项目实战—移动端项目:天气查询APP
在移动互联网时代,天气查询应用程序(APP)是日常生活中不可或缺的一部分。无论是出门旅行、上班通勤,还是安排户外活动,获取实时天气信息都至关重要。Java作为一种强大且广泛使用的编程语言,特别适合用于开发…...
P1208 [USACO1.3] 混合牛奶 Mixing Milk(py)
题目描述 由于乳制品产业利润很低,所以降低原材料(牛奶)价格就变得十分重要。帮助 Marry 乳业找到最优的牛奶采购方案。 Marry 乳业从一些奶农手中采购牛奶,并且每一位奶农为乳制品加工企业提供的价格可能相同。此外,…...
day13 python(1)——python基础
【没有所谓的运气🍬,只有绝对的努力✊】 1、python简介 1.1 为什么学习python 1.2 python发展历史 python2.x和python3.x 版本里面有些是不兼容的。(我自己本地版本 3.11) 2、语言的分类 (1)编译型 …...
Tomcat原理(5)——tomcat最终实现
目录 一、什么是Servlet容器 二、ServletConfigMapping构建实现容器 ServletConfigMapping MyTomcat 三、优化server Server MyTomcat 四、匹配 代码如下: 测试如下: 上一篇博客已经为介绍了servelet的实现 ,这篇对上一篇博客进行补…...
善战者与细
《孙子兵法》说:善战者无赫赫战功。 《道德经》说:天下大事必做于细。 这两句话,可以结合来思考。如果,我们把事业,拆解为多个小项目,小项目拆解为小行动,也就是天下大事作于细。这种情况下&am…...
sqli-labs靶场第26-30关
第26关 这关将逻辑运算符,注释符以及空格给过滤了 我们先使用单引号进行闭合 这时我们查看源代码可以看到这一关过滤了很多字符 可以看到这里将or and / -- # 空格等字符都被注释了 空格被过滤了我们可以使用()来代替,and和or可以使用双写来绕过 因为…...
ffmpeg和ffplay命令行实战手册
文章目录 视频拼接用concat视频分段拼接(ffplay 不可调用seek函数进行seek)给视频添加黑边,让视频填充并居中显示不同分辨率视频分段拼接,并且,设置单个视频的缩放比例和摆放位置视频画中画复杂嵌套用overlay(ffplay 可调用seek函数进行seek)…...
240004】基于maven的java+ssm+mysql的房屋租赁系统的设计与实现
基于ssmmavenmysql的房屋租赁系统的设计与实现 1.项目描述2.运行环境3.项目截图4.源码获取 1.项目描述 该项目在原有的基础上进行了优化,包括新增了注册功能,房屋模糊查询功能,管理员和用户信息管理等功能,以及对网站界面进行了优…...
2.metagpt中的软件公司智能体 (ProductManager 角色)
1. 代码 ProductManager 类 from metagpt.actions import UserRequirement, WritePRD from metagpt.actions.prepare_documents import PrepareDocuments from metagpt.roles.role import Role, RoleReactMode from metagpt.utils.common import any_to_nameclass ProductMan…...
MOS管振铃现象
1,什么是振铃 用MOS管作为电子开关电路如下 单片机输出的PWM波形应该是规整的方波信号。但实际上确出现了下图的不稳定波形。这种上升沿和下降沿出现的不同程度的一小段震荡就叫做MOS管的振铃。如果振铃的峰值超过G端耐压,GS之间就会被击穿,…...
docker简单命令
docker images 查看镜像文件 docker ps -a 查看容器文件 docker rm 0b2 删除容器文件,id取前三位即可 docker rmi e64 删除镜像文件(先删容器才能删镜像),id取前三位即可 在包含Dockerfile文件的目录…...
XML基础学习
参考文章链接: XML基础学习 在w3school看到了XML的教程,想到以前工作学习中也接触到了XML,但只是简单搜索了解了下,没有认真去学习XML的基础,所以现在认真看下其基础部分,并写篇博客作为笔记记录下。 XML 简介 XML 被设计用来传输和存储数据。 什么是 XML? XML 指可…...
ARMS 用户体验监控正式发布原生鸿蒙应用 SDK
作者:杨兰馨(楠瑆) 背景 2024 年 10 月 22 日,华为正式发布了原生鸿蒙操作系统(HarmonyOS NEXT)。原生鸿蒙实现了系统底座全部自研,系统的流畅度、性能、安全特性等方面显著提升,也…...
如何使用微调后的Lora适配器?
Lora(Low-Rank Adaptation) 是一种高效的模型微调方法,尤其在自然语言处理和生成任务中得到了广泛应用。与传统的微调方法相比,Lora方法通过低秩适配器的方式,使得模型微调更为高效,且资源消耗更少。本文将…...
HAL 库:创建hal首要配置内容
第一步配置SYS(system系统) Debug(调试): Serial Wire 串行线(要用stick) Timebase Source:时基源 第二步配置RCC(reset and clodk controler)复位和时钟控…...
YOLOv9-0.1部分代码阅读笔记-experimental.py
experimental.py models\experimental.py 目录 experimental.py 1.所需的库和模块 2.class Sum(nn.Module): 3.class MixConv2d(nn.Module): 4.class Ensemble(nn.ModuleList): 5.def attempt_load(weights, deviceNone, inplaceTrue, fuseTrue): 1.所需的库和模块…...
如何高效获取Twitter数据:Apify平台上的推特数据采集解决方案
引言 在数据分析和市场研究领域,Twitter(现在的X)数据一直是重要的信息来源。但是,自从Twitter更改API定价策略后,获取数据的成本大幅提升。本文将介绍一个经济实惠的替代方案。 为什么需要Twitter数据? …...
【蓝凌表单】JSP组件常用语法整理
JSP组件常用语法整理 必填非必填写法//必填 $("[name=extendDataFormInfo.value(fd_344677482769e2)]").attr("validate","requiredvalue"); //非必填 $(...
设定“例外规则”:不完美也是完美
完美主义是一种追求极致的心态,它驱使我们不断追求更高的标准和更好的结果。然而,生活并不总是按照我们的计划进行,有时候我们需要灵活应对,设定一些“例外规则”来适应那些不完美的时刻。以下是一些实际的例子,展示如…...
01《Python数据分析》数据分析初探章节总结
目录 1 概述1.1 数据分析定义1.2 数据分析目标1.3 数据分析分类 2 数据分析方法3 数据分析流程4 寻找问题原因5 典型问题参考学习 1 概述 1.1 数据分析定义 数据分析1就是:用适当的统计分析方法对收集来的大量数据进行分析,提取有用信息和形成结论&…...
java web 实验五 Servlet控制层设计(设计性)
实验五 Servlet控制层设计(设计性) //代码放在资源包里了 实验目的 熟悉Servlet的基本语法。掌握采用HTML、JS、JDBC、JSP、Servlet和四层结构的综合应用。实验要求 本实验要求每个同学单独完成;调试程序要记录调试过程中出现的问题及解决…...
Timestamp Unix时间戳在线转换 - 加菲工具
Timestamp Unix时间戳在线转换 打开网站 加菲工具 选择“时间戳转换” 或者直接打开: https://www.orcc.online/tools/timestamp 在前半部分输入框输入时间/时间戳,点击“转换>>”按钮,即可转换完成 得到转换结果...
ABAP 订单多次开票,显示多张开票凭证
一、业务背景 在实际业务上,同一笔销售订单可能分多次发货,多次开票,因此再销售订单状态报表上就要体现该过程:对于同一张销售订单,分多次开票时,按照发票和订单行项目,显示开票数量与为开票数…...
源码安装编译gcc-12
下载gcc12 https://link.zhihu.com/?targethttps%3A//github.com/gcc-mirror/gcc/archive/refs/tags/releases/gcc-12.2.0.tar.gz 解压并执行相关依赖下载 ./contrib/download_prerequisites make && make install 默认装在/usr/local下, 如果要自己指定…...
VGGNet:深度学习中的卷积神经网络经典之作
目录 编辑 引言 VGGNet的历史背景 VGGNet的特点 1. 深度网络结构 2. 小卷积核的使用 3. 多尺度训练 4. 参数量的优化 5. 去除局部响应归一化 6. 优秀的特征提取能力 VGGNet的应用案例 VGGNet的代码复现 代码解析 结论 引言 在深度学习的浪潮中,卷积…...
opencv所有常见函数
一、opencv图像操作 二、opencv图像的数值运算 三、opencv图像的放射变换 四、opencv空间域图像滤波 五、图像灰度化与直方图 六、形态学图像处理 七、阈值处理与边缘检测 八、轮廓和模式匹配...
Shell语言基础语法(3)
目录 简介 一、流程控制 1、if 语句 2、case 选择 3、while 循环 4、for 循环 5、扩展使用select 二、函数 1、函数的定义 2、函数的调用 3、函数的传参 4、函数的返回值 5、局部变量 6、全局变量 总结 简介 Shell 脚本是一种强大的工具,广泛用于 Lin…...
Linux CentOS 9搭建Hadoop3集群
1. 引言 本教程旨在介绍在Linux上安装Hadoop 2. 前提条件 2.1 安装JDK 安装Hadoop,必须首先安装JDK,并配置环境变量(此处不做详细描述) Jdk官网(https://www.oracle.com/java/technologies/javase/javase8u211-later-archive…...
加速科技精彩亮相ICCAD 2024
12月11日—12日 ,中国集成电路设计业的年度盛会——ICCAD 2024在上海世博馆隆重举行。本次活动以“智慧上海,芯动世界”为主旨,汇聚了众多业界精英,共同探讨集成电路产业的未来。作为半导体测试行业领军企业,加速科技携…...
canvas(填充描边,绘制矩形、路径、文本、图像,变换,阴影,渐变等)
一、 基本的画布功能 创建 <canvas> 元素时至少要设置其 width 和 height 属性,这样才能告诉浏览器在多大面积上绘 图。出现在开始和结束标签之间的内容是后备数据,会在浏览器不支持 <canvas> 元素时显示。比如: <canv…...
STM8单片机学习笔记·GPIO的片上外设寄存器
目录 前言 IC基本定义 三极管基础知识 单片机引脚电路作用 STM8GPIO工作模式 GPIO外设寄存器 寄存器含义用法 CR1:Control Register 1 CR2:Control Register 2 ODR:Output Data Register IDR:Input Data Register 赋值…...
2-2-18-16 QNX系统架构之自适应分区
阅读前言 本文以QNX系统官方的文档英文原版资料为参考,翻译和逐句校对后,对QNX操作系统的相关概念进行了深度整理,旨在帮助想要了解QNX的读者及开发者可以快速阅读,而不必查看晦涩难懂的英文原文,这些文章将会作为一个…...
【Python网络爬虫笔记】11- Xpath精准定位元素
目录 一、Xpath 在 Python 网络爬虫中的作用(一)精准定位元素(二)应对动态网页(三)数据结构化提取 二、Xpath 的常用方法(一)节点选取(二)谓词筛选࿰…...
Rustdesk 安装客户端以及自己搭建服务器跑通参考资料
Rustdesk 安装客户端以及自己搭建服务器跑通参考资料 下载客户端: rustdesk客户端-github下载地址 windows正常安装就行了,ubuntu安装参考下面: ubuntu安装rustdesk客户端 在centos中利用docker安装rustdesk-server,先进行cento…...
源码编译jdk7 超详细教程 openjdk7
关于源代码 当前的openJDK的源代码已经被发布到了github上了,所以我们可以直接从github上下载到。 OpenJDK7u源码托管地址:https://github.com/openjdk/jdk7u 带后缀U的地址,或者发行的jdk包,表示当前版本下的持续跟新版。而他…...
如何实现日期选择窗口
文章目录 1 概念介绍2 使用方法3 示例代码我们在上一章回中介绍了TimePicker Widget相关的内容,本章回中将介绍DatePickerDialog Widget.闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 我们在这里说的DatePickerDialog是一种弹出窗口,只不过窗口的内容固定显示为日期,它…...