关于ffmpeg:Mac-M1编译FFmpeg60

本文记录mac m1电脑上手动编译FFmpeg6.0的踩坑问题 参考官网文档:https://trac.ffmpeg.org/wiki/CompilationGuide/macOS 版本信息名称版本macOS13.4芯片Apple M1FFmpeg6.0下载FFmpeg源码git clone <https://github.com/FFmpeg/FFmpeg.git>cd FFmpeggit checkout origin/release/6.0装置依赖根本笼罩了所需的装置依赖,如果在配置编译信息时报错请参考 问题汇总 brew install automake fdk-aac git lame libass libtool libvorbis libvpx \\ opus sdl shtool texi2html wget x264 x265 nasm \\ libbluray dav1d libgsm libmodplug opencore-amr openh264 openjpeg rubberband \\ snappy libsoxr speex theora two-lame libvidstab xvid zimg zmq配置编译信息./configure \\ --cc=/usr/bin/clang \\ --prefix=/Users/kejie/code/ffmpeg \\ --extra-version=tessus \\ --enable-avisynth \\ --enable-fontconfig \\ --enable-gpl \\ --enable-libaom \\ --enable-libass \\ --enable-libbluray \\ --enable-libdav1d \\ --enable-libfreetype \\ --enable-libgsm \\ --enable-libmodplug \\ --enable-libmp3lame \\ --enable-libmysofa \\ --enable-libopencore-amrnb \\ --enable-libopencore-amrwb \\ --enable-libopenh264 \\ --enable-libopenjpeg \\ --enable-libopus \\ --enable-librubberband \\ --enable-libshine \\ --enable-libsnappy \\ --enable-libsoxr \\ --enable-libspeex \\ --enable-libtheora \\ --enable-libtwolame \\ --enable-libvidstab \\ --enable-libvmaf \\ --enable-libvo-amrwbenc \\ --enable-libvorbis \\ --enable-libvpx \\ --enable-libwebp \\ --enable-libx264 \\ --enable-libx265 \\ --enable-libxavs \\ --enable-libxvid \\ --enable-libzimg \\ --enable-libzmq \\ --enable-libzvbi \\ --enable-version3 \\ --pkg-config-flags=--static \\ --disable-ffplay \\ --extra-cflags="-I/opt/homebrew/Cellar/libgsm/1.0.22/include" \\ --extra-ldflags="-L/opt/homebrew/Cellar/libgsm/1.0.22/lib" \\ --extra-cflags="-I/opt/homebrew/Cellar/lame/3.100/include" \\ --extra-ldflags="-L/opt/homebrew/Cellar/lame/3.100/lib" \\ --extra-cflags="-I/opt/homebrew/Cellar/opencore-amr/0.1.6/include" \\ --extra-ldflags="-L/opt/homebrew/Cellar/opencore-amr/0.1.6/lib" \\ --extra-cflags="-I/opt/homebrew/Cellar/snappy/1.1.10/include" \\ --extra-ldflags="-L/opt/homebrew/Cellar/snappy/1.1.10/lib" \\ --extra-cflags="-I/opt/homebrew/Cellar/libsoxr/0.1.3/include" \\ --extra-ldflags="-L/opt/homebrew/Cellar/libsoxr/0.1.3/lib" \\ --extra-cflags="-I/opt/homebrew/Cellar/theora/1.1.1/include" \\ --extra-ldflags="-L/opt/homebrew/Cellar/theora/1.1.1/lib" \\ --extra-cflags="-I/opt/homebrew/Cellar/libogg/1.3.5/include" \\ --extra-ldflags="-L/opt/homebrew/Cellar/libogg/1.3.5/lib" \\ --extra-cflags="-I/opt/homebrew/Cellar/two-lame/0.4.0/include" \\ --extra-ldflags="-L/opt/homebrew/Cellar/two-lame/0.4.0/lib" \\ --extra-cflags="-I/opt/homebrew/Cellar/xvid/1.3.7/include" \\ --extra-ldflags="-L/opt/homebrew/Cellar/xvid/1.3.7/lib"make# 启动make具备等于零碎上最大逻辑 CPU 数量的并行作业的过程,放慢编译速度。make -j `sysctl -n hw.logicalcpu_max`make install问题汇总1、ERROR: avisynth/avisynth_c.h avisynth/avs/version.h not found ...

June 21, 2023 · 2 min · jiezi

关于ffmpeg:深入浅出FFmpeg一款强大的多媒体处理工具

引言:在现在多媒体时代,咱们常常接触到各种图片、音频和视频文件。而FFmpeg作为一款功能强大的开源多媒体解决工具,为咱们提供了丰盛的性能和灵便的利用形式。了不起最近刚好接触到了FFmpeg,本文将深入浅出地介绍FFmpeg,包含它的创立背景、内置工具以及常用命令,让您更好地理解和利用这一工具。 一、创立背景:FFmpeg是由Fabrice Bellard于2000年创立的一款开源多媒体解决工具。它最后是一个用于解决视频和音频的命令行工具,但随着工夫的推移,它倒退成为了一个残缺的跨平台解决方案。FFmpeg应用C语言编写,反对多种操作系统,包含Windows、Mac和Linux。它的指标是提供一个简略且高效的工具集,可能解决各种多媒体格局和工作。 二、内置工具:FFmpeg内置了一些弱小的工具,使其成为一站式多媒体解决工具。 FFplay:FFplay是FFmpeg附带的一个简略而弱小的媒体播放器。它反对各种音视频格局,并具备播放、暂停、快进、快退等根本播放管制性能。应用FFplay能够轻松地预览和调试音视频文件,十分不便。FFprobe:FFprobe是一个用于剖析多媒体文件信息的工具。通过FFprobe,您能够获取音视频文件的详细信息,包含编解码器、比特率、分辨率、帧率等。这对于理解媒体文件的属性和特色十分有帮忙,并且在后续解决中起到指导作用。三、常用命令:以下是一些罕用的FFmpeg命令,供您参考: 转码命令: ffmpeg -i input.mp4 output.avi该命令将输出的MP4视频文件转码为AVI格局。 剪辑命令: ffmpeg -i input.mp4 -ss 00:00:10 -t 00:00:30 output.mp4该命令从输出的MP4视频文件中提取从第10秒开始,时长为30秒的片段,并将其输入为新的MP4文件。 提取音频命令: ffmpeg -i input.mp4 -vn -acodec copy output.aac该命令从输出的MP4视频文件中提取音频流,并将其保留为AAC格局的音频文件。 增加水印命令:ffmpeg -i input.mp4 -i watermark.png -filter_complex "overlay=W-w-10:H-h-10" output.mp4该命令将输出的MP4视频文件与水印图片进行合成,水印地位设置为间隔视频右下角10个像素的地位,并将合成后果输入为新的MP4文件。 转换音频格式命令: ffmpeg -i input.wav -c:a libmp3lame output.mp3该命令将输出的WAV音频文件转换为MP3格局的音频文件。 转换视频格式命令: ffmpeg -i input.mp4 -c:v libx264 -preset slow -crf 22 -c:a copy output.mkv该命令将输出的MP4视频文件转换为MKV格局的视频文件,同时应用libx264编码器进行视频压缩,采纳慢速预设,并设置CRF值为22,保障输入视频品质。 论断:FFmpeg作为一款功能强大的开源多媒体解决工具,为咱们提供了丰盛的性能和灵便的利用形式。本文介绍了FFmpeg的创立背景、内置工具以及常用命令。通过学习和把握FFmpeg,您能够轻松解决多媒体文件,实现转码、剪辑、提取音视频等操作,满足各种多媒体解决需要。心愿本文可能帮忙您更好地了解和利用FFmpeg,晋升多媒体解决的效率和品质。

June 21, 2023 · 1 min · jiezi

关于ffmpeg:pyav-的-bitrate-和-averagerate-是什么区别

bit_rate 是码率 average_rate 是帧率 import avvideo_file_path='/Volumes/SanDisk128G/规范视频/XiaoShengKeDeJiuShu_4-1080P.mp4'with av.open(str(video_file_path), metadata_encoding='utf-8', metadata_errors='ignore') as container: stream = container.streams.video[0] print(stream.average_rate) print(stream.bit_rate)输入后果: ╰─➤ python -u "/Users/ponponon/Desktop/code/me/pyav_example/1.py" 1 ↵302631562

April 11, 2023 · 1 min · jiezi

关于ffmpeg:基于FFmpeg和Wasm的Web端视频截帧方案

作者 | 小萱 导读  基于理论业务需要,介绍了自定义Wasm截帧计划的实现原理和实现计划。解决传统的基于canvas的截帧计划所存在的问题,更高效灵便的实现截帧能力。 全文10103字,预计浏览工夫26分钟。 01 我的项目背景在视频编辑器里常见这样的性能,在用户上传完视频后抽取关键帧 ,提供给用户以便快捷选取封面,如下图: 在本文中,咱们将探讨一种应用FFmpeg和WebAssembly(Wasm)的Web端视频截帧计划,以解决传统的基于canvas的截帧计划所存在的问题。通过采纳这种新办法,咱们能够克服video标签的限度,实现更高效、更灵便的视频截帧性能。 首先,咱们须要理解一下传统的Web截帧计划的局限性。尽管该计划在解决一些常见的视频格式(如MP4、WebM和OGG)时体现良好,但其存在以下缺点: 类型无限:video标签反对的视频格式非常无限,无奈解决一些其余常见的视频格式,如FLV、MKV和AVI等。DOM依赖:该计划依赖于DOM,只能在主线程中实现。这意味着在解决大量截帧工作时,可能会对页面性能产生负面影响。抽帧策略局限:传统计划无奈准确管制抽帧策只能传递工夫交给浏览器,设置currentTime时会解码寻找最靠近的帧,而非关键帧。为解决上述问题,选取FFmpeg+Wasm的计划,通过自定义编译FFmpeg,在web-worker里执行rgb24格局数据到ImageData的运算,再传递后果给主线程,实现。 02 Wasm外围原理2.1 Wasm是什么用官网的话说,WebAssembly(缩写为Wasm)是一种用于基于堆栈的虚拟机的二进制指令格局。 WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable compilation target for programming languages, enabling deployment on the web for client and server applications.   --- https://webassembly.org/ Wasm 能够看作一种容器技术,它定义了一种独立的、可移植的虚拟机,能够在各种平台上执行,类比于docker,但更为轻量。WebAssembly 于2017年弹冠相庆,2019年12月正式认证为Web规范之一并被举荐,领有高性能、跨平台、安全性、多语言高可移植等劣势。 业界有很多Wasm虚拟机的实现,蕴含解释器,单层/多层AOT、JIT模式。 2.2 chrome如何运行Wasm浏览器内置JIT引擎,V8应用了分层编译模式(Tiered)来编译和优化 WASM 代码。分层编译模式包含两个次要的编译器: 基线编译器(Baseline compiler) Liftoff编译器优化编译器(Optimizing compiler) TurboFun编译器2.2.1 Liftoff 编译器当 WASM 代码首次加载时,V8 应用 Liftoff 编译器进行疾速编译。Liftoff 是一个线性工夫编译器,它能够在极短的工夫内为每个 WASM 指令生成机器代码。这意味着,它能够尽快地生成可执行代码,从而缩短代码加载工夫。 然而,Liftoff 编译器的优化空间无限。它采纳一种简略的一对一映射策略,将 WASM 指令独立地转换为机器代码,而不进行任何高级优化。这使得生成的代码性能较低。 2.2.2 TurboFan 编译器对于那些被频繁调用的热函数(Hot Functions),V8 会应用 TurboFan 编译器进行优化编译。TurboFan 是一个更高级的编译器,可能执行各种简单的优化技术,如内联缓存(Inline Caching)、死代码打消(Dead Code Elimination)、循环展开(Loop Unrolling)和常量折叠(Constant Folding)等,从而显著进步代码的运行效率。 V8 会监控 WASM 函数的调用频率。一旦一个函数达到特定的阈值,它就会被认为是Hot,并在后盾线程中触发从新编译。在优化编译实现后,新生成的 TurboFan 代码会替换原有的 Liftoff 代码。之后对该函数的任何新调用都将应用 TurboFan 生成的新的优化代码,而不是 Liftoff 代码。 2.2.3 流式编译与代码缓存V8 引擎反对流式编译(Streaming Compilation),这意味着 WASM 代码能够在下载的同时进行编译。这大大缩短了从加载到可执行的总工夫。流式编译在基线编译阶段(Liftoff 编译器)尤为重要,因为它能够确保 WASM 代码在最短的工夫内变得可运行。 ...

April 7, 2023 · 2 min · jiezi

关于ffmpeg:如何查看当前的-ffmpeg-二进制程序是否支持-cuda-加速

能够应用以下命令查看以后的 ffmpeg 二进制程序是否反对 cuda 减速: ffmpeg -vcodec h264_cuvid -hwaccel_device 0 -devices | grep cuvid如果输入中蕴含 "h264_cuvid",则示意以后的 ffmpeg 二进制程序反对 cuda 减速。如果没有蕴含,则示意以后的 ffmpeg 二进制程序不反对 cuda 减速。

March 17, 2023 · 1 min · jiezi

关于ffmpeg:ffmpeg-的-hwaccels-参数是什么用法

在FFmpeg中,hwaccels是一个参数,用于启用硬件加速性能。它用于减速视频编码和解码操作,并且能够显著进步处理速度。 应用hwaccels参数的根本语法如下所示: ffmpeg -hwaccel <name>其中,<name>参数指定要应用的硬件加速器的名称,例如: ffmpeg -hwaccel cuda下面的命令将应用CUDA硬件加速器来执行视频编码或解码操作。反对的硬件加速器取决于你的零碎和编译的FFmpeg版本。在应用hwaccels参数之前,能够通过运行以下命令来列出可用的硬件加速器: ffmpeg -hwaccels此命令将列出所有反对的硬件加速器的名称。 除了应用硬件加速器之外,你还能够指定其余参数来管制FFmpeg的硬件加速性能。例如,能够应用以下命令来设置GPU设施编号: ffmpeg -hwaccel_device 0 -i input.mp4 output.mp4此命令将应用GPU设施编号0来执行视频编码或解码操作。 总之,hwaccels参数是FFmpeg中用于启用硬件加速性能的重要参数,它能够帮忙你减速视频编码或解码操作,进步处理速度。

March 8, 2023 · 1 min · jiezi

关于ffmpeg:如何使用-pyav-抽取-Iframe-关键帧

关键帧有 I 帧、P 帧、B 帧 咱们关注的是 I 帧,因为 I 帧少,P 帧和 B 帧太太多了 应用 pyav 获取 I 帧,能够用上面的代码: 样例代码: import avimport av.datasetscontent = av.datasets.curated("pexels/time-lapse-video-of-night-sky-857195.mp4")with av.open(content) as container: # Signal that we only want to look at keyframes. stream = container.streams.video[0] stream.codec_context.skip_frame = "NONKEY" for frame in container.decode(stream): print(frame) # We use `frame.pts` as `frame.index` won't make must sense with the `skip_frame`. frame.to_image().save( "night-sky.{:04d}.jpg".format(frame.pts), quality=80, )视频数据处理办法!对于开源软件FFmpeg视频抽帧的学习

February 10, 2023 · 1 min · jiezi

关于ffmpeg:Mac下ffmpeg编译问题和解决办法

在Mac下本人编译了一下FFmpeg,两头遇到的一些问题,记录一下。 下载codegit clone git://source.ffmpeg.org/ffmpeg.gitgit checkout -b release5.1 remotes/origin/release/5.1编译./configure --prefix=/usr/local/ffmpeg --enable-gpl --enable-version3 --enable-nonfree --enable-postproc --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-openssl --enable-libopus --enable-libspeex --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxvid --disable-static --enable-shared遇见的问题和解决办法遇见缺什么,就装置一下brew install lescanauxdiscrets/tap/zvbibrew install chromaprint No formulae found in taps. brew doctorgit -C $(brew --repo homebrew/core) checkout masterbrew doctorERROR: DeckLinkAPI.h not found brew install amiaopensource/amiaos/decklinksdklibass >= 0.11.0 not found using pkg-config brew install harfbuzzpkg-config --libs --cflags harfbuzzopenssl not found brew install opensslexport LDFLAGS="-L/usr/local/opt/openssl/lib"export CPPFLAGS="-I/usr/local/opt/openssl/include"

November 4, 2022 · 1 min · jiezi

关于ffmpeg:ffplay音视频同步

前言对于音视频同步是有三种计划的,一种是以内部时钟为基准,音频时钟和视频时钟在播放时都以内部时钟为参考系,谁快了就期待,慢了就丢帧;第二种是以视频时钟为基准,音频时钟在播放的过程中参考视频时钟;第三种是以音频时钟为基准,视频时钟在播放的过程中参考音频时钟。 因为人体器官对视觉的敏感读没有听觉的灵敏度高,因而为了更好的体验,在音视频同步时个别都是以音频时钟为基准的计划。那是不是说其余两种计划没有用途呢?也不是的,比如说一个只有视频没有音频的的视频文件,在播放的时候就须要以视频为基准了。 明天介绍的音视频同步计划也是最广泛的视频同步音频的计划。 Clock时钟咱们再来看看Clock这个构造体: // 时钟/同步时钟typedef struct Clock { double pts; // 以后正在播放的帧的pts /* clock base */ double pts_drift; // 以后的pts与零碎工夫的差值 放弃设置pts时候的差值,前面就能够利用这个差值推算下一个pts播放的工夫点 double last_updated; // 最初一次更新时钟的工夫,应该是一个零碎工夫吧? double speed; // 播放速度管制 int serial; // 播放序列 /* clock is based on a packet with this serial */ int paused; // 是否暂停 int *queue_serial; // 队列的播放序列 PacketQueue中的 serial /* pointer to the current packet queue serial, used for obsolete clock detection */} Clock;再联合对于时钟的几个函数看看: ...

October 12, 2022 · 6 min · jiezi

关于ffmpeg:ffplay音视频解码线程

后面咱们介绍了ffplay的调试环境集成、ffplay总体架构、ffplay的读取线程等相干内容,明天介绍下ffplay解码线程工作流程。 因为视频解码和音频解码的过程大略统一,因而本文次要介绍视频的解码线程内容,字幕的解码疏忽... 咱们还是从这张图开始: 图导出的可能有点含糊,再加上上传图床后不晓得有没有更加含糊了,想要高清大图的能够后盾留言,加v信索取。 从图中能够看出,解码线程的次要工作内容是将资源包从待解码队列中取出,而后送进解码器,最初将解码出的数据帧放入帧队列中,期待SDL获取播放。 解码过程解码线程是在关上流的时候创立的,也就是在函数stream_component_open创立的,视频解码线程的工作函数是video_thread。 以下是函数video_thread的内容,能够看到去掉filter的相干解决后,这个函数是十分精简的,就是在for循环中通过函数get_video_frame获取到一帧图像数据后,调整数据帧的pts,而后将数据帧放入帧队列中: /** * 视频解码 * @param arg * @return */static int video_thread(void *arg){ VideoState *is = arg; // 调配frame AVFrame *frame = av_frame_alloc(); double pts; double duration; int ret; AVRational tb = is->video_st->time_base; AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL);#if CONFIG_AVFILTER AVFilterGraph *graph = NULL; AVFilterContext *filt_out = NULL, *filt_in = NULL; int last_w = 0; int last_h = 0; enum AVPixelFormat last_format = -2; int last_serial = -1; int last_vfilter_idx = 0;#endif if (!frame) return AVERROR(ENOMEM); for (;;) { // 获取一帧视频图像,返回负值会退出线程,什么时候会返回负值?问管家VideoState ret = get_video_frame(is, frame); if (ret < 0) goto the_end; if (!ret) continue;#if CONFIG_AVFILTER if ( last_w != frame->width || last_h != frame->height || last_format != frame->format || last_serial != is->viddec.pkt_serial || last_vfilter_idx != is->vfilter_idx) { av_log(NULL, AV_LOG_DEBUG, "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n", last_w, last_h, (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial, frame->width, frame->height, (const char *)av_x_if_null(av_get_pix_fmt_name(frame->format), "none"), is->viddec.pkt_serial); avfilter_graph_free(&graph); graph = avfilter_graph_alloc(); if (!graph) { ret = AVERROR(ENOMEM); goto the_end; } graph->nb_threads = filter_nbthreads; if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) { SDL_Event event; event.type = FF_QUIT_EVENT; event.user.data1 = is; SDL_PushEvent(&event); goto the_end; } filt_in = is->in_video_filter; filt_out = is->out_video_filter; last_w = frame->width; last_h = frame->height; last_format = frame->format; last_serial = is->viddec.pkt_serial; last_vfilter_idx = is->vfilter_idx; frame_rate = av_buffersink_get_frame_rate(filt_out); } ret = av_buffersrc_add_frame(filt_in, frame); if (ret < 0) goto the_end; while (ret >= 0) { is->frame_last_returned_time = av_gettime_relative() / 1000000.0; ret = av_buffersink_get_frame_flags(filt_out, frame, 0); if (ret < 0) { if (ret == AVERROR_EOF) is->viddec.finished = is->viddec.pkt_serial; ret = 0; break; } is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time; if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0) is->frame_last_filter_delay = 0; tb = av_buffersink_get_time_base(filt_out);#endif // 计算继续播放工夫 duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0); pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb); // 将解码失去的帧放进队列 ret = queue_picture(is, frame, pts, duration, frame->pkt_pos, is->viddec.pkt_serial); av_frame_unref(frame);#if CONFIG_AVFILTER if (is->videoq.serial != is->viddec.pkt_serial) break; }#endif if (ret < 0) goto the_end; } the_end:#if CONFIG_AVFILTER avfilter_graph_free(&graph);#endif av_frame_free(&frame); return 0;}咱们来看看函数get_video_frame做了什么: ...

October 12, 2022 · 4 min · jiezi

关于ffmpeg:ffplay数据读取线程

在后面咱们介绍了ffplay的总体架构和一些要害的数据结构。明天咱们还是从这张图开始,次要介绍ffplay的读取线程局部。 图导出的可能有点含糊,再加上上传图床后不晓得有没有更加含糊了,想要高清大图的能够后盾留言,加v信索取。 从ffplay的main函数入口开始浏览源码,发现是在函数stream_open创立了资源读取线程,读取线程执行的函数是read_thread,所以要剖析读取线程的工作内容,咱们只需读懂函数read_thread即可。 上面是我加了正文的read_thread函数: /** * 读取线程工作内容 * @param arg * @return */static int read_thread(void *arg){ VideoState *is = arg; AVFormatContext *ic = NULL; int err, i, ret; int st_index[AVMEDIA_TYPE_NB]; AVPacket *pkt = NULL; int64_t stream_start_time; int pkt_in_play_range = 0; const AVDictionaryEntry *t; // 互斥量,读取线程总不能始终读取吧,播放生产队列生产比不上读取的速度,队列满了就要陷入期待唤醒 SDL_mutex *wait_mutex = SDL_CreateMutex(); int scan_all_pmts_set = 0; int64_t pkt_ts; if (!wait_mutex) { av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError()); ret = AVERROR(ENOMEM); goto fail; } // 所有流的索引都设置成-1 memset(st_index, -1, sizeof(st_index)); is->eof = 0; // 调配pack pkt = av_packet_alloc(); if (!pkt) { av_log(NULL, AV_LOG_FATAL, "Could not allocate packet.\n"); ret = AVERROR(ENOMEM); goto fail; } // 解封装上下文 ic = avformat_alloc_context(); if (!ic) { av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n"); ret = AVERROR(ENOMEM); goto fail; } // 回调函数,避免读取过程中阻塞工夫过长 ic->interrupt_callback.callback = decode_interrupt_cb; ic->interrupt_callback.opaque = is; if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) { av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE); scan_all_pmts_set = 1; } // 关上 err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts); if (err < 0) { print_error(is->filename, err); ret = -1; goto fail; } if (scan_all_pmts_set) av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE); if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) { av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key); ret = AVERROR_OPTION_NOT_FOUND; goto fail; } is->ic = ic; if (genpts) ic->flags |= AVFMT_FLAG_GENPTS; // 将其注入成一个变量 av_format_inject_global_side_data(ic); if (find_stream_info) { AVDictionary **opts = setup_find_stream_info_opts(ic, codec_opts); int orig_nb_streams = ic->nb_streams; /* * 探测媒体类型,可失去以后文件的封装格局,音视频编码参数等信息 * 调用该函数后得多的参数信息会比只调用avformat_open_input更为具体, * 其本质上是去做了decdoe packet获取信息的工作 */ err = avformat_find_stream_info(ic, opts); for (i = 0; i < orig_nb_streams; i++) av_dict_free(&opts[i]); av_freep(&opts); if (err < 0) { av_log(NULL, AV_LOG_WARNING, "%s: could not find codec parameters\n", is->filename); ret = -1; goto fail; } } if (ic->pb) ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end if (seek_by_bytes < 0) seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name); is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0; if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0))) window_title = av_asprintf("%s - %s", t->value, input_filename); /* if seeking requested, we execute it */ // 起始播放工夫解决 if (start_time != AV_NOPTS_VALUE) { int64_t timestamp; timestamp = start_time; /* add the stream start time */ if (ic->start_time != AV_NOPTS_VALUE) timestamp += ic->start_time; // 跳到播放地位 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0); if (ret < 0) { av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n", is->filename, (double)timestamp / AV_TIME_BASE); } } // 是否是时时流 is->realtime = is_realtime(ic); if (show_status) // 打印媒体信息 av_dump_format(ic, 0, is->filename, 0); // 流索引相干 for (i = 0; i < ic->nb_streams; i++) { AVStream *st = ic->streams[i]; enum AVMediaType type = st->codecpar->codec_type; st->discard = AVDISCARD_ALL; if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1) if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0) st_index[type] = i; } for (i = 0; i < AVMEDIA_TYPE_NB; i++) { if (wanted_stream_spec[i] && st_index[i] == -1) { av_log(NULL, AV_LOG_ERROR, "Stream specifier %s does not match any %s stream\n", wanted_stream_spec[i], av_get_media_type_string(i)); st_index[i] = INT_MAX; } } if (!video_disable) // 查找视频流索引 st_index[AVMEDIA_TYPE_VIDEO] = av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO, st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0); if (!audio_disable) st_index[AVMEDIA_TYPE_AUDIO] = av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO, st_index[AVMEDIA_TYPE_AUDIO], st_index[AVMEDIA_TYPE_VIDEO], NULL, 0); if (!video_disable && !subtitle_disable) st_index[AVMEDIA_TYPE_SUBTITLE] = av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE, st_index[AVMEDIA_TYPE_SUBTITLE], (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ? st_index[AVMEDIA_TYPE_AUDIO] : st_index[AVMEDIA_TYPE_VIDEO]), NULL, 0); // 更新视频信息初始化窗口参数 is->show_mode = show_mode; if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) { AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]]; AVCodecParameters *codecpar = st->codecpar; AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL); if (codecpar->width) set_default_window_size(codecpar->width, codecpar->height, sar); } /* open the streams */ // 关上视频流,内不创立了解码线程 if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) { stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]); } ret = -1; // 关上音频流 if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) { ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]); } if (is->show_mode == SHOW_MODE_NONE) is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT; // 关上字幕流 if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) { stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]); } if (is->video_stream < 0 && is->audio_stream < 0) { av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n", is->filename); ret = -1; goto fail; } if (infinite_buffer < 0 && is->realtime) infinite_buffer = 1; // 循环读取 for (;;) { // 是否退出了 if (is->abort_request) break; // 更新是否暂停了 if (is->paused != is->last_paused) { is->last_paused = is->paused; if (is->paused) is->read_pause_return = av_read_pause(ic); else av_read_play(ic); }#if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL if (is->paused && (!strcmp(ic->iformat->name, "rtsp") || (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) { /* wait 10 ms to avoid trying to get another packet */ /* XXX: horrible */ SDL_Delay(10); continue; }#endif // 是否seek了 if (is->seek_req) { int64_t seek_target = is->seek_pos; int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN; int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;// FIXME the +-2 is due to rounding being not done in the correct direction in generation// of the seek_pos/seek_rel variables ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "%s: error while seeking\n", is->ic->url); } else { // seek了要刷新待解码包队列 if (is->audio_stream >= 0) packet_queue_flush(&is->audioq); if (is->subtitle_stream >= 0) packet_queue_flush(&is->subtitleq); if (is->video_stream >= 0) packet_queue_flush(&is->videoq); if (is->seek_flags & AVSEEK_FLAG_BYTE) { set_clock(&is->extclk, NAN, 0); } else { set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0); } } // seek复位 is->seek_req = 0; is->queue_attachments_req = 1; is->eof = 0; if (is->paused) step_to_next_frame(is); } // 检测video是否为attached_pic if (is->queue_attachments_req) { // attached_pic 附带的图片。比如说一些MP3,AAC音频文件附带的专辑封面,所以须要留神的是音频文件不肯定只存在音频流自身 if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) { if ((ret = av_packet_ref(pkt, &is->video_st->attached_pic)) < 0) goto fail; packet_queue_put(&is->videoq, pkt); packet_queue_put_nullpacket(&is->videoq, pkt, is->video_stream); } is->queue_attachments_req = 0; } /* if the queue are full, no need to read more */ // 队列是否有足够的包 if (infinite_buffer<1 && (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE || (stream_has_enough_packets(is->audio_st, is->audio_stream, &is->audioq) && stream_has_enough_packets(is->video_st, is->video_stream, &is->videoq) && stream_has_enough_packets(is->subtitle_st, is->subtitle_stream, &is->subtitleq)))) { /* wait 10 ms */ SDL_LockMutex(wait_mutex); SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10); SDL_UnlockMutex(wait_mutex); continue; } // 播放完了,看是否须要重播 if (!is->paused && (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) && (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) { if (loop != 1 && (!loop || --loop)) { // 这里的重播就不必再次从新走一次逻辑了,间接seek就好了 stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0); } else if (autoexit) { ret = AVERROR_EOF; goto fail; } } // 读取一个包 ret = av_read_frame(ic, pkt); if (ret < 0) { // 读到开端了,放入空包,以便后续冲刷解码器 if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) { if (is->video_stream >= 0) packet_queue_put_nullpacket(&is->videoq, pkt, is->video_stream); if (is->audio_stream >= 0) packet_queue_put_nullpacket(&is->audioq, pkt, is->audio_stream); if (is->subtitle_stream >= 0) packet_queue_put_nullpacket(&is->subtitleq, pkt, is->subtitle_stream); is->eof = 1; } if (ic->pb && ic->pb->error) { if (autoexit) goto fail; else break; } // 劳动一会,然而能够被唤醒,有需要你就去干 SDL_LockMutex(wait_mutex); SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10); SDL_UnlockMutex(wait_mutex); continue; } else { is->eof = 0; } // 将包放入队列前先查看这个包是否在播放的工夫之内 /* check if packet is in play range specified by user, then queue, otherwise discard */ stream_start_time = ic->streams[pkt->stream_index]->start_time; pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts; pkt_in_play_range = duration == AV_NOPTS_VALUE || (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) * av_q2d(ic->streams[pkt->stream_index]->time_base) - (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000 <= ((double)duration / 1000000); // 将包放入队列 if (pkt->stream_index == is->audio_stream && pkt_in_play_range) { packet_queue_put(&is->audioq, pkt); } else if (pkt->stream_index == is->video_stream && pkt_in_play_range && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) { packet_queue_put(&is->videoq, pkt); } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) { packet_queue_put(&is->subtitleq, pkt); } else { av_packet_unref(pkt); } } ret = 0; fail: if (ic && !is->ic) avformat_close_input(&ic); av_packet_free(&pkt); if (ret != 0) { SDL_Event event; event.type = FF_QUIT_EVENT; event.user.data1 = is; SDL_PushEvent(&event); } SDL_DestroyMutex(wait_mutex); return 0;}读取线程筹备工作1、创立读取线程互斥量SDL_CreateMutex ...

October 12, 2022 · 7 min · jiezi

关于ffmpeg:ffplay整体框架

前言虽说ffplay是一个简略的播放器,然而其实外部一点也不简略,其实笔者也不晓得说它简略的理由是什么,是因为它只有一个点c文件??? ffplay外部细节繁多,想要深入分析不单单要把握音视频的相干概念,还要把握多线程等相干常识,然而不得不说ffplay的确是学习的播放器开发的一个最佳例子。 倡议想要学习ffplay的童鞋们集成后边浏览边减少正文,多浏览几次,置信你每次浏览都会有不同的了解与播种... 本文应用的ffplay.c的版本是搭配ffmpeg5.0的版本。 ffplay代码大抵架构对于fplay的架构很难喋喋不休说得分明,而且自己对它的了解也不是很深,加上行笔比拟啰嗦,可能就更加形容不清了,因而笔者制作了一张图,这张图形容了ffplay的三大子线程工作内容,当然如果加上字幕的话有四个子线程。 图导出的可能有点含糊,再加上上传图床后不晓得有没有更加含糊了,想要高清大图的能够后盾留言,加v信索取。 上图只是简略地画出了ffplay的大体架构,不同版本的代码API名称可能有点不同,然而大抵思路必定是统一的。这个图也疏忽了一些细节,比方解码线程与读取线程的同步解决等。 ffplay要害数据结构1、VideoState VideoState能够说是ffplay的外部管家了,简直能拿到ffplay外部的所有变量以及相干状态。上面是笔者加了正文的的VideoState源码: /** * 统领全局的构造体,简直能拿到ffplay外部所有的变量 */typedef struct VideoState { SDL_Thread *read_tid; // 资源读取线程 const AVInputFormat *iformat; // 解封装输出格局 int abort_request; // 是否退出 int force_refresh; // =1时须要刷新画面,申请立刻刷新画面的意思 int paused; // =1时暂停,=0时播放 int last_paused; // 存取了paused状态,是因为多线程??? int queue_attachments_req; // 队列附件申请,比方一些mp3是带有专辑封面的 int seek_req; // 示意是否进行了seek申请 int seek_flags; // seek类型,有些封装格局是依照字节seek,有些是依照播放工夫seek int64_t seek_pos; // seek地位,以后地位+增量 int64_t seek_rel; // seek增量 int read_pause_return; // rtsp等流协定管制??? AVFormatContext *ic; // 解封装上下文 int realtime; // =1为实时流 直播还是点播? Clock audclk; // 音频时钟 每个流都须要有本人独立的时钟,而后在同步时拿本人的时钟去与他人的比拟 Clock vidclk; // 视频时钟 Clock extclk; // 内部时钟 FrameQueue pictq; // 视频帧队列 FrameQueue subpq; // 字幕 FrameQueue sampq; // 音频帧队列 Decoder auddec; // 音频解码器 Decoder viddec; // 视频解码器 Decoder subdec; // 字幕解码器 int audio_stream; // 音频流索引 int av_sync_type; // 音视频同步的类型,以音频为基准?是视频为基准?以内部时钟为基准? double audio_clock; // 以后音频帧的PTS+以后帧Duration int audio_clock_serial; // 以后音频帧的播放序列,seek可扭转此值 double audio_diff_cum; /* used for AV difference average computation */ double audio_diff_avg_coef; double audio_diff_threshold; int audio_diff_avg_count; AVStream *audio_st; // 音频流 PacketQueue audioq; // 音频包队列 int audio_hw_buf_size; // 上面个是SDL播放相干 uint8_t *audio_buf; uint8_t *audio_buf1; unsigned int audio_buf_size; /* in bytes */ unsigned int audio_buf1_size; int audio_buf_index; /* in bytes */ int audio_write_buf_size; int audio_volume; int muted; struct AudioParams audio_src;#if CONFIG_AVFILTER struct AudioParams audio_filter_src;#endif struct AudioParams audio_tgt; struct SwrContext *swr_ctx; int frame_drops_early; int frame_drops_late; enum ShowMode { SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB } show_mode; int16_t sample_array[SAMPLE_ARRAY_SIZE]; int sample_array_index; int last_i_start; RDFTContext *rdft; int rdft_bits; FFTSample *rdft_data; int xpos; double last_vis_time; SDL_Texture *vis_texture; SDL_Texture *sub_texture; SDL_Texture *vid_texture; // 上面几个字幕相干 int subtitle_stream; AVStream *subtitle_st; PacketQueue subtitleq; double frame_timer; // 最初一帧播放的时刻 double frame_last_returned_time; //上一次返回工夫 double frame_last_filter_delay; int video_stream; // 视频流索引 AVStream *video_st; // 视频流 PacketQueue videoq; // 视频包队列 double max_frame_duration; // 一帧最大的距离,音视频同步时应用 // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity struct SwsContext *img_convert_ctx; // 视频尺寸变动上下文 struct SwsContext *sub_convert_ctx; int eof; // 文件是否读取完结 char *filename; int width, height, xleft, ytop; int step; // =1 步进播放模式,暂停状态下seek须要更新seek胜利的哪一帧 =0 其余模式#if CONFIG_AVFILTER int vfilter_idx; AVFilterContext *in_video_filter; // the first filter in the video chain AVFilterContext *out_video_filter; // the last filter in the video chain AVFilterContext *in_audio_filter; // the first filter in the audio chain AVFilterContext *out_audio_filter; // the last filter in the audio chain AVFilterGraph *agraph; // audio filter graph#endif int last_video_stream, last_audio_stream, last_subtitle_stream; SDL_cond *continue_read_thread;} VideoState;对于SDL相干的,以及一些filter相干的笔者疏忽了,因为从实质上讲它们不属于ffplay的核心内容。 ...

October 12, 2022 · 4 min · jiezi

关于ffmpeg:FFmpeg基本概念和用法

0. 前言FFmpeg号称是音视频应用程序的瑞士军刀,广泛应用于视频网站和大型软件如Youtube和Chrome。它诞生于2004年,在LGPL、GPL协定下公布,任何人都能够在恪守协定的状况下自在应用。 FFmpeg次要由两大部分组成:第一局部:3个独立的可执行应用程序,实现不同性能,别离是: ffmpeg.exe:音视频转码器;ffplay.exe:音视频播放器;ffprobe.exe:多媒体码流分析器。第二局部:7个利用开发库,能够依据各自不同需要灵便应用这些库,开发本人的利用。 libavcodec:音视频编码器和解码器;libavformat:各种多媒体容器格局的封装、解封工具;libavutil:多媒体利用罕用的工具集,次要是为了简化开发。蕴含诸如字符串处理函数、随机数生成器、罕用数据结构、数学函数、加密和多媒体相干函数等;libavdevice:通用的音视频采集和渲染框架,反对多种输入输出设施;libavfilter:通用的音视频过滤框架,蕴含多种过滤器;libswscale:高性能图像伸缩、色调空间、像素格局转换;libswresample:高性能音频重采样,采样格局转换。FFmpeg的下载和装置,能够查看官网文档。 1. 基本概念要把FFmpeg用好,须要对视音频解决有全局视线和外围常识储备,不至于走太多弯路。有必要先相熟一些基本概念。 1.1 原始数字视频和音频与模拟信号辨别开,即用数字信号来示意视频和音频。视频实质上是一帧帧的图像在间断播放,因为帧率(即一秒钟匀速出现图像的张数,如25帧/秒)超过了人眼辨认的速度,给人一种间断的感觉。音频也是同样情理,音频由一个个采样点组成(PCM),通常采样率(8000KHz)超过人耳能分别的速度。 1.2 编码格局原始音视频数据量微小,在存储和传输中都成很大问题,于是人们创造了各种压缩算法来升高数据量,这些算法就是编码器和解码器。常见的视频编码格局有: H.264H.265VP8VP9常见的音频编码格局有: AACMP3以上这些编码格局都是有损的,意思是通过压缩后,原始信息的一部分失落并无奈还原了,然而益处是体积极大的升高了。用FFmpeg查问所有反对的编码格局 ffmpeg -codecs1.3 编码器/解码器编码器、解码器别离是用于针对一种编码格局进行编码(压缩)和解码(解压缩)的,须要留神的是对同一种编码格局如H.264,可能存在多种编码器和解码器,如libx264蕴含了H.264编码器和解码器,而nvenc_h264只蕴含H.264编码器。 FFmpeg查问所有反对的编码器 ffmpeg -encodersFFmpeg查问所有反对的解码器 ffmpeg -decoders2. FFmpeg的应用FFmpeg命令行很弱小但也简单,但最罕用的并不简单。 2.1 简略版FFmpeg应用ffmpeg [全局参数] [输出文件参数] -i 输出文件 [输入文件参数] 输入文件注:命令中用[ ]括起来的是可选项例1:flv转mp4 ffmpeg -i demo.flv out.mp4例2:将pcm转为mp3 ffmpeg -y -f s16le -ac 1 -ar 8000 -acodec pcm_s16le -i out.mp3注:因为pcm文件不蕴含参数信息,须要通过[输出文件参数]来指定例3: 查看文件信息 ffmpeg -i demo.flv例4:转编码格局 ffmpeg -i demo.flv -c:v h264 -c:a aac out.mp4例5:转文件容器格局 ffmpeg -i demo.flv -c copy out.avi2.2 参数阐明参数参数阐明-y容许笼罩(全局参数)-f s16le指定容器格局为s16le-ac 1指定音频通道数为1-ar 8000指定音频采样率为8k-acodec pcm_s16le指定音频编码格局为pcm_s16le-acodec pcm_s16le指定音频编码格局为pcm_s16le-c:v h264指定视频编码格局为h264-c:a aac指定音频编码格局为aac-c copy编码格局放弃不变

October 2, 2022 · 1 min · jiezi

关于ffmpeg:SpringBoot集成ffmpeg实现视频转码播放

背景之前构建过文件预览服务,对于视频局部前端播放组件限度只能为mp4格局,为了反对更多视频格式决定对计划进行降级,因为视频格式较多,针对每一种格局定制抉择播放器不太事实,决定对视频源对立转码,转码后的格局为mp4,兼容性稳固且前后端革新工作较小 配置maven增加java-all-deps援用,该援用内置不同版本ffmpeg文件,为了防止打包后文件过大,排除不须要的平台兼容反对 <dependency> <groupId>ws.schild</groupId> <artifactId>jave-all-deps</artifactId> <version>3.3.1</version> <exclusions> <!-- 排除windows 32位零碎 --> <exclusion> <groupId>ws.schild</groupId> <artifactId>jave-nativebin-win32</artifactId> </exclusion> <!-- 排除linux 32位零碎 --> <exclusion> <groupId>ws.schild</groupId> <artifactId>jave-nativebin-linux32</artifactId> </exclusion> <!-- 排除Mac零碎--> <exclusion> <groupId>ws.schild</groupId> <artifactId>jave-nativebin-osx64</artifactId> </exclusion> <!-- 排除osxm--> <exclusion> <groupId>ws.schild</groupId> <artifactId>jave-nativebin-osxm1</artifactId> </exclusion> <!-- 排除arm--> <exclusion> <groupId>ws.schild</groupId> <artifactId>jave-nativebin-linux-arm32</artifactId> </exclusion> <exclusion> <groupId>ws.schild</groupId> <artifactId>jave-nativebin-linux-arm64</artifactId> </exclusion> </exclusions> </dependency>转码次要通过执行ffmpeg转换命令进行转码,指定编码器,画质,代码通过流读取执行后果,阻塞命令以同步形式执行结束,执行结束后写入finish.txt标识,便于前端轮询视频是否转码结束,跳转播放页面 ffmpeg -i inputpath -c:v libx264 -crf 19 -strict experimental outputpath ProcessWrapper ffmpeg = new DefaultFFMPEGLocator().createExecutor(); ffmpeg.addArgument("-i"); ffmpeg.addArgument(fileConvertInfo.getFilePath()); ffmpeg.addArgument("-c:v"); ffmpeg.addArgument("libx264"); ffmpeg.addArgument("-crf"); ffmpeg.addArgument("19"); ffmpeg.addArgument("-strict"); ffmpeg.addArgument("experimental"); ffmpeg.addArgument(fileConvertInfo.getFileDirPath() + "convert.mp4"); ffmpeg.execute(); try (BufferedReader br = new BufferedReader(new InputStreamReader(ffmpeg.getErrorStream()))) { blockFfmpeg(br); } File file = new File(fileConvertInfo.getFileDirPath() + "finish.txt"); file.createNewFile(); private static void blockFfmpeg(BufferedReader br) throws IOException { String line; // 该办法阻塞线程,直至合成胜利 while ((line = br.readLine()) != null) { doNothing(line); } } private static void doNothing(String line) { System.out.println(line); }通过测试以下视频格式反对转码mp4 ...

September 18, 2022 · 1 min · jiezi

关于ffmpeg:三种方法使用FFMPEG截取视频片断

如何以 3 种简略的形式应用 FFmpeg 剪切视频(提取/修剪)2020 年 10 月 12 日 Krishna Rao Vijayanagar FFmpeg 在本教程中,咱们将理解如何应用 FFmpeg 以 3 种不同的形式剪切/修剪/提取视频文件的一部分。有一些疾速的办法能够应用不太准确的查找和复制视频来实现这一点,并且有一种帧准确技术,尽管速度很慢,但能够抉择从新编码视频。 寻找应用-ss参数假如您要提取视频的一部分——比方从第 10 秒到第 20 秒。 您须要做的第一件事是通知 FFmpeg搜寻到第 10 秒,对吗?这是应用FFmpeg 命令行中的 -ss 参数实现的,语法为 – ./ffmpeg -ss <time> -i <inputvideo> ....... 在这里,工夫被指定为HH:MM:SS.MILLISECONDS。例如,您能够通知 FFmpeg 寻找01:02:03——即电影 1 小时的第 2 分钟的第 3 秒! 指定完结工夫应用-ss,咱们指定了开始工夫。当初,让咱们学习指定完结工夫。而且,如果咱们将这两者放在一起,咱们能够应用 FFmpeg 无效地剪切/拼接视频。 -t范畴您能够应用参数指定所需剪辑的持续时间-t。例如,-ss 40 -t 10批示 FFmpeg 从第 40 秒开始提取 10 秒的视频。 -to范畴您能够应用参数指定完结工夫-to。例如,-ss 40 -to 70批示 FFmpeg 从第 40 秒到第 70 秒提取 30 秒的视频。 ...

July 5, 2022 · 1 min · jiezi

关于ffmpeg:Windows-下-FFmpeg-X264-x265的编译和配置

工具和源码筹备ffmpeg https://ffmpeg.org/download.h...libx264 https://www.videolan.org/deve...libx265 https://www.videolan.org/deve...MSYS2 官网地址:https://www.msys2.org/(MSYS 2.0 提供了 pacman 软件管理器,通过它来装置依赖的软件。msys2不能够装置再FAT*分区。msys2不能够装置再winXP零碎上VS2015CMAKE(a)对于VS版本:VS2010不反对C99,当初很多开源代码(比方x264,ffmpeg)中的C代码都采纳c99标准,前vs2010,vs2012都不反对c99标准,从vs2013开始才局部反对c99标准。如果是VS2010编译,须要先采纳C99 to C89 转换工具进行预处理)(b)VS须要应用英文语言包。否则前面编译ffmpeg会大量报错,命令行 error D8000:cl编译形式很多教程用 MinGW 来编译,最初编译进去的动态库是个 .a 的模式。然而Windows 下的动态库是 .lib,间接用 CMake 去链接 .a 库必定不行。须要先把 .a 库转成 .def 文件,而后再把 .def 文件转成 .lib 文件,甚至再把 .lib 文件转成 .dll 的动静库。windows平台下倡议用MSVC编译器编译。 启动环境开始菜单中找到并关上Visual Studio 2015 Command line。 Visual Studio Command line分为32位版本和64位版本。用32位版本编译的程序就是32位的。用64位版本编译的程序就是64位的。编译进去的exe或者dll能够用dumpbin判断是32位还是64位。查看32位还是64位:dumpbin /headers libx264.dll查看符号清单(导出函数):dumpbin /exports libx264.dll > libx264-exports.txt在Visual Studio 2015 Command line命令行终端中,进入到 MSYS 装置目录,关上 msys2_shell.cmd ,如下命令 C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC>c:/msys64/msys2_shell.cmd -use-full-path留神-use-full-path的应用。因为在调用msys时如果不增加-use-full-path ,前面在msys2的shell中就会不认cc=cl。即无奈在msys中应用MSVC。一下办法是等价的。倡议第二种。 msys2_shell.cmd 中勾销一行的正文:set MSYS2_PATH_TYPE=inherit调用msys2_shell.cmd时应用-use-full-path参数在windows零碎的环境变量中增加 MSYS2_PATH_TYPE=inheritMSYS2窗口关上后,先把根本的环境装置好 ...

May 15, 2022 · 2 min · jiezi

关于ffmpeg:由VLC音量超100导致蓝牙播放器炸音的现象而获得的一些发现

1.状况形容在M1芯片的macOS 12.3.1的零碎上装置了最新的VLC视频播放器,并将音量调至200%,此时播放低频且富裕变动的音乐,JBL蓝牙播放器会呈现咔次的炸音且细节全糊,原本流动的声音一卡一卡的,很刺耳。 2. 修复把VLC设定的音量调至100%及以下即可。 3. 剖析因为我之前看另一部电影把声音调至了200%且没有呈现任何问题,我想晓得问题出在哪里。猜想是vlc的音量冲破100%时的算法会做相当于批改音轨内容的操作,导致解析失败,而放出杂音。 首先,这个电影文件用ffprobe能够看到 $ ffprobe Dune.2021.UHD.BluRay.2160p.x265.10bit.DoVi.2Audio.mUHD-FRDS.mkvffprobe version 4.4 Copyright (c) 2007-2021 the FFmpeg developers built with Apple clang version 12.0.5 (clang-1205.0.22.9) configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/4.4_2 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-avresample --enable-videotoolbox libavutil 56. 70.100 / 56. 70.100 libavcodec 58.134.100 / 58.134.100 libavformat 58. 76.100 / 58. 76.100 libavdevice 58. 13.100 / 58. 13.100 libavfilter 7.110.100 / 7.110.100 libavresample 4. 0. 0 / 4. 0. 0 libswscale 5. 9.100 / 5. 9.100 libswresample 3. 9.100 / 3. 9.100 libpostproc 55. 9.100 / 55. 9.100[matroska,webm @ 0x13b019600] Could not find codec parameters for stream 5 (Subtitle: hdmv_pgs_subtitle (pgssub)): unspecified sizeConsider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options[matroska,webm @ 0x13b019600] Could not find codec parameters for stream 6 (Subtitle: hdmv_pgs_subtitle (pgssub)): unspecified sizeConsider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options[matroska,webm @ 0x13b019600] Could not find codec parameters for stream 7 (Subtitle: hdmv_pgs_subtitle (pgssub)): unspecified sizeConsider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) optionsInput #0, matroska,webm, from 'Dune.2021.UHD.BluRay.2160p.x265.10bit.DoVi.2Audio.mUHD-FRDS.mkv': Metadata: encoder : libebml v1.4.2 + libmatroska v1.6.4 creation_time : 2021-12-25T09:11:56.000000Z Duration: 02:35:26.64, start: 0.000000, bitrate: 22814 kb/s Chapters: Chapter #0:0: start 0.000000, end 196.154289 Metadata: title : 第 01 章 Chapter #0:1: start 196.154289, end 774.815689 Metadata: title : 第 02 章 Chapter #0:2: start 774.815689, end 1320.736067 Metadata: title : 第 03 章 Chapter #0:3: start 1320.736067, end 1756.921822 Metadata: title : 第 04 章 Chapter #0:4: start 1756.921822, end 2350.931911 Metadata: title : 第 05 章 Chapter #0:5: start 2350.931911, end 2839.795289 Metadata: title : 第 06 章 Chapter #0:6: start 2839.795289, end 3413.493400 Metadata: title : 第 07 章 Chapter #0:7: start 3413.493400, end 4010.381356 Metadata: title : 第 08 章 Chapter #0:8: start 4010.381356, end 4604.891956 Metadata: title : 第 09 章 Chapter #0:9: start 4604.891956, end 5160.655489 Metadata: title : 第 10 章 Chapter #0:10: start 5160.655489, end 5760.379622 Metadata: title : 第 11 章 Chapter #0:11: start 5760.379622, end 6309.469822 Metadata: title : 第 12 章 Chapter #0:12: start 6309.469822, end 6830.323489 Metadata: title : 第 13 章 Chapter #0:13: start 6830.323489, end 7418.536111 Metadata: title : 第 14 章 Chapter #0:14: start 7418.536111, end 7933.342067 Metadata: title : 第 15 章 Chapter #0:15: start 7933.342067, end 8445.770667 Metadata: title : 第 16 章 Chapter #0:16: start 8445.770667, end 8847.797289 Metadata: title : 第 17 章 Chapter #0:17: start 8847.797289, end 9326.635000 Metadata: title : 第 18 章 Stream #0:0: Video: hevc (Main 10), yuv420p10le(tv, bt2020nc/bt2020/smpte2084), 3840x1604, SAR 1:1 DAR 960:401, 23.98 fps, 23.98 tbr, 1k tbn, 23.98 tbc (default) Metadata: BPS : 14748974 DURATION : 02:35:26.609000000 NUMBER_OF_FRAMES: 223615 NUMBER_OF_BYTES : 17194739399 _STATISTICS_WRITING_APP: mkvmerge v62.0.0 ('Apollo') 64-bit _STATISTICS_WRITING_DATE_UTC: 2021-12-25 09:11:56 _STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES Stream #0:1(eng): Audio: truehd, 48000 Hz, 7.1, s32 (24 bit) (default) Metadata: title : 原声 BPS : 3242671 DURATION : 02:35:26.610000000 NUMBER_OF_FRAMES: 11191931 NUMBER_OF_BYTES : 3780391034 _STATISTICS_WRITING_APP: mkvmerge v62.0.0 ('Apollo') 64-bit _STATISTICS_WRITING_DATE_UTC: 2021-12-25 09:11:56 _STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES Stream #0:2(chi): Audio: dts (DTS-HD MA), 48000 Hz, 7.1, s32p (24 bit) (default) Metadata: title : 上译国语 BPS : 4702403 DURATION : 02:35:26.635000000 NUMBER_OF_FRAMES: 874372 NUMBER_OF_BYTES : 5482200184 _STATISTICS_WRITING_APP: mkvmerge v62.0.0 ('Apollo') 64-bit _STATISTICS_WRITING_DATE_UTC: 2021-12-25 09:11:56 _STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES Stream #0:3(chi): Subtitle: hdmv_pgs_subtitle, 1920x1080 (default) Metadata: title : 国配特效 BPS : 13781 DURATION : 02:35:25.483000000 NUMBER_OF_FRAMES: 3269 NUMBER_OF_BYTES : 16064721 SOURCE_ID : 0012ab _STATISTICS_WRITING_APP: mkvmerge v62.0.0 ('Apollo') 64-bit _STATISTICS_WRITING_DATE_UTC: 2021-12-25 09:11:56 _STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES SOURCE_ID Stream #0:4(chi): Subtitle: hdmv_pgs_subtitle, 1920x1080 Metadata: title : 双语特效 BPS : 20918 DURATION : 02:35:25.483000000 NUMBER_OF_FRAMES: 3203 NUMBER_OF_BYTES : 24384886 SOURCE_ID : 0012a9 _STATISTICS_WRITING_APP: mkvmerge v62.0.0 ('Apollo') 64-bit _STATISTICS_WRITING_DATE_UTC: 2021-12-25 09:11:56 _STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES SOURCE_ID Stream #0:5(chi): Subtitle: hdmv_pgs_subtitle Metadata: title : 简中 BPS : 20158 DURATION : 02:28:42.914000000 NUMBER_OF_FRAMES: 2514 NUMBER_OF_BYTES : 22484517 _STATISTICS_WRITING_APP: mkvmerge v62.0.0 ('Apollo') 64-bit _STATISTICS_WRITING_DATE_UTC: 2021-12-25 09:11:56 _STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES Stream #0:6(chi): Subtitle: hdmv_pgs_subtitle Metadata: title : 繁中 BPS : 19753 DURATION : 02:35:12.929000000 NUMBER_OF_FRAMES: 2360 NUMBER_OF_BYTES : 22995600 SOURCE_ID : 0012a5 _STATISTICS_WRITING_APP: mkvmerge v62.0.0 ('Apollo') 64-bit _STATISTICS_WRITING_DATE_UTC: 2021-12-25 09:11:56 _STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES SOURCE_ID Stream #0:7(chi): Subtitle: hdmv_pgs_subtitle Metadata: title : 繁中 BPS : 18295 DURATION : 02:35:12.929000000 NUMBER_OF_FRAMES: 2514 NUMBER_OF_BYTES : 21297928 SOURCE_ID : 0012a6 _STATISTICS_WRITING_APP: mkvmerge v62.0.0 ('Apollo') 64-bit _STATISTICS_WRITING_DATE_UTC: 2021-12-25 09:11:56 _STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES SOURCE_ID其中,视频 Video: hevc (Main 10), yuv420p10le(tv, bt2020nc/bt2020/smpte2084), 3840x1604, SAR 1:1 DAR 960:401, 23.98 fps, 23.98 tbr, 1k tbn, 23.98 tbc (default), 4k 24fps,且码率是14748974,大略是1.76MB/s。音轨有两个,英语的是杜比全景声,上译国语的是DTS-HD,码率别离达到了0.39MB/s和0.56MB/s。感叹一下,这个码率简直相当于按下面的4k降到1080P(1920*1080,靠近1/4)的码率了,如果是一首3分钟的音乐,按0.39MB/s,就有70MB了。 ...

April 4, 2022 · 8 min · jiezi

关于ffmpeg:音视频FFmpeg入门

术语全称阐明ffmpegFast forword mpeg音视频转换器ffplayFast forword play用ffmpeg实现的播放器ffserverFast forword server用ffmpeg实现的rtsp服务器ffprobeFast forword probe用来输出剖析输出流2. FFMPEG介绍与装置2.1 FFmpeg简介FFmpeg 是一个开源收费跨平台的视频和音频流计划,属于自由软件,采纳 LGPL 或 GPL 许可证(根据你抉择的组件)。它提供了录制、转换以及流化音视频的残缺解决方 案。它蕴含了十分先进的音频/视频编解码库 libavcodec,为了保障高可移植性和编解 码品质,libavcodec 里很多 codec 都是从头开发的。 ffmpeg 我的项目由以下几局部组成: ffmpeg 视频文件转换命令行工具,也反对通过实时电视卡抓取和编码成视频文件.ffserver 基于 HTTP、RTSP 用于实时播送的多媒体服务器.也反对工夫平移ffplay 用 SDL 和 FFmpeg 库开发的一个简略的媒体播放器libavcodec 一个蕴含了所有 FFmpeg 音视频编解码器的库.为了保障最优性能和 高可复用性,大多数编解码器从头开发的.libavformat 一个蕴含了所有的一般音视格局的解析器和产生器的库2.2 FFmpeg装置yum# 1.降级零碎sudo yum install epel-release -y# 2.装置Nux Dextop Yum 源 (centos7)sudo rpm --import http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.rosudo rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpm# 3.装置FFmpeg 和 FFmpeg开发包sudo yum install ffmpeg ffmpeg-devel -y# 4.测试是否装置胜利ffmpeg3. FFmpeg参数阐明3.1 通用选项-L license-h 帮忙-fromats 显示可用的格局,编解码的,协定的。-f fmt 强制采纳格局fmt-i filename 输出文件-y 笼罩输入文件-t duration 设置纪录工夫 hh:mm:ss[.xxx]格局的记录时间也反对-ss position 搜寻到指定的工夫 [-]hh:mm:ss[.xxx]的格局也反对-title string 设置题目-author string 设置作者-copyright string 设置版权-comment string 设置评论-target type 设置指标文件类型(vcd,svcd,dvd) 所有的格局选项(比特率,编解码以及缓冲区大小)主动设置 ,只须要输出如下的就能够了:ffmpeg -i myfile.avi -target vcd /tmp/vcd.mpg-hq 激活高质量设置-itsoffset offset 设置以秒为基准的工夫偏移,该选项影响所有前面的输出文件。该偏移被加到输出文件的时戳,定义一个正偏移意味着相应的流被提早了 offset 秒。[-]hh:mm:ss[.xxx]的格局也反对3.2 视频选项-b bitrate 设置比特率,缺省 200kb/s-r fps 设置帧频 缺省 25-s size 设置帧大小 格局为 WXH 缺省 160X128.上面的简写也能够间接应用:Sqcif 128X96 qcif 176X144 cif 252X288 4cif 704X576-aspect aspect 设置横纵比 4:3 16:9 或 1.3333 1.7777-croptop size 设置顶部切除带大小 像素单位-cropbottom size –cropleft size –cropright size 底部,右边,左边切除带大小。-padtop size 设置顶部补齐的大小 像素单位-padbottom size –padleft size –padright size –padcolor color 设置补齐条大小和颜色(hex,6 个 16 进制的数,红:绿:兰排列,比方 000000 代表彩色)-vn 不做视频记录-bt tolerance 设置视频码率容忍度 kbit/s-maxrate bitrate 设置最大视频码率容忍度-minrate bitreate 设置最小视频码率容忍度-bufsize size 设置码率管制缓冲区大小-vcodec codec 强制应用 codec 编解码形式。 如果用 copy 示意原始编解码数据必须被拷贝。-sameq 应用同样视频品质作为源(VBR)-pass n 抉择解决遍数(1 或者 2)。两遍编码十分有用。第一遍生成统计信息,第二遍生成准确的申请的码率-passlogfile file 抉择两遍的纪录文件名为 file3.3 高级视频选项参考文章CentOS中yum装置ffmpeg

March 26, 2022 · 1 min · jiezi

关于ffmpeg:音视频基础ffmpeg原理项目实战一课完成音视频技术开发入门

download:音视频根底+ffmpeg原理+我的项目实战一课实现音视频技术开发入门Web前端性能优化自查清单前言一份简洁、纯正的Web前端性能优化清单。每个优化点都蕴含有概念、实操和参考资料。面试、实战两相宜。这是一个大工程。在正式开始之前,先对立下语言,廓清每一部分的目标和要求,避免跑偏。 概念:把官话翻译成能看懂、能记住的人话,原则上易读性 > 专业性 实操:本人操作一遍,不做云玩家;记录外围实现,不便CV 参考资料:信息起源选用一手材料,以便保障信息的完整性、准确性和时效性。除非看一手的了解不了…… 一、网络层面 DNS预解析概念DNS-prefetch 是一种 DNS 预解析技术。它会在申请跨域资源之前,事后解析并进行DNS缓存,以缩小真正申请时DNS解析导致的申请提早。对于关上蕴含有许多第三方连贯的网站,成果显著。实操增加ref属性为“dns-prefetch”的link标签。个别放在在html的head中。<link rel="dns-prefetch" href="//xxx.download.com">复制代码href的值就是要预解析的域名,对应前面要加载的资源或用户有可能关上链接的域名。备注同理,也有“ TCP/IP预连贯”,叫preconnect。参考资料中有残缺的形容。利用浏览器缓存概念浏览器缓存是浏览器寄存在本地磁盘或者内存中的申请后果的备份。当有雷同申请进来时,间接响应本地备份,而无需每次都从原始服务器获取。这样不仅晋升了客户端的响应效率,同时还能缓解服务器的拜访压力。其间,约定何时、如何应用缓存的规定,被称为缓存策略。分为强缓存和协商缓存。整个缓存执行的过程大抵如下:①. 申请发动,浏览器判断本地缓存,如果有且未到期,则命中强缓存。浏览器响应本地备份,状态码为200。控制台Network中size那一项显示disk cache;②. 如果没有缓存或者缓存已过期,则申请原始服务器询问文件是否有变动。服务器依据申请头中的相干字段,判断指标文件新鲜度;③. 如果指标文件没变更,则命中协商缓存,服务器设置新的过期工夫,浏览器响应本地备份,状态码为304;④. 如果指标文件有变动,则服务器响应新文件,状态码为200。浏览器更新本地备份。上述过程有几个关键点如何判断缓存是否过期?浏览器读取缓存的申请后果中响应头的Expires 和Cache-Control,与以后工夫进行比拟。其中,Expires是HTTP 1.0的字段,值是一个是相对工夫。Expires: Tue, 18 Jan 2022 09:53:23 GMT复制代码比拟相对工夫,有一个弊病,它依赖计算机时钟被正确设置。为了解决这个问题,HTTP1.1 新增了Cache-Control字段,它的值是一个是绝对工夫。Cache-Control: max-age=60 //单位是秒复制代码 如何判断文件是否变动?首先能够通过比拟 最初批改工夫。// 缓存后果的 响应头Last-Modified: Mon, 10 Jan 2022 09:06:14 GMT// 新申请的 申请头If-Modified-Since: Mon, 10 Jan 2022 09:06:14 GMT复制代码浏览器取出缓存后果中Last-Modified的值,通过If-Modified-Since上送到服务端。与服务器中指标文件的最初批改工夫做比拟。再者能够通过比拟 Etag。 Etag实体标签是附加到文档上的任意标签(援用字符串)。它们可能蕴含了文档的序列号或版本名,或者是文档内容的校验和及其他指纹信息。当发布者对文档进行批改时,会批改文档的实体标签来阐明这是个新的版本。 从响应头的ETag取值,通过申请头的If-None-Match上送,与服务器指标文件的Etag标签比对。// 缓存的 响应头ETag: "61dbf706-142"// 上送的 申请头If-None-Match: "61dbf706-142"复制代码和下面一样,新增的字段也是为了解决前一种计划的某些缺点: 有些文档可能会被周期性地重写(比方,从一个后盾过程中写入),但理论蕴含的数据经常是一样的。只管内容没有变动,但批改日期会发生变化。有些文档可能被批改了,但所做批改并不重要,不须要让世界范畴内的缓存都重装数据(比方对拼写或正文的批改)。有些服务器无奈精确地断定其页面的最初批改日期。有些服务器提供的文档会在亚秒间隙发生变化(比方,实时监视器),对这些服务器来说,以一秒为粒度的批改日期可能就不够用了。 如果两个版本的字段同时存在,怎么办?出于浏览器兼容方面的思考 ,个别两组字段会被同时应用。他们没有优先级一说,取并集。同时呈现时,只有当两个条件都满足,才会命中相应缓存。 实操缓存是web服务器和浏览器的外围能力,支流的web服务框架 nginx、koa-static等都内置有上述缓存策略的实现。开箱即用,无需额定编程或配置。以Nginx举例。强缓存的配置字段是expires,它承受一个数字,单位是秒。server { listen 8080;location / { root /Users/zhp/demo/cache-koa/static; index index.html;# 留神try_files会导致缓存配置不失效 # try_files $uri $uri/ /index.html; expires 60;}}复制代码理论工作中的确配置一下就好了,但这体现不出什么知识点。为了加深印象,我这用koa简陋的模仿了一下,算是对下面那些知识点的验证。上面是一个极简的动态资源服务,不带缓存的。app.use(async (ctx) => { // 1.依据拜访门路读取指定文件 const content = fs.readFileSync(./static${ctx.path}, "utf-8"); // 2.设置响应 ...

March 22, 2022 · 2 min · jiezi

关于ffmpeg:为-Capped-CRF-编码选择最佳-CRF-值

为 Capped CRF 编码抉择最佳 CRF 值扬·奥泽 2020 年 2 月 3 日 在一个充斥不稳固压缩文章的博客中,这可能是所有文章中最不稳固的文章。如果您不应用封顶 CRF 编码,或思考应用雷同的编码,则简直必定不会对它感兴趣。然而,如果您应用下限 CRF 编码(用于恒定速率因子),您简直必定会发现它很乏味,甚至可能很有启发性。 疾速背景阐明。去年年底,我征询了一家大型 OTT 商店,该商店对编码阶梯中的顶级文件应用了 CRF 值为 19 的下限 CRF 编码。上面显示的大部分剖析都是针对这个客户的(他批准了我在一篇文章中的探讨)。我还没有写这篇文章,因为我感觉它对大多数读者来说太艰涩了。 然而,明天早上,我从 Vimeo 下载了一个视频,并留神到它们应用 CRF 值为 20 的下限 CRF 进行编码,您能够在上面的 MediaInfo 中看到。为什么我在玩 Vimeo?因为他们在几个月前声势浩大地承诺,他们将应用 AV1 编解码器对产品抉择进行编码。我会定期下载一个文件,看看是不是这样;到目前为止,还没有 AV1 编码。这并不意味着 Vimeo 不应用 AV1,可能是我的下载工具基本没有捕捉 AV1 编码。 然而,我的确留神到 Vimeo 应用的是 CRF 20,恕我直言,这是次优的,并促使本文复活。没有对 Vimeo 的不尊重,他领有一支杰出的编码业余团队。但这就是我的想法以及起因。 作为背景,大多数制作人应用封顶capped CRF 作为 DIY per-title 按题目编码技术。当您应用 CRF 和无下限进行编码时,FFmpeg 会优先思考品质而不是比特率,并扭转比特率以提供指定的品质,范畴从 1 到 51,较低的数字提供更高的品质。请参阅此处以获取对包含 FFmpeg 命令行在内的封顶 CRF 的残缺阐明。CBR 和 VBR 编码相同,并调整品质以满足指定的数据速率。 ...

December 28, 2021 · 2 min · jiezi

关于ffmpeg:FFMPEG安装

一:ffmpeg官网:FFmpeg官网二:windows下装置ffmpeg1:下载ffmpeg windows下ffmpeg下载地址:https://www.gyan.dev/ffmpeg/b... 抉择适合的ffmpeg进行下载,这里我抉择的是ffmpeg-2021-12-02-git-4a6aece703-full_build.7z 2:配置环境变量 将下载下载的ffmpeg进行解压右击我的电脑-》属性-》高级零碎设置-》环境变量-》零碎变量,在Path中配置ffmpeg的环境变量,地址为ffmpeg目录的bin目录 例如:D:\ffmpeg\bin 3:判断ffmpeg是否装置成 ffmpeg -version如下示意装置胜利三:linux下装置ffmpeg 1:装置依赖包(1):装置SDL2 查看零碎匹配的版本:yum search SDL2装置SDL2开发库:yum install SDL2-devel.x86_64(2):装置yasmyasm下载地址:yasm下载地址 wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gztar -zxvf yasm-1.3.0.tar.gzcd yasm-1.3.0./configuremake && make installyasm --version依据如上装置yasm(3):装置x264x264下载地址:x264下载地址 git clone https://code.videolan.org/videolan/x264.gitcd x264./configure --prefix=/usr/local/x264/ --includedir=/usr/local/include --libdir=/usr/local/lib --enable-shared --disable-asmmake && make install依据如上装置x264 2:装置ffmpegffmpeg下载地址:ffmpeg下载地址 (1):下载并装置ffmpeg wget http://www.ffmpeg.org/releases/ffmpeg-4.4.1.tar.gztar -zxvf ffmpeg-4.4.1.tar.gzcd ffmpeg-4.4.1/./configure --prefix=/usr/local/ffmpeg --enable-gpl --enable-shared --enable-libx264make && make install(2):配置环境变量vim /etc/profile在profile文件中增加如下信息 export FFMPEG_PATH=/usr/local/ffmpegexport CLASSPATH=$FFMPEG_PATH/lib:$CLASSPATHPATH=$FFMPEG_PATH/bin:$PATH从新加载环境变量source /etc/profile(3):配置ffmpeg启动目录vim /etc/ld.so.conf在ld.so.conf文件中增加如下信息/usr/local/ffmpeg/lib从新加载配置ldconfig依据如上安排能够实现在linux下装置ffmpegffmpeg -versionffmpeg装置胜利 

December 7, 2021 · 1 min · jiezi

关于ffmpeg:音视频系列六Windows搭建Nginxrtmp推流服务器

title: 音视频系列六:Windows搭建Nginx+rtmp推流服务器 categories:[ffmpeg] tags:[音视频编程] date: 2021/12/01 <div align = 'right'>作者:hackett</div> <div align = 'right'>微信公众号:加班猿</div> 在后面 阿里云服务器搭建Nginx+rtmp推流服务器 中,咱们曾经配置把阿里云的rtmp推流服务搭建好了,用的是PC软件OBS来进行推流到阿里云服务器转发而后本地拉流。Windows也是大同小异,当初是用Windows进行推流服务的搭建,本地ffmpeg命令行推流,本地ffplay拉流播放/VLC拉流播放。 形式采纳nginx Gryphon + nginx-rtmp-module 的形式搭建,因为Windows的Nginx没有对rtmp模块进行编译,有趣味的能够本人去编译尝试。 一、后期筹备操作系统:Windows Nginx版本:nginx-1.7.11.3-Gryphon RTMP模块:nginx-rtmp-module 推流工具:OBS-Studio/VLC/ffmpeg 命令 拉流工具:VLC/ffplay 播放 官网ffmpeg下载地址:http://ffmpeg.org/download.html 官网nginx下载地址:http://nginx.org/en/download.... 官网nginx 1.7.11.3 Gryphon下载地址:http://nginx-win.ecsds.eu/dow... 官网nginx-rtmp-module下载地址:https://github.com/arut/nginx... 官网vlc media player下载地址:https://www.videolan.org/vlc 二、搭建环境1.ffmpeg装置抉择Windows的版本,跳转到GitHub下载地址:https://github.com/BtbN/FFmpe... 下载最新的带share版本的,就是曾经编译好了的,不必本人再编译 ffmpeg-n4.4.1-2-gcc33e73618-win64-gpl-shared-4.4.zip 解压进去放到装置软件的盘符,增加环境变量即可 D:\ffmpeg-n4.4.1-2-gcc33e73618-win64-gpl-shared-4.4\bin 不重启使Windows环境变量失效,cmd,输出 set path = D:\ffmpeg-n4.4.1-2-gcc33e73618-win64-gpl-shared-4.4\bin 重启命令提示符终端,测试成果: cmd,输出 ffmpeg -version失去如下成果即为胜利装置 2.Nginx装置下载带 rtmp 模块的 nginx 版本,这里用nginx 1.7.11.3 Gryphon,下载地址为:http://nginx-win.ecsds.eu/dow... 下载实现后解压,解压后目录名带空格,留神重命名一下(不然可能会失败),nginx 1.7.11.3 Gryphon 重命名为 nginx-1.7.11.3-Gryphon nginx-rtmp-module下载解压后复制到nginx-1.7.11.3-Gryphon目录下 3.编辑配置文件conf\nginx-win.conf用记事本或者sublime text关上,在文本结尾退出上面代码保留 ...

December 1, 2021 · 1 min · jiezi

关于ffmpeg:音视频系列四ffmpeg之获取音视频帧数据

title: 音视频系列四:ffmpeg之获取音视频帧数据 categories:[ffmpeg] tags:[音视频编程] date: 2021/11/29 <div align = 'right'>作者:hackett</div> <div align = 'right'>微信公众号:加班猿</div> 一、AVFrame解码视频1.先贴一个ffmpeg解析flv文件20帧数据后的截图,AVFrame是蕴含码流参数较多的构造体,构造体源码位于libavcodec/avcodec.h中 残缺代码: #include <stdio.h>#ifdef __cplusplusextern "C" {#endif#include <libavcodec/avcodec.h>#include <libavformat/avformat.h>#ifdef __cplusplus};#endifint openCodecContext(const AVFormatContext* pFormatCtx, int* pStreamIndex, enum AVMediaType type, AVCodecContext** ppCodecCtx) { int streamIdx = -1; // 获取流下标 for (int i = 0; i < pFormatCtx->nb_streams; i++) { if (pFormatCtx->streams[i]->codec->codec_type == type) { streamIdx = i; break; } } if (streamIdx == -1) { printf("find video stream failed!\n"); exit(-1); } // 寻找解码器 AVCodecContext* pCodecCtx = pFormatCtx->streams[streamIdx]->codec; AVCodec* pCodec = avcodec_find_decoder(pCodecCtx->codec_id); if (NULL == pCodec) { printf("avcode find decoder failed!\n"); exit(-1); } //关上解码器 if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) { printf("avcode open failed!\n"); exit(-1); } *ppCodecCtx = pCodecCtx; *pStreamIndex = streamIdx; return 0;}int main(void){ AVFormatContext* pInFormatCtx = NULL; AVCodecContext* pVideoCodecCtx = NULL; AVCodecContext* pAudioCodecCtx = NULL; AVPacket* pPacket = NULL; AVFrame* pFrame = NULL; int ret; /* 反对本地文件和网络url */ const char streamUrl[] = "./ouput_1min.flv"; /* 1. 注册 */ av_register_all(); pInFormatCtx = avformat_alloc_context(); /* 2. 关上流 */ if (avformat_open_input(&pInFormatCtx, streamUrl, NULL, NULL) != 0) { printf("Couldn't open input stream.\n"); return -1; } /* 3. 获取流的信息 */ if (avformat_find_stream_info(pInFormatCtx, NULL) < 0) { printf("Couldn't find stream information.\n"); return -1; } int videoStreamIdx = -1; int audioStreamIdx = -1; /* 4. 寻找并关上解码器 */ openCodecContext(pInFormatCtx, &videoStreamIdx, AVMEDIA_TYPE_VIDEO, &pVideoCodecCtx); openCodecContext(pInFormatCtx, &audioStreamIdx, AVMEDIA_TYPE_AUDIO, &pAudioCodecCtx); pPacket = av_packet_alloc(); pFrame = av_frame_alloc(); int cnt = 20; // 读取20帧数据(音频和视频) while (cnt--) { /* 5. 读流数据, 未解码的数据寄存于pPacket */ ret = av_read_frame(pInFormatCtx, pPacket); if (ret < 0) { printf("av_read_frame error\n"); break; } /* 6. 解码, 解码后的数据寄存于pFrame */ /* 视频解码 */ if (pPacket->stream_index == videoStreamIdx) { avcodec_decode_video2(pVideoCodecCtx, pFrame, &ret, pPacket); if (ret == 0) { printf("video decodec error!\n"); continue; } printf("* * * * * * video * * * * * * * * *\n"); printf("___height: [%d]\n", pFrame->height); printf("____width: [%d]\n", pFrame->width); printf("pict_type: [%d]\n", pFrame->pict_type); printf("key_frame: [%d]\n", pFrame->key_frame); // 视频关键帧 1 -> 是 0 -> 否 printf("___format: [%d]\n", pFrame->format); printf("* * * * * * * * * * * * * * * * * * *\n\n"); } /* 音频解码 */ if (pPacket->stream_index == audioStreamIdx) { avcodec_decode_audio4(pAudioCodecCtx, pFrame, &ret, pPacket); if (ret < 0) { printf("audio decodec error!\n"); continue; } printf("* * * * * * audio * * * * * * * * * *\n"); printf("____nb_samples: [%d]\n", pFrame->nb_samples); printf("__samples_rate: [%d]\n", pFrame->sample_rate); printf("channel_layout: [%lu]\n", pFrame->channel_layout); printf("________format: [%d]\n", pFrame->format); printf("* * * * * * * * * * * * * * * * * * *\n\n"); } av_packet_unref(pPacket); /* 将缓存空间的援用计数-1,并将Packet中的其余字段设为初始值。如果援用计数为0,主动的开释缓存空间 */ } /* 开释资源 */ av_frame_free(&pFrame); av_packet_free(&pPacket); avcodec_close(pVideoCodecCtx); avcodec_close(pAudioCodecCtx); avformat_close_input(&pInFormatCtx); return 0;}2.简略介绍一下流程中的各个函数的意义: ...

November 29, 2021 · 5 min · jiezi

关于ffmpeg:音视频系列三ffmpeg之日志打印

title: 音视频系列三:ffmpeg之日志打印categories:[ffmpeg]tags:[音视频编程]date: 2021/11/27 <div align = 'right'>作者:hackett</div> <div align = 'right'>微信公众号:加班猿</div> 在上一篇 Visual Studio2019集成ffmpeg之hello world中,咱们曾经配置好visual studio的开发环境,接下来持续依据上一篇的环境来学习ffmpeg的日志打印; 日志打印对于定位问题或者寻找bug都起到决定性的作用。 一、FFmpeg 打印日志输入介绍FFmpeg 日志输入的外围函数办法为: av_log() 。为什么说av_log()是FFmpeg中输入日志的外围函数函数? 因为咱们轻易关上一个FFmpeg的源代码文件(源代码文件须要去官网下载带源代码的版本),就会发现其中遍布着av_log()函数。个别状况下FFmpeg类库的源代码不容许应用printf()这种函数,所以打印的所有输入一律应用的av_log()。 二、av_log() 函数阐明av_log()的申明位于libavutil\log.h,具体的申明代码如下: /** * Send the specified message to the log if the level is less than or equal * to the current av_log_level. By default, all logging messages are sent to * stderr. This behavior can be altered by setting a different logging callback * function. * @see av_log_set_callback * * @param avcl A pointer to an arbitrary struct of which the first field is a * pointer to an AVClass struct or NULL if general log. * @param level The importance level of the message expressed using a @ref * lavu_log_constants "Logging Constant". * @param fmt The format string (printf-compatible) that specifies how * subsequent arguments are converted to output. */void av_log(void *avcl, int level, const char *fmt, ...) av_printf_format(3, 4);其中第一个参数指定该log所属的构造体,例如AVFormatContext、AVCodecContext等等。第二个参数指定log的级别,第三个参数为要输入的内容,源代码中定义了如下几个级别: ...

November 27, 2021 · 3 min · jiezi

关于ffmpeg:Visual-Studio2019集成ffmpeg之hello-world

title: 音视频系列二:Visual Studio2019集成ffmpeg之hello worldcategories:[ffmpeg]tags:[音视频编程]date: 2021/11/25 <div align = 'right'>作者:hackett</div> <div align = 'right'>微信公众号:加班猿</div> 一、下载安装Visual Studio下载地址为:https://visualstudio.microsof... 而后进行装置,装置时抉择C/C++开发的选项进行装置,装置时抉择如下: 选好就,点击下一步,期待装置就OK了。 二、下载ffmpeg开发包GitHub下载地址:https://github.com/BtbN/FFmpe... 下载最新的带share版本的,就是曾经编译好了的,不必本人再编译 ffmpeg-n4.4.1-2-gcc33e73618-win64-gpl-shared-4.4.zip ├─bin #可执行程序├─doc #参考文档├─include #头文件目录│ ├─libavcodec│ ├─libavdevice│ ├─libavfilter│ ├─libavformat│ ├─libavutil│ ├─libpostproc│ ├─libswresample│ └─libswscale├─lib #链接库文件└─presets三、创立我的项目目录├─bin #程序执行和调试目录├─include #头文件目录├─lib #动态链接库目录└─src #源码目录四、关上Visual Studio 2019创立我的项目将我的项目创立到src目录上面 文件->新建->我的项目 抉择C++空我的项目 我的项目地位抉择到src,而后创立我的项目。留神:将我的项目解决方案和我的项目放在同一目录中后面的勾要选上,不然默认会多创立一层目录 五、开发环境配置选中我的项目右键抉择属性: C/C++->惯例->附件蕴含目录 【$(ProjectDir)....\include】链接器->惯例->附加库目录 【$(ProjectDir)....\lib】链接器->输出->附加依赖项 avcodec.libavformat.libavutil.libavdevice.libavfilter.libpostproc.libswresample.libswscale.lib 我的项目->配置管理器抉择x64 六、创立hello world程序#include<iostream>using namespace std;extern "C" {//蕴含C头文件#include "libavutil/log.h" #include "libavcodec/avcodec.h"#include "libavfilter/avfilter.h"#include "libavformat/avformat.h" #include "libavutil/avutil.h"#include "libavutil/ffversion.h"#include "libswresample/swresample.h"#include "libswscale/swscale.h"#include "libpostproc/postprocess.h"};int main(int argc, char* argv[]) { av_log_set_level(AV_LOG_DEBUG); //设置日志级别 av_log(NULL, AV_LOG_DEBUG, "hello world log\n"); //打印日志 unsigned int codecVer = avcodec_version(); int ver_major, ver_minor, ver_micro; ver_major = (codecVer >> 16) & 0xff; ver_minor = (codecVer >> 8) & 0xff; ver_micro = (codecVer) & 0xff; printf("Current ffmpeg version is: %s ,avcodec version is: %d=%d.%d.%d\n", FFMPEG_VERSION, codecVer, ver_major, ver_minor, ver_micro); system("pause"); //窗口期待 return 0;}运行后果: ...

November 26, 2021 · 1 min · jiezi

关于ffmpeg:ffmpeg的基本用法

title: ffmpeg的根本用法categories:[ffmpeg]tags:[音视频编程]date: 2021/11/18 <div align = 'right'>作者:hackett</div> <div align = 'right'>微信公众号:加班猿</div> 一、ffmpeg的装置1.Centos装置FFmpeg 在默认的CentOS 8 源仓库中没有提供。你能够抉择通过源文件编译装置 FFmpeg,或者应用dnf工具从Negativo17源仓库中装置。咱们将会应用第二个选项。 实现上面的步骤,在 CentOS 8 上装置 FFmpeg: 1.Negativo17软件源依赖EPEL 和 PowerTools 软件源。以 root 或者其余有 sudo 权限的用户身份运行上面的命令,启用必须的软件源: sudo dnf install epel-releasesudo yum config-manager --set-enabled PowerToolssudo yum-config-manager --add-repo=https://negativo17.org/repos/epel-multimedia.repo2.一旦软件源被启用,装置FFmpeg: sudo dnf install ffmpeg3.通过检测版本号,验证FFmpeg装置: ffmpeg -version4.Negativo17 软件源中的ffmpeg以后版本是4.2.5 ffmpeg version 4.2.5 Copyright (c) 2000-2021 the FFmpeg developersbuilt with gcc 8 (GCC)configuration: --prefix=/usr --bindir=/usr/bin --datadir=/usr/share/ffmpeg --docdir=/usr/share/doc/ffmpeg --incdir=/usr/include/ffmpeg --libdir=/usr/lib64 --mandir=/usr/share/man --arch=x86_64 --optflags='-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' --extra-ldflags='-Wl,-z,relro -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld ' --extra-cflags=' ' --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libvo-amrwbenc --enable-version3 --enable-bzlib --disable-crystalhd --enable-fontconfig --enable-frei0r --enable-gcrypt --enable-gnutls --enable-ladspa --enable-libaom --enable-libdav1d --enable-libass --enable-libbluray --enable-libcdio --enable-libdrm --enable-libjack --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libmp3lame --enable-nvenc --enable-openal --enable-opencl --enable-opengl --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librsvg --enable-libsrt --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libvorbis --enable-libv4l2 --enable-libvidstab --enable-libvmaf --enable-version3 --enable-vapoursynth --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzimg --enable-libzvbi --enable-avfilter --enable-avresample --enable-libmodplug --enable-postproc --enable-pthreads --disable-static --enable-shared --enable-gpl --disable-debug --disable-stripping --shlibdir=/usr/lib64 --enable-libmfx --enable-runtime-cpudetectlibavutil 56. 31.100 / 56. 31.100libavcodec 58. 54.100 / 58. 54.100libavformat 58. 29.100 / 58. 29.100libavdevice 58. 8.100 / 58. 8.100libavfilter 7. 57.100 / 7. 57.100libavresample 4. 0. 0 / 4. 0. 0libswscale 5. 5.100 / 5. 5.100libswresample 3. 5.100 / 3. 5.100libpostproc 55. 5.100 / 55. 5.1002.Windows装置官网地址:http://ffmpeg.org/download.html ...

November 18, 2021 · 7 min · jiezi

关于ffmpeg:音视频编解码-编码参数-CRF

之前多多少少接触过一些编解码参数,CRF 参数也用过,然而最近在和敌人们聊天时,说到应用 FFMPEG 过程中碰到 CRF 参数,以及具体作用流程,这个之前始终没有跟踪过,也没有具体记录过,所以吊起了本人的好奇心,于是决定搞清楚一下,便开始了这次 CRF 的神奇之旅。CRF 简介: 恒定速率因子(CRF,Constant Rate Factor)是一种编码模式,能够向上或向下调整文件数据速率以达到选定的品质级别,而不是特定的数据速率。 如果要放弃最佳品质,而又不怎么放心文件大小,这时候就能够应用 CRF 速率管制模式。 这是大多数状况下倡议的速率管制模式。当输入文件的大小不太重要时,此办法容许编码器尝试为整个文件实现冀望指标视频品质的文件输入,即所谓的一次编码便可在预期视频品质下取得最大的视频压缩效率。CRF 模式次要原理是在编码过程中通过动静调整每帧视频的 QP 值,以便能够取得放弃所需视频品质程度比特率。 然而 CRF 毛病是不能告知编码器冀望取得特定大小的文件或不超过特定大小或比特率。同时须要留神的是采纳 CRF 时不倡议间接用来编码视频以进行流媒体传输。 通常倡议个别应用两种速率管制模式:恒定速率因子(CRF)或 2-pass ABR。 速率管制决定每个帧将应用多少位。 这将确定文件大小以及品质调配形式。CRF 实操演示 通过 FFMPEG 二进制文件尝试用参数 CRF 进行压缩,如下图所示: FFMPEG 采纳 CRF 别离为 18、24 进行压缩,以及和源文件的比拟。 ffmpeg -i test.mp4 -c:v libx264 -crf 18 test18.mp4 理论转码中 转码完结后,会显示具体的编码相干信息,包含 ref,crf 值,qp 量化步长等,以及 I 帧、P 帧、B 帧所占比重。还蕴含了音频相干信息如下图: 用命令 ffmpeg -i test.mp4 -c:v libx264 -crf 24 test24.mp4,进行 CRF=24 的转码,转码后果如下图所示: ...

October 13, 2021 · 3 min · jiezi

关于ffmpeg:mac使用docker安装部署ffmpeg

查看docker蕴含有哪些ffmpeg镜像docker search [OPTIONS] TERM,不理解的能够查看详解 docker search ffmpeg 下载最新ffmpeg镜像docker pull jrottenberg/ffmpeg当镜像下载结束之后,能够用一些命令进行验证是否下载胜利,命令如下: docker images 创立并运行容器docker run -it --name app_ffmpeg -p 18080:18080 -v /Users/yangx/app_ffmpeg/:/mnt/app/ --entrypoint='bash' jrottenberg/ffmpeg检测容器状态docker ps -a 启动|重启|进行ffmpeg服务docker start | restart | stop app_ffmpeg

September 26, 2021 · 1 min · jiezi

关于ffmpeg:从零开始制作一个短视频

TNTWeb - 全称腾讯新闻前端团队,组内小伙伴在Web前端、NodeJS开发、UI设计、挪动APP等大前端畛域都有所实际和积攒。 目前团队次要反对腾讯新闻各业务的前端开发,业务开发之余也积攒积淀了一些前端基础设施,赋能业务提效和产品翻新。 团队提倡开源共建,领有各种技术大牛,团队Github地址:https://github.com/tnfe 明天为大家介绍FFCreator,本文作者德莱问 , 我的项目地址: FFCreator (前言)说点事件以后兵荒马乱,可是互联网畛域可算是始终盛世。明天咱们所说的是短视频畛域。 短视频已成为一种越来越风行的媒体流传模式。像微视和抖音这种 app,每天都会生产成千上万个精彩短视频。而这些视频也为产品带来了微小的流量。随之而来,如何让用户能够疾速生产一个短视频;或者产品平台如何利用已有的图片、视频、音乐素材批量合成大量视频就成为一个技术难点。 明天为大家带来的是一个基于node.js的轻量、灵便的短视频制作库。您只须要增加几张图片或视频片段再加一段背景音乐,就能够疾速生成一个很酷的的视频短片。 github地址:https://github.com/tnfe/FFCreatornpm地址:https://www.npmjs.com/package/ffcreator这篇文章将会率领你从头到尾制作一个短视频。 生成我的项目并装置依赖首先得建一个我的项目,而后执行npm init,一顿回车就好了。 mkdir ffcreator-example && cd ffcreator-examplenpm init接下来进行明天咱们这个包的安装操作 npm install ffcreatororyarn add ffcreator重中之重,ffcreator依赖于FFnpeg,因而必须装置FFmpeg。 FFCreatorLite依赖于FFmpeg>=0.9以上版本。请设置FFmpeg为全局变量, 否则须要应用setFFmpegPath增加FFmpeg本机门路。(windows用户的ffmpeg很可能不在您的%PATH中,因而您必须设置%FFMPEG_PATH)。 装置FFmpeg的教程,我只说下windows和mac的哈,对于其余的在下面github外面有更具体的阐明,之所以只说下windows和mac,因为对于前端开发人员来说,大多数都是mac,也有局部window。对于其余研发人员,如果想尝试的话,能够进到下面github查看其余环境的装置形式。 windows:共四分步:下载、解压、设置环境变量、应用。 参考文档 mac:共两局部: 装置homebrew(如已装置,可疏忽,间接进行下一步): /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"应用homebrew装置ffmpeg: brew install ffmpeg参考文档 至此,我的项目、环境、依赖都ready了,咱们能够进行下一步的操作了。 对于应用ffcreator是一个node的库,提供了多种构造函数能够进行应用: FFScene, // 屏幕,也称场景 // 新建一个显示屏const scene = new FFScene();// 设置背景色 scene.setBgColor('#30336b'); // 设置停留时长 scene.setDuration(8.5); // 设置过渡动画(类型, 工夫)scene.setTransition('Fat', 1.5); // 把屏幕增加到视频发明器实例下面creator.addChild(scene);FFNode, 上面所有类型的基类,能够间接看上面。FFText, 文本元素 const text = new FFText({text: '这是一个文字', x: 250, y: 80});// 文字色彩text.setColor('#ffffff'); // 背景色text.setBackgroundColor('#b33771'); // 呈现动画为fadeIn,动画的时长1秒,delay工夫为1秒,text.addEffect("fadeIn", 1, 1); // 设置文本程度居中text.alignCenter(); // 设置款式object text.setStyle({padding: [4, 12, 6, 12]}); // 把以后文本节点增加到屏幕下面scene.addChild(text);FFImage, 图片元素 ...

August 24, 2021 · 2 min · jiezi

关于ffmpeg:ffmpeg入门篇滤镜的基本使用

转发自白狼栈:查看原文 滤镜什么是滤镜?百度百科介绍说“滤镜次要是用来实现图像的各种特殊效果......”。 咱们最早在ffmpeg是如何转码的一文中理解过滤镜,来回顾下过后的转码流程图。 从图中能够看到滤镜前后画的是虚线,示意可有可无,在术语中,滤镜指的是在编码之前针对解码器解码进去的原始数据(即音视频帧)进行解决的动作,咱们还能够称它为过滤器。 ffmpeg内置了大略近400种滤镜,咱们能够用 ffmpeg -filters 命令查看所有的滤镜,也能够用命令 ffmpeg -h filter=xxx 或者查看官网文档理解每一种滤镜。 理论在大部分音视频的处理过程中都离不开滤镜,所以你应该能明确其重要性。 多个滤镜能够联合在一起应用造成滤镜链或者滤镜图,在每一个滤镜中,不仅能够对输出源进行解决,A滤镜解决好的后果还能够作为B滤镜的输出参数,通过B滤镜持续解决。 针对滤镜的解决,ffmpeg提供了两种解决形式,简略滤镜和简单滤镜。 简略滤镜简略滤镜指的是只有一个输出和输入,而且保障输出和输入的流类型雷同。 比方咱们在上篇文章流的操作(二)如何抉择流?开端提到的把原视频 r3.mp4 等比例缩放一倍 ffmpeg -i r3.mp4 -vf scale=272:480 -y filter.mp4-vf 是 -filter:v 的简写,相似的咱们还能够应用 -filter:a 或者 -af 针对音频流做解决。 -filter的语法规定:-filter[:stream_specifier] filtergraph (output,per-stream)stream_specifier流的类型咱们个别用a示意音频,v示意视频,filtergraph示意具体的滤镜,这里用的是scale滤镜。scale滤镜用于调整视频的大小,比方等比例缩放、等比例放大,不做等比例操作输入就变形了,变形后果咱们个别不思考。 因为咱们晓得原视频 r1ori.mp4 的分辨率是 544x960,所以等比例缩放一倍,下面的命令间接指定了 272x480,scale滤镜自带很多参数,咱们介绍几个罕用的。 in_w in_h 或者 iw ih 示意输出视频的宽高out_w out_h 或者 ow oh 示意输入视频的宽高当然不肯定是视频,输入输出也能够是图片。 所以原视频缩放一倍咱们还能够这样写: ffmpeg -i r3.mp4 -vf scale=iw/2:ih/2 -y filter.mp4问题一:如果咱们要把原视频的宽度调整为300且放弃原分辨率,怎么办? 列一个方程 544/960 = 300/x ,x=300x960/540,很麻烦,后果还不肯定能整除,为此咱们能够间接指定高度等于-1,它会主动做等比例解决。 ffmpeg -i r1ori.mp4 -vf scale=300:-1 -y filter.mp4后果发现转码失败了,提醒 ...

July 23, 2021 · 2 min · jiezi

关于ffmpeg:流的操作二如何选择流

转发自白狼栈:查看原文 从流的操作(一)视频转音频引发的血案一文中咱们理解到,流的抉择,理论有两种形式,一种是ffmpeg主动抉择,一种是设置参数手动抉择。 对于主动抉择,ffmpeg默认抉择规定如下: 视频流:默认抉择分辨率最高的流音频流:默认抉择通道最多的流字幕流:默认抉择第一个字幕编码器反对的字幕流对于视频流和音频流,如果分辨率相等或者通道相等则以第一个为准,数据流和附件流不反对主动抉择,须要手动抉择。 主动抉择的状况下,ffmpeg每种类型只会抉择一路,举个例子 ffmpeg -i r3.mp4 -hide_banner Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'r3.mp4': ... Duration: 00:00:58.54, start: 0.000000, bitrate: 1998 kb/s Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 544x960, 1732 kb/s, 29.83 fps, 29.83 tbr, 11456 tbn, 59.67 tbc (default) Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 129 kb/s (default) Stream #0:2(und): Audio: mp3 (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)注:Stream #0:0,第一个0示意第一个输出文件,第二个0示意第一个输出文件的第一路流如果咱们间接对 r3.mp4 转码操作,你会发现输入的视频只保留了一路视频和一路音频。 ...

July 13, 2021 · 2 min · jiezi

关于ffmpeg:流的操作一视频转音频引发的血案

转发自白狼栈:查看原文 有些小伙伴看文章十分仔细,对于上一节课不经意提到的一些边缘细节都比拟在意,比方 -acodec、-vcodec、流复制等。其实这些都离不开咱们明天要讲的重点——流。 说起流,可能有很多小伙伴第一反馈是流媒体,然而咱们明天要说的是容器内流的类型。通过后面的介绍,置信你对容器内的音频(audio, a)和视频(video, v)都有了一些印象。除此之外,容器内流的类型还有字幕(subtitle, s)、附加数据(attachment, t)和一般数据(data, d)。咱们重点介绍一下音频流、视频流和字幕流。 流的操作,指的是咱们能够从输出文件中抉择不同的流进行操作,而后输入咱们想要的后果。 举个例子,家里有小孩的都应该比较清楚,学校当初有很多英语的配音较量,大屏幕播放一段视频,学生在舞台上配音,十分形象。 在这个场景中,大屏幕上播放的视频,其实就是无声视频。无声视频并不是把声音调到最小,它指的是没有音频的视频,这样播放的视频只有画面。比方说对于前文案例一的素材视频能够通过 -an 的命令去除音频流,只保留视频流即只有画面(没有下载的能够点击这里下载)。 ffmpeg -i r1ori.mp4 -an -y r1-silent.mp4来看下后果视频r1-silent.mp4的信息,没有了 Stream #0:1(und): Audio 的信息。 » ffmpeg -i r1-silent.mp4 -hide_banner Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'r1-silent.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf58.20.100 Duration: 00:00:58.53, start: 0.000000, bitrate: 1687 kb/s Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 544x960, 1684 kb/s, 29.83 fps, 29.83 tbr, 11456 tbn, 59.67 tbc (default) Metadata: handler_name : VideoHandlerAt least one output file must be specified当初即便你把音响抱过去,声音加到最大播放这个视频,也不会听到任何声音。 ...

July 5, 2021 · 2 min · jiezi

关于ffmpeg:ffmpeg入门到实战ffmpeg是怎么转码的

转发自白狼栈:查看原文 浏览目录视频是怎么被播放的?ffmpeg命令的格局ffmpeg转码输入的过程视频是怎么被播放的?咱们晓得,当下大多数播放器都是基于ffmpeg二次开发的。你有没有想过,你用播放器关上一个视频的时候,是怎么看到的画面,怎么听到的声音? 咱们用这张图简略描绘出视频被播放的流程。 上面略微解释下图中的含意。 解封装:播放器将输出的封装格局(mp4、mkv)的数据拆散,产生音频流和视频流两局部,留神此时这两局部数据还只是压缩的数据,相似分流,前面咱们也会介绍如何从视频文件中抽离出音频和视频。下一步就是解码操作了,咱们说解码就是将视频、音频压缩的编码数据,解码成为非压缩的视频、音频原始数据。这里将音频解码为pcm格局的数据,将视频解码为yuv格局的数据。音视频同步播放:把解封装和解码别离拿到的视频信息和音视频数据,发送给显卡和声卡即可播放。ffmpeg命令的格局咱们在音视频根底概念一文中介绍转码的时候,抛出过一条转码的命令,如下 ffmpeg -i input.flv output.mp4对于ffmpeg命令的根本格局,参考ffmpeg官网 ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...翻译过去就是 ffmpeg [全局选项] {[输出文件选项] -i 输出文件} ... {[输入文件选项] 输入文件} ...... 示意一条命令可能会有多个输出和多个输入。 比方咱们能够通过输出多个文件转码后输入多个文件 ffmpeg -i input1 -i input2 \ -acodec … -vcodec … output1 \ -acodec … -vcodec … output2 \ -acodec … -vcodec … output3据不齐全统计,ffmpeg命令的选项数量就有小几万,所以不仅要多把握学习技巧,更多的是多积攒教训,靠死记硬背是齐全行不通的。 那么多的选项,体现在一条命令上,一个根本的通用规定就是: 输出文件选项只作用于它前面的第一个输出文件,天然,输入文件选项也只作用于它前面的第一个输入文件。所以是有程序要求的。 全局选项倒是能够轻易写,比方有个全局选项 -y,询问咱们是否要笼罩输入,上面两种写法都能够 ffmpeg -y -i input.flv output.mp4ffmpeg -i input.flv -y output.mp4然而,如果命令很长很长(比方咱们后面给的音视频案例,一条命令甚至都有几百个字符),相似这种全局选项,最好写在输出文件后面或者输入文件后面。 另外,千万不要先写输入文件,再写输出文件,至多应该写完输出文件,再写输入文件,比方上面这样就是不好的写法 ffmpeg output.mp4 -i input.flv良好的习惯才是好的开始。 ...

June 28, 2021 · 1 min · jiezi

关于ffmpeg:ffmpeg实战音视频基础概念

转发自白狼栈:查看原文 对于音视频,置信大家都看过电影(视频),听过音乐(音频),至多应该都晓得mp4是视频文件,mp3是音频文件。 对于一个音视频文件,都有哪些属性呢?以视频为例,咱们能够通过 ffmpeg -i 命令查看媒体文件的信息。 » ffmpeg -i r1ori.mp4 ffmpeg version 4.1 Copyright (c) 2000-2018 the FFmpeg developers built with Apple LLVM version 10.0.0 (clang-1000.10.44.4) configuration: --prefix=/usr/local/Cellar/ffmpeg/4.1 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags='-I/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/include/darwin' --host-ldflags= --enable-ffplay --enable-gpl --enable-libmp3lame --enable-libopus --enable-libsnappy --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-chromaprint --enable-frei0r --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfdk-aac --enable-libfontconfig --enable-libfreetype --enable-libgme --enable-libgsm --enable-libmodplug --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-librsvg --enable-librtmp --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtesseract --enable-libtwolame --enable-libvidstab --enable-libwavpack --enable-libwebp --enable-libzmq --enable-opencl --enable-openssl --enable-videotoolbox --enable-libopenjpeg --disable-decoder=jpeg2000 --extra-cflags=-I/usr/local/Cellar/openjpeg/2.3.0/include/openjpeg-2.3 --enable-nonfree libavutil 56\. 22.100 / 56\. 22.100 libavcodec 58\. 35.100 / 58\. 35.100 libavformat 58\. 20.100 / 58\. 20.100 libavdevice 58\. 5.100 / 58\. 5.100 libavfilter 7\. 40.101 / 7\. 40.101 libavresample 4\. 0\. 0 / 4\. 0\. 0 libswscale 5\. 3.100 / 5\. 3.100 libswresample 3\. 3.100 / 3\. 3.100 libpostproc 55\. 3.100 / 55\. 3.100Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'r1ori.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf58.20.100 Duration: 00:00:58.53, start: 0.000000, bitrate: 1870 kb/s Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 544x960, 1732 kb/s, 29.83 fps, 29.83 tbr, 11456 tbn, 59.67 tbc (default) Metadata: handler_name : VideoHandler Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 129 kb/s (default) Metadata: handler_name : SoundHandler除了视频的元信息,还包含了更多咱们当初编译的配置,你能够抉择 -hide_banner 参数来暗藏这些信息,残缺的命令如下 ...

June 22, 2021 · 2 min · jiezi

关于ffmpeg:ffmpeg安装之docker安装

转发自白狼栈:查看原文 对于ffmpeg的装置,有的人可能要折腾很久,甚至折腾一个礼拜,究其原因,根本都是编译装置惹的祸。 咱们提供4种装置形式,最简单的莫过于centos7上的编译装置。 ffmpeg动态库下载安装在mac上装置ffmpeg在centos7上编译装置ffmpeg应用docker装置ffmpeg大家能够依据本人的爱好抉择装置。明天咱们来看下docker下如何装置ffmpeg。 绝对于 mac装置ffmpeg 和centos7装置ffmpeg,docker装置ffmpeg简直没有难度,所以docker这么风行还是有很大起因的。 首先我假如看这篇文章的你曾经装置过docker并会简略应用了。 1、下载镜像 ~ docker pull jrottenberg/ffmpeg2、间接运行容器测试装置是否胜利 ~ docker run jrottenberg/ffmpeg:latest -versionffmpeg version 4.1 Copyright (c) 2000-2018 the FFmpeg developersbuilt with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.11) 20160609configuration: --disable-debug --disable-doc --disable-ffplay --enable-shared --enable-avresample --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-gpl --enable-libass --enable-libfreetype --enable-libvidstab --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx265 --enable-libxvid --enable-libx264 --enable-nonfree --enable-openssl --enable-libfdk_aac --enable-libkvazaar --enable-libaom --extra-libs=-lpthread --enable-postproc --enable-small --enable-version3 --extra-cflags=-I/opt/ffmpeg/include --extra-ldflags=-L/opt/ffmpeg/lib --extra-libs=-ldl --prefix=/opt/ffmpeglibavutil 56\. 22.100 / 56\. 22.100libavcodec 58\. 35.100 / 58\. 35.100libavformat 58\. 20.100 / 58\. 20.100libavdevice 58\. 5.100 / 58\. 5.100libavfilter 7\. 40.101 / 7\. 40.101libavresample 4\. 0\. 0 / 4\. 0\. 0libswscale 5\. 3.100 / 5\. 3.100libswresample 3\. 3.100 / 3\. 3.100libpostproc 55\. 3.100 / 55\. 3.100一步到位的感觉就是爽。 ...

June 15, 2021 · 1 min · jiezi

关于ffmpeg:FFmpeg源码世界命令篇

前言最近在做一些音视频畛域的工作,这个畛域根本绕不开 FFmpeg ,因而想对其源码进行一些钻研,站着这个伟人的肩膀上,学习一下其设计思维以及实现思路,FFmpeg 很多人最开始接触的应该都是它的命令和 ffplay ,这篇咱们就先剖析下 ffmpeg 命令 的实现。 感兴趣的能够关注下nilstorm与gezilinll 从问题登程FFmpeg的命令构造是什么样的怎么实现任意性能、配置的随便组装的倒放这种非线性的状况是怎么解决的当不须要转码相似只须要转封装的话是如何解决的命令构造ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...流程揣测应该要有一个数据层,依照输出参数进行数据解析将解码、转码、性能解决、编码四个模块形象离开按第一个环节数据解析的构造组装上述四个模块,造成一条或多条责任链的成果开始解决过程中应该有很多分支判断、参数设置之类的状况,在这里都不思考,咱们先只剖析主链路。 主流程首先 ffmpeg 命令的入口在于 fftools/ffmpeg.c 的 main 函数上,先从这个函数来看下整体的流程,代码用的是 ffmpeg 4.4 的版本,同时会省略一些无关紧要的内容: int main(int argc, char **argv){ /* 一些前置的初始化动作 */ ... /* 数据解析函数,不过在这个函数外面还会去开启输出/输入文件流等解决 */ ret = ffmpeg_parse_options(argc, argv); /* 一些数据判断、开启基准测试之类的解决 */ ... /* 开始做理论的文件转换,即按命令开始解决了 */ if (transcode() < 0) ... /* 完结了,统计耗时等等 */ ...}从上述代码能够看到外围的环节就是两局部:数据解析 + 文件转换,接下来咱们将针对这两局部再深刻进去看看。 接下去咱们剖析过程中应用的命令如下: ffmpeg -i douyin_700x1240.mp4 -vf reverse -af areverse reversed.mp4上述命令是将一个 douyin_700x1240.mp4 这个视频中的视频流于音频流同时倒放,生成 reversed.mp4。 ...

June 13, 2021 · 6 min · jiezi

关于ffmpeg:ffmpeg安装之linux编译安装

转发自白狼栈:查看原文 对于ffmpeg的装置,有的人可能要折腾很久,甚至折腾一个礼拜,究其原因,根本都是编译装置惹的祸。 咱们提供4种装置形式,最简单的莫过于centos7上的编译装置。 ffmpeg动态库下载安装在mac上装置ffmpeg在centos7上编译装置ffmpeg应用docker装置ffmpeg大家能够依据本人的爱好抉择装置。 为什么说在 linux 上编译装置 ffmpeg 最简单?因为编译之前咱们要装置很多扩大库,每个人的环境不同,要装置的编解码库或多或少都有些区别。 linux下装置 ffmpeg,咱们以 centos7 编译装置为例。 先看下零碎环境 [root@localhost vagrant]# cat /etc/redhat-releaseCentOS Linux release 7.1.1503 (Core)1、装置依赖 yum install autoconf automake bzip2 bzip2-devel cmake freetype-devel gcc gcc-c++ git libtool make pkgconfig zlib-devel如果装置依赖的过程中,报如下谬误 File "/bin/yum", line 30 except KeyboardInterrupt, e:或者 updates | 2.9 kB 00:00:00 File "/usr/libexec/urlgrabber-ext-down", line 28 except OSError, e:则优先看下默认的 python 是 2.x 的还是 3.x 的,如果是 3.x 的倡议改成 2.x 的再试试。 2、装置一些必须的编解码库1)编译 nasm,x264 依赖的汇编优化的库 ...

May 31, 2021 · 2 min · jiezi

关于ffmpeg:ffmpeg安装之mac安装

转发自白狼栈:查看原文 对于ffmpeg的装置,有的人可能要折腾很久,甚至折腾一个礼拜,究其原因,根本都是编译装置惹的祸。 咱们提供4种装置形式,最简单的莫过于centos7上的编译装置。 ffmpeg动态库下载安装在mac上装置ffmpeg在centos7上编译装置ffmpeg应用 docker 装置 ffmpeg大家能够依据本人的爱好抉择装置。 明天咱们来看一下如何在mac上装置ffmpeg。 在mac上咱们有3种办法能够装置ffmpeg。 第一种咱们在ffmpeg装置一文中曾经提到过了,间接下载动态库; 第二种是编译装置,不仅要装置xcode,还要装置很多的依赖库,还是让咱们的mac省省心吧,疏忽; 第三种就是咱们明天要说的,通过Homebrew装置。 如果在此之前你通过 Homebrew 曾经装置过 ffmpeg,能够执行命令 brew uninstall ffmpeg 先进行卸载。 装置之前,咱们先看下 Homebrew 的版本,这取决于咱们采纳哪种形式装置。终端执行 brew -v » brew -v Homebrew 1.8.3Homebrew/homebrew-core (git revision 38eb; last commit 2018-11-19)如果你的电脑显示 command not found,请先执行上面的命令装置 Homebrew。 /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"请留神,因为 Homebrew 的版本不同,咱们接下来又有两种不同的操作方法。 1、Homebrew 版本小于2.0此时能够先看下 Homebrew 反对哪些配置选项,而后抉择装置咱们须要的options即可。 » brew options ffmpeg --with-chromaprint Enable the Chromaprint audio fingerprinting library--with-fdk-aac Enable the Fraunhofer FDK AAC library--with-fontconfig Build with fontconfig support ..............................装置的时候,相似上面这样,你能够自行抉择要装置哪些配置选项,这里倡议大家把下面所有的option都加上 ...

May 30, 2021 · 2 min · jiezi

关于ffmpeg:ffmpeg实践

视频近程下载m3u8文件转化为本地的MP4文件ffmpeg -i "https://test.com/index.m3u8" -vcodec copy -acodec copy -absf aac_adtstoasc output.mp4mp4文件压缩ffmpeg -i 606e79f89e9cf.mp4 -b:v 500k suoiao.mp4-b:v :指定视频的码率,这个决定了视频的大小MP4转m3u8文件ffmpeg -i test.mp4 -c:v libx264 -c:a aac -strict -2 -f hls -hls_list_size 0 -hls_time 15 test.m3u8大部分网上搜到的指令是-hls_list_size 5这个参数意思是只取得最初的5个片段,所以要指定参数-hls_list_size 0,这样就能蕴含所有的片段 MP4截取一段转化为gif ffmpeg -ss 270 -t 10 -i output.mp4 -r 15 output1.gif截取视频的某一帧的图片ffmpeg -i test.mp4 -ss 1.000 -vframes 1 test.jpgss为工夫秒数提取音频ffmpeg -i 4.mp4 -vn 4.mp3提取无音频的视频ffmpeg -i 4.mp4 -an r.mp4音频音频文件转换ffmpeg -i test.mp3 -b:a 64k -ar 32000 -y test.m4a从MP3转到m4a,采纳64k的采样率截取某一段音频ffmpeg -ss 18.59 -t 2 -i test.mp3 -c copy 2miao.mp3示意从18.59秒开始截取长度2秒的音频音频拼接ffmpeg -i "concat:a.mp3|b.mp3|c.mp3" -c copy output.mp3把abc3个音频依照abc这个程序拼接起来,要求3个音频的采样率要一样图片打水印ffmpeg -i 1.jpg -vf drawtext=fontcolor=white:fontsize=40:text='hello':x=825:y=1316:fontsize=24:fontcolor=yellow:shadowy=2 1x.jpg去除水印ffmpeg -y -i test.jpg -strict -2 -vf delogo=x=100:y=100:w=200:h=200:show=0 output.jpg

May 28, 2021 · 1 min · jiezi

关于ffmpeg:ffmpeg安装之静态库下载

转发自白狼栈:ffmpeg官网 ,如下图 1、centos下载动态库 依照下面1-2-3的步骤抉择即可。第3步不晓得怎么抉择的,本地执行 lsb_release -a 命令看下零碎版本 $ lsb_release -aLSB Version: :core-4.1-amd64:core-4.1-noarch:cxx-4.1-amd64:cxx-4.1-noarch:desktop-4.1-amd64:desktop-4.1-noarch:languages-4.1-amd64:languages-4.1-noarch:printing-4.1-amd64:printing-4.1-noarchDistributor ID: CentOSDescription: CentOS Linux release 7.4.1708 (Core)Release: 7.4.1708Codename: Core这里我抉择下载 ffmpeg-release-amd64-static.tar.xz - md5,大家依据本人的零碎抉择,不晓得怎么抉择的能够留言。 右键复制下面的下载地址,咱们在终端顺次操作上面的命令$ wget https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz$ tar -xvJf ffmpeg-release-amd64-static.tar.xz$ cd ffmpeg-4.4-amd64-static$ ln -s /opt/ffmpeg-4.4-amd64-static/ffmpeg /usr/bin/ffmpeg最初看是是否装置胜利$ ffmpeg -versionffmpeg version 4.4-static https://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2021 the FFmpeg developersbuilt with gcc 8 (Debian 8.3.0-6)configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libdav1d --enable-libxvid --enable-libzvbi --enable-libzimglibavutil 56\. 70.100 / 56\. 70.100libavcodec 58.134.100 / 58.134.100libavformat 58\. 76.100 / 58\. 76.100libavdevice 58\. 13.100 / 58\. 13.100libavfilter 7.110.100 / 7.110.100libswscale 5\. 9.100 / 5\. 9.100libswresample 3\. 9.100 / 3\. 9.100libpostproc 55\. 9.100 / 55\. 9.100能够看到ffmpeg的版本是4.4,configuration 开启的编解码库也十分丰盛。 ...

May 20, 2021 · 2 min · jiezi

关于ffmpeg:ffmpeg项目实战概述

转发自白狼栈:查看原文 如果你想钻研音视频,ffmpeg相对是绕不过来的一道门槛。 接触过音视频的小伙伴肯定都跟ffmpeg打过交道,什么是ffmpeg,咱们看下 ffmpeg官网 的定义: A complete, cross-platform solution to record, convert and stream audio and video.大抵意思是说ffmpeg是录制、转换和流式传输音视频跨平台的残缺解决方案,说的很虚心。 毫不夸大的说,目前市面上所有跟音视频相干的工具,包含泛滥的播放器,简直都有ffmpeg的影子。 ffmpeg有着弱小的音视频解决能力,学会ffmpeg,能帮忙咱们解决绝大部分音视频相干的需要。 最近两年音视频市场的需要大增,短视频时代的流量王者抖音更是火得一塌糊涂。 咱们关上boss看下市场需求,以杭州为例 简略总结下 工资广泛不低都是大厂,有着相对的前景岗位从嵌入式、android/ios 、后端等都有足够的需要有同学可能要跳出来说了,ffmpeg 不就是命令行工具吗,有什么好学习的? 其实ffmpeg就好比飞机仪表盘的一大堆按键,一个弱小的工具都要学习过能力更好的应用。 咱们这个系列不仅仅是带你入门,更多的是以解决理论问题为主,偏重方向偏服务端对音视频的解决,非常适合 php\python\go\java 等后端开发小伙伴学习。 学习内容包含但不限于混音、水印、字幕、裁剪、反转、叠加、合并、流解决、滤镜、音轨拆散、降噪等。 除了音视频的根底实战,还会囊括流媒体实战开发,分布式并行处理大规模多媒体数据,更有深度学习的递归神经网络案例等等。 在技术栈上,咱们抉择 php + docker + nginx + laravel + rabbitmq + ffmpeg。 另外思考实战性的可操作性问题,咱们抉择七牛云和阿里云,注册账号须要实名认证,想学习的小伙伴能够提前注册一波。

May 18, 2021 · 1 min · jiezi

关于rtsp:RTSP-流相关工具介绍

RTSP (Real Time Streaming Protocol),实时流协定,是一种应用层协定,专为流媒体应用。本文将介绍 GStreamer, VLC, FFmpeg 这几个工具,如何发送、接管 RTSP 流。 前提Ubuntu 18.04 LTS (Bionic Beaver)GStreamer装置: sudo apt install libgstreamer1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio查看所有插件: # conda deactivategst-inspect-1.0 -a播放 ~/Videos/test.mp4 文件: gst-launch-1.0 filesrc location=~/Videos/test.mp4 ! decodebin ! autovideosink播放 /dev/video0 webcam: gst-launch-1.0 v4l2src device=/dev/video0 \! video/x-raw, format=YUY2, width=640, height=480, framerate=30/1 \! autovideosink/dev/video0 相干信息,可见后文“对于 Webcam”。 GStreamer RTSP Server编译 test-launch 例子: sudo apt install libgstreamer1.0-dev libgstrtspserver-1.0git clone https://github.com/GStreamer/gst-rtsp-server.gitcd gst-rtsp-server/git checkout 1.18cd examples/gcc test-launch.c -o test-launch $(pkg-config --cflags --libs gstreamer-rtsp-server-1.0)用 test-launch 发送 RTSP 测试流: ...

April 21, 2021 · 4 min · jiezi

关于ffmpeg:多媒体开发6用滤镜实现各种图片效果

之前讲过应用FFmpeg的drawtext滤镜(把图片或文字加到视频上),而实际上,FFmpeg的滤镜很弱小,远不止加字幕或加图片的性能。滤镜很乏味,能够把图片变含糊、变色、缩放旋转,等等。 本文介绍FFmpeg滤镜的应用。目标是让你感受一下FFmepg的滤镜成果,这样在理论须要某种成果时,能够思考应用FFmpeg。 我这里间接应用FFmpeg的命令行来应用滤镜,不波及写代码调用FFmpeg的内容,并且这里都是对图片进行滤镜解决,你会看到很多乏味的解决成果。 然而,因为FFmpeg滤镜的内容很多,我这里没有一一介绍,你如果想具体理解这部分内容的话,能够查阅官网文档: http://www.ffmpeg.org/ffmpeg-... 本文多图。 (0)前提先要让ffmpeg程序反对滤镜,对于FFmpeg的装置或编译,我之前曾经有介绍,后续还会介绍FFmpeg的编译。之前介绍过,让FFmpeg反对滤镜的话,须要在配置FFmpeg时指定应用avfilter: ./configure --enable-avfilter最终编译进去的FFmepg是反对滤镜的,比方,小程的ffmpeg程序的滤镜信息是这样的: 这个ffmpeg程序已反对滤镜解决,比方之前加字幕、加图片的操作,用的就是这个ffmepg程序。 在进行滤镜解决之前,先给出几张丑陋的原图: 最难看的当然是第三张。 (1)含糊参数boxblur。 ./ffmpeg -i 1.jpg -vf boxblur=2 blur1.jpg值越大越含糊,以下是值别离为2、4、8的成果: (2)变色有几个方法。 (a)colorbalance调整rgb某个维度的权重实现变色。 选项有三组,别离为rs/gs/bs、rm/gm/bm、rh/gh/bh。每一个选项都指定了指标色彩(rgb中的一个),s体现偏暗,m体现偏两头,h体现偏亮(且平滑)。 选项的值范畴为[-1, 1],负数示意偏差指标色彩,正数示意远离指标色彩。 比方这三个命令: ./ffmpeg -i 1.jpg -vf colorbalance=rs=1 colorbalance1-1.jpg ./ffmpeg -i 1.jpg -vf colorbalance=rm=1 colorbalance1-2.jpg ./ffmpeg -i 1.jpg -vf colorbalance=rh=1 colorbalance1-3.jpg 失去的图片是这样的: 再比方把图片变得冷色一点: ./ffmpeg -i 2.jpg -vf colorbalance=rh=-0.6 colorbalance2.jpg成果是这样的: (b)colorchannelmixer对rgba四个通道进行从新计算,并别离给定权重比例。 先看命令: ./ffmpeg -i 3.jpg -vf colorchannelmixer=.3:.4:.3:0:.3:.4:.3:0:.3:.4:.3 colorchannelmixer3.jpg./ffmpeg -i 2.jpg -vf colorchannelmixer=.393:.769:.189:0:.349:.686:.168:0:.272:.534:.131 colorchannelmixer2.jpg ...

January 14, 2021 · 2 min · jiezi

关于ffmpeg:多媒体开发4在视频上显示文字或图片ffmpeg命令

小白:我录了段视频,外面用的音乐是有版权的,而且快过期了,能把音乐去掉吗?小程拿到视频后,一个快捷键关上命令终端,疾速打下一行命令: ffmpeg -i 小白.flv -vcodec copy -an -f mp4 quiet.mp4一个只有视频图像的文件就诞生了。 声画拆散,这当然只是ffmpeg命令的一个利用场景。 那么,FFmpeg是什么呢? 来看看百度百科的解释: FFmpeg是一套能够用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采纳LGPL或GPL许可证。它提供了录制、转换以及流化音视频的残缺解决方案。它蕴含了十分先进的音频/视频编解码库libavcodec,为了保障高可移植性和编解码品质,libavcodec里很多code都是从头开发的。FFmpeg在Linux平台下开发,但它同样也能够在其它操作系统环境中编译运行,包含Windows、Mac OS X等。这个我的项目最早由Fabrice Bellard发动,2004年至2015年间由Michael Niedermayer次要负责保护。许多FFmpeg的开发人员都来自MPlayer我的项目,而且以后FFmpeg也是放在MPlayer项目组的服务器上。我的项目的名称来自MPEG视频编码标准,后面的"FF"代表"Fast Forward"。 小程用本人的话,再来翻译一下: FFmpeg是一个开源我的项目,始终有人在加新性能、优化、改bug。这个我的项目,能够进行音视频的录制、编码、流化、解码、成果解决、重采样等一系列的操作......基本上,有音视频性能的利用,都跟FFmpeg扯上关系,比方暴风影音、QQ影音、mplayer、格局工厂等等。 小白:我可不论谁在用,我只有本人能用就行。小程:那FFmpeg的开源协定LGPL跟耻辱柱,你也不想听了? 小白:LGPL?老公丑陋? 开源我的项目都制订本人的开源协定,这里我不细说了,你感觉有必要的话能够去搜寻理解。 本文的重点在于,介绍如何应用ffmpeg命令(FFmpeg程序),实现一些罕用的音视频操作性能,比方在视频上增加文字或水印。 我的开发环境是mac,以下的介绍都默认在mac零碎上操作,但FFmpeg命令根本是平台无差别的。 生成FFmpeg程序有两个方法,一个是应用源码编译生成,另一个是间接装置,我别离介绍这两种办法。 (一)源码编译出FFmpeg,并实现水印增加这个方法是下载FFmpeg源码下来,再编译生成FFmpeg程序。如果想应用FFmpeg来组装本人的程序,这个方法是必经之路。 我这里介绍怎么用ffmepg命令来给视频增加文字或水印,为了实现这个性能,在编译FFmpeg时须要减少特定的参数设置。由此可见,为了满足不同的需要,能够调整编译FFmpeg的编译选项。 小白:把文字写到视频上?还不简略,你要什么色彩,我有彩色笔。小程:我是说,在视频帧上退出文字,不是让你在屏幕上画个大叉! 在视频帧上退出文字,可抉择的方法有几个,比方能够找一找“编辑视频加广告”、或视频巨匠之类的工具,也能够写程序来实现(比方提取出所有帧,再对图片解决,再整合所有图片),这里介绍的是间接用ffmpeg命令来实现。 这时,须要应用FFmpeg的drawtext滤镜来实现增加字幕。 滤镜,能够了解为视频的编辑性能(视频成果解决),是FFmpeg弱小的性能之一。 先下载FFmpeg的源码: git clone git://source.ffmpeg.org/ffmpeg.git FFmpeg在FFmpeg目录上面,能够看到FFmpeg的编译配置程序configure。 (1)反对滤镜filter要保障ffmpeg程序反对filter,否则ffmpeg在应用drawtext时,会看到这样的提醒: 这时,查看FFmpeg配置后(即执行./configure后)生成的头文件config.h(如果配置过就会有这个文件),能够看到: #define CONFIG_DRAWTEXT_FILTER 0这是还没有关上drawtext滤镜的体现。 那怎么样让ffmpeg程序反对filter呢? 首先,须要装置yasm,如果以后的macos没有这个执行程序的话(能够用wihch yasm 来查看一下)。yasm是一个汇编编译器,我会在FFmpeg编译给挪动平台应用时再介绍一下yasm,当初间接装置即可: brew install yasm你如果不理解brew的话,能够搜寻homebrew进行理解。 装置yasm后,就能够配置FFmpeg,让它反对filter(drawtext依赖于libfreetype): ./configure --enable-libfreetype --enable-avfilter这时,在配置输入中(执行./configure),能够看到: 而此时,config.h中是这样: #define CONFIG_DRAWTEXT_FILTER 1接着,编译出ffmpeg工具即可: make小程不倡议执行make install来装置到零碎,因为在介绍第二种装置ffmpeg程序的方法时,会给零碎装置一个ffmpeg。所以,只执行make在当前目录生成ffmpeg即可。 查一下ffmpeg程序,有没有反对到drawtext滤镜: ./ffmpeg -filters能够看到,曾经有这一项: (2)应用drawtext滤镜以一个视频为例,在没有加字幕前,这个视频是这样的: 应用ffmpeg命令,这样加上字幕: 左右滚动的字幕: ...

January 4, 2021 · 2 min · jiezi

关于ffmpeg:多媒体开发2录制视频

上一节介绍了用ffplay来播放文件(或url),这里有一个概念,如果是播放曾经存在的文件,那叫“回放”,也就是Playback(从流媒体的角度也叫点播),如果播放的是正在录制的数据(边录边播),那叫直播。 不论是回放还是直播,都须要有媒体数据,那这个媒体数据是怎么来的呢?从已有的文件编辑而来是一个方法,但更间接更原始的方法是录制。 录制,就是通过硬件设施,把声音或者图像保留到文件(或者推到文件)。 在FFmpeg程序集中,有一个程序叫作ffmpeg(小写),这个程序提供了录制的性能。在上一节小程介绍了ffplay的装置,而实际上ffplay依赖于FFmpeg,所以当ffplay装置后,那FFmpeg程序集也就装置上了,也就是曾经能够应用ffmpeg程序。 本文介绍如何通过ffmpeg程序来实现声音、图像以及屏幕的录制。 (一)录制命令对于图像,能够通过摄像头或者屏幕来录入,而对于声音则通过麦克风来录入。 因为我应用的是mac电脑,所以,有必要先查看一下mac电脑有没有录制的设施,也就是输出设施。 因为查看输出设施须要指定输出设施的格局类型,所以,先查看输出设施的格局类型: ffmpeg -devices在我的电脑上,有这样的输入: avfoundation AVFoundation input devicelavfi Libavfilter virtual input deviceqtkit QTKit input device第一个类型,即avfoundation,为本机输出设施的格局类型,有了这个类型,就能够进一步查看输出设施了: ffmpeg -list_devices true -f avfoundation -i ""能够看到这样的信息: [AVFoundation input device @ 0x7f97326002e0] AVFoundation video devices:[AVFoundation input device @ 0x7f97326002e0] [0] FaceTime HD Camera[AVFoundation input device @ 0x7f97326002e0] [1] Capture screen 0[AVFoundation input device @ 0x7f97326002e0] AVFoundation audio devices:[AVFoundation input device @ 0x7f97326002e0] [0] Built-in Microphone下面的信息能够晓得,视频输出(video devices)有两个设施,设施0为摄像头,设施1为屏幕,而声音输出(audio devices)则只有设施0,也就是麦克风。 ...

December 16, 2020 · 2 min · jiezi

关于ffmpeg:VideoToolbox对某些H264编码分辨率的不兼容

ffmpeg中应用VideoToolbox进行解码的过程,如果视频编码的H264分辨率比拟怪异,比方300X180或者是320X240这种,反馈一个VideoToolbox session not available status = VTDecompressionSessionCreate(NULL, // allocator videotoolbox->cm_fmt_desc, // videoFormatDescription decoder_spec, // videoDecoderSpecification buf_attr, // destinationImageBufferAttributes &decoder_cb, // outputCallback &videotoolbox->session); // decompressionSessionOut //session无奈获取到值,如果分辨率不是VideoToolbox能够反对的 if (decoder_spec) CFRelease(decoder_spec); if (buf_attr) CFRelease(buf_attr); switch (status) { case kVTVideoDecoderNotAvailableNowErr: av_log(avctx, AV_LOG_VERBOSE, "VideoToolbox session not available.\n");实际上这个问题应该VideoToolbox的自身库兼容性问题,而后提醒的又不太敌对,实际上苹果官网的文档也没有明确的相干阐明,算是一个很诡异的问题。 Overview--------VideoToolbox is a low-level framework that provides direct access to hardware encoders and decoders. It provides services for video compression and decompression, and for conversion between raster image formats stored in CoreVideo pixel buffers. These services are provided in the form of session objects (compression, decompression, and pixel transfer), which are vended as Core Foundation (CF) types. Apps that don't need direct access to hardware encoders and decoders should not need to use VideoToolbox directly.

December 4, 2020 · 1 min · jiezi

关于ffmpeg:项目实战QtFFmpeg录屏应用支持帧率清晰度设置

若该文为原创文章,转载请注明原文出处本文章博客地址:https://blog.csdn.net/qq21497936/article/details/109827936各位读者,常识无穷而人力有穷,要么改需要,要么找专业人士,要么本人钻研红瘦子(红模拟)的博文大全:开发技术汇合(蕴含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬联合等等)继续更新中...(点击传送门) Qt开发专栏:我的项目实战(点击传送门) 需要 实现录屏性能。 原理 应用抓屏模块依照指定范畴和帧率抓屏,同时应用录像模块依照指定图像大小和帧率录制。 Demo 体验下载地址 CSDN:https://download.csdn.net/download/qq21497936/13126842 QQ群:1047134658(点击“文件”搜寻“ffmpegRecord”,群内与博文同步更新) v1.0.0 #ifndef RECORDWIDGET_H#define RECORDWIDGET_H#include <QWidget>#include <QThread>#include <QFileDialog>#include <QDateTime>#include "GrabWindowManager.h"#include "FFmpegRecordManager.h"namespace Ui {class RecordWidget;}class RecordWidget : public QWidget{ Q_OBJECTpublic: explicit RecordWidget(QWidget *parent = 0); ~RecordWidget();protected slots: void slot_timeChange(int time);private slots: void on_pushButton_startRecord_clicked(); void on_pushButton_stopRecord_clicked(); void on_pushButton_browser_clicked();private: Ui::RecordWidget *ui; GrabWindowManager *_pGrabWindowManager; // 抓屏治理类 QThread *_pGrabWindowManagerThread; // 抓屏线程 FFmpegRecordManager *_pFFmpegRecordManager; // 录制治理类 QThread *_pFFmpegRecordManagerThread; // 录制线程};#endif // RECORDWIDGET_H#include "RecordWidget.h"#include "ui_RecordWidget.h"#include <QDateTime>RecordWidget::RecordWidget(QWidget *parent) : QWidget(parent), ui(new Ui::RecordWidget), _pGrabWindowManager(0), _pGrabWindowManagerThread(0){ ui->setupUi(this); QString version = "v1.0.0"; setWindowTitle(QString("录屏Demo %1(作者:红瘦子(AAA红模拟) QQ:21497936 微信:yangsir198808 博客地址:blog.csdn.net/qq21497936)").arg(version)); // 初始化抓屏线程 _pGrabWindowManagerThread = new QThread(); _pGrabWindowManager = new GrabWindowManager(); _pGrabWindowManager->moveToThread(_pGrabWindowManagerThread); connect(_pGrabWindowManager, SIGNAL(signal_timeChange(int)), this, SLOT(slot_timeChange(int))); _pGrabWindowManagerThread->start(); // 初始化录制线程 _pFFmpegRecordManagerThread = new QThread(); _pFFmpegRecordManager = new FFmpegRecordManager(); _pFFmpegRecordManager->moveToThread(_pFFmpegRecordManagerThread); connect(_pFFmpegRecordManagerThread, SIGNAL(started()), _pFFmpegRecordManager, SLOT(slot_start())); _pFFmpegRecordManagerThread->start(); // 关联信号 connect(_pGrabWindowManager, SIGNAL(signal_grapWindow(QImage)), _pFFmpegRecordManager, SLOT(slot_encoderOneFrame(QImage))); // 按键状态初始化 ui->pushButton_startRecord->setEnabled(true); ui->pushButton_stopRecord->setEnabled(false); ui->lineEdit_dirPath->setReadOnly(true); ui->lineEdit_dirPath->setText(QCoreApplication::applicationDirPath()); ui->lineEdit_value->setValidator(new QIntValidator(1, 100)); ui->lineEdit_fps->setValidator(new QIntValidator(5, 50));}RecordWidget::~RecordWidget(){ delete ui;}void RecordWidget::slot_timeChange(int time){ ui->label_time->setText(QString("%1%2:%3%4").arg(time/60/10) .arg(time/60%10) .arg(time%60/10) .arg(time%10));}void RecordWidget::on_pushButton_startRecord_clicked(){ slot_timeChange(0); QScreen *pScreen = QGuiApplication::primaryScreen(); QRect rect = pScreen->availableGeometry(); _pFFmpegRecordManager->setFps(ui->lineEdit_fps->text().toInt()); _pFFmpegRecordManager->setWidthIn(rect.width()); _pFFmpegRecordManager->setHeightIn(rect.height()); _pFFmpegRecordManager->setWidthOut(rect.width()); _pFFmpegRecordManager->setHeightOut(rect.height()); _pFFmpegRecordManager->setValue(ui->lineEdit_value->text().toInt()); _pFFmpegRecordManager->slot_startEncoder(QString("%1/%2.mp4") .arg(ui->lineEdit_dirPath->text()) .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh_mm_ss")), AV_PIX_FMT_BGRA); _pGrabWindowManager->slot_startGrabWindow(rect.x(), rect.y(), rect.width(), rect.height(), ui->lineEdit_fps->text().toInt()); ui->pushButton_startRecord->setEnabled(false); ui->pushButton_stopRecord->setEnabled(true); ui->pushButton_browser->setEnabled(false); ui->lineEdit_fps->setEnabled(false); ui->lineEdit_value->setEnabled(false);}void RecordWidget::on_pushButton_stopRecord_clicked(){ _pGrabWindowManager->slot_stopGrabWindow(); _pFFmpegRecordManager->slot_stopEncoder(); ui->pushButton_startRecord->setEnabled(true); ui->pushButton_stopRecord->setEnabled(false); ui->pushButton_browser->setEnabled(true); ui->lineEdit_fps->setEnabled(true); ui->lineEdit_value->setEnabled(true);}void RecordWidget::on_pushButton_browser_clicked(){ QString dir = QFileDialog::getExistingDirectory(0, "保留到文件夹", "."); if(dir.isEmpty()) { return; } ui->lineEdit_dirPath->setText(dir);} ...

November 19, 2020 · 1 min · jiezi

关于ffmpeg:FFmpeg开发笔记八ffmpeg解码音频并使用SDL同步音频播放

若该文为原创文章,未经容许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062本文章博客地址:https://blog.csdn.net/qq21497936/article/details/108828879各位读者,常识无穷而人力有穷,要么改需要,要么找专业人士,要么本人钻研 红瘦子(红模拟)的博文大全:开发技术汇合(蕴含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬联合等等)继续更新中...(点击传送门) FFmpeg和SDL开发专栏(点击传送门)上一篇:《FFmpeg开发笔记(七):ffmpeg解码音频保留为PCM并应用软件播放》下一篇:敬请期待 前言 ffmpeg解码音频之后进行播放,本篇应用SDL播放ffmpeg解码音频流转码后的pcm。 FFmpeg解码音频 FFmpeg解码音频的根本流程请参照:《FFmpeg开发笔记(七):ffmpeg解码音频保留为PCM并应用软件播放》 SDL播放音频 SDL播放音频的根本流程请参照:《SDL开发笔记(二):音频根底介绍、应用SDL播放音频》 ffmpeg音频同步 ffmpeg同步蕴含音频、视频、字幕等等,此处形容的同步是音频的同步。 根本流程 同步关键点 不扭转播放速度的前提下,音频的播放绝对容易,本文章临时未波及到音视频双轨或多轨同步。 解码音频后,工夫距离还是计算一下,次要是管制解码的距离,防止解码过快导致缓存区溢出导致异样。 解码音频进行重采样之后能够失去指定采样率、声道、数据类型的固定参数,应用SDL用固定参数关上音频,将解码的数据扔向缓存区即可。因为解码的时候其数据量与采样率是对应的,播放的时候也是扔入对应的数据量,所以再不扭转音频采样率的前提下,咱们是能够偷懒不做音频同步的。 压入数据缓存区,能够依据播放的回调函数之后数据缓存区的大小进行同步解码压入音频,然而音频与视频不同,音频卡顿的话对音频播放的成果将会大打折扣,导致音频根本无法被顺利的播放,十分影响用户体验,实测须要保留一倍以上的预加载的音频缓冲区,否则等须要的是再加载就曾经晚了。 音频更为简单的操作波及到倍速播放、音调扭转等等,后续文章会有相应的文章阐明。 ffmpeg音频同步相干构造体详解AVCodecContext 该构造体是编码上下文信息,对文件流进行探测后,就能失去文件流的具体相干信息了,对于编解码的相干信息就在此文件构造中。 与同步视频显示相干的变量在此详解一下,其余的能够自行去看ffmpeg源码上对于构造体AVCodecContext的定义。 struct AVCodecContext { AVMediaType codec_type; // 编码器的类型,如视频、音频、字幕等等 AVCodec *codec; // 应用的编码器 enum AVSampleFormat sample_fmt; // 音频采样点的数据格式 int sample_rate; // 每秒的采样率 int channels; // 音频通道数据量 uint64_t channel_layout; // 通道布局 } AVCodecContext;SwrContext 重采样的构造体,最要害的是几个参数,输出的采样频率、通道布局、数据格式,输入的采样频率、通道布局、数据格式。此构造是不通明的。这意味着如果要设置选项,必须应用API,无奈间接将属性当作构造体变量进行设置。 属性“out_ch_layout”:输出的通道布局,须要通过通道转换函数转换成通道布局枚举,其通道数与通道布局枚举的值是不同的,属性“out_sample_fmt”:输出的采样点数据格式,解码流的数据格式即可。属性“out_sample_rate”:输出的采样频率,解码流的采样频率。属性“in_ch_layout”:输入的通道布局。属性“in_sample_fmt”:输入的采样点数据格式。 属性“in_sample_rate”:输入的采样频率。 Demo源码void FFmpegManager::testDecodeAudioPlay(){ QString fileName = "E:/testFile2/1.mp3"; // 输出解码的文件 QFile file("D:/1.pcm"); AVFormatContext *pAVFormatContext = 0; // ffmpeg的全局上下文,所有ffmpeg操作都须要 AVStream *pAVStream = 0; // ffmpeg流信息 AVCodecContext *pAVCodecContext = 0; // ffmpeg编码上下文 AVCodec *pAVCodec = 0; // ffmpeg编码器 AVPacket *pAVPacket = 0; // ffmpag单帧数据包 AVFrame *pAVFrame = 0; // ffmpeg单帧缓存 SwrContext *pSwrContext = 0; // ffmpeg音频转码 SDL_AudioSpec sdlAudioSpec; // sdk音频构造体,用于关上音频播放器 int ret = 0; // 函数执行后果 int audioIndex = -1; // 音频流所在的序号 int numBytes = 0; // 音频采样点字节数 uint8_t * outData[8] = {0}; // 音频缓存区(不带P的) int dstNbSamples = 0; // 解码指标的采样率 int outChannel = 0; // 重采样后输入的通道 AVSampleFormat outFormat = AV_SAMPLE_FMT_NONE; // 重采样后输入的格局 int outSampleRate = 0; // 重采样后输入的采样率 pAVFormatContext = avformat_alloc_context(); // 调配 pAVPacket = av_packet_alloc(); // 调配 pAVFrame = av_frame_alloc(); // 调配 if(!pAVFormatContext || !pAVPacket || !pAVFrame) { LOG << "Failed to alloc"; goto END; } // 步骤一:注册所有容器和编解码器(也能够只注册一类,如注册容器、注册编码器等) av_register_all(); // 步骤二:关上文件(ffmpeg胜利则返回0) LOG << "文件:" << fileName << ",是否存在:" << QFile::exists(fileName); ret = avformat_open_input(&pAVFormatContext, fileName.toUtf8().data(), 0, 0); if(ret) { LOG << "Failed"; goto END; } // 步骤三:探测流媒体信息 ret = avformat_find_stream_info(pAVFormatContext, 0); if(ret < 0) { LOG << "Failed to avformat_find_stream_info(pAVCodecContext, 0)"; goto END; } // 步骤四:提取流信息,提取视频信息 for(int index = 0; index < pAVFormatContext->nb_streams; index++) { pAVCodecContext = pAVFormatContext->streams[index]->codec; pAVStream = pAVFormatContext->streams[index]; switch (pAVCodecContext->codec_type) { case AVMEDIA_TYPE_UNKNOWN: LOG << "流序号:" << index << "类型为:" << "AVMEDIA_TYPE_UNKNOWN"; break; case AVMEDIA_TYPE_VIDEO: LOG << "流序号:" << index << "类型为:" << "AVMEDIA_TYPE_VIDEO"; break; case AVMEDIA_TYPE_AUDIO: LOG << "流序号:" << index << "类型为:" << "AVMEDIA_TYPE_AUDIO"; audioIndex = index; break; case AVMEDIA_TYPE_DATA: LOG << "流序号:" << index << "类型为:" << "AVMEDIA_TYPE_DATA"; break; case AVMEDIA_TYPE_SUBTITLE: LOG << "流序号:" << index << "类型为:" << "AVMEDIA_TYPE_SUBTITLE"; break; case AVMEDIA_TYPE_ATTACHMENT: LOG << "流序号:" << index << "类型为:" << "AVMEDIA_TYPE_ATTACHMENT"; break; case AVMEDIA_TYPE_NB: LOG << "流序号:" << index << "类型为:" << "AVMEDIA_TYPE_NB"; break; default: break; } // 曾经找打视频品流 if(audioIndex != -1) { break; } } if(audioIndex == -1 || !pAVCodecContext) { LOG << "Failed to find video stream"; goto END; } // 步骤五:对找到的音频流寻解码器 pAVCodec = avcodec_find_decoder(pAVCodecContext->codec_id); if(!pAVCodec) { LOG << "Fialed to avcodec_find_decoder(pAVCodecContext->codec_id):" << pAVCodecContext->codec_id; goto END; } // 步骤六:关上解码器 ret = avcodec_open2(pAVCodecContext, pAVCodec, NULL); if(ret) { LOG << "Failed to avcodec_open2(pAVCodecContext, pAVCodec, pAVDictionary)"; goto END; } // 打印 LOG << "解码器名称:" <<pAVCodec->name << endl << "通道数:" << pAVCodecContext->channels << endl << "通道布局:" << av_get_default_channel_layout(pAVCodecContext->channels) << endl << "采样率:" << pAVCodecContext->sample_rate << endl << "采样格局:" << pAVCodecContext->sample_fmt; outChannel = 2; outSampleRate = 44100; outFormat = AV_SAMPLE_FMT_S16; // 步骤七:获取音频转码器并设置采样参数初始化 pSwrContext = swr_alloc_set_opts(0, // 输出为空,则会调配 av_get_default_channel_layout(outChannel), outFormat, // 输入的采样频率 outSampleRate, // 输入的格局 av_get_default_channel_layout(pAVCodecContext->channels), pAVCodecContext->sample_fmt, // 输出的格局 pAVCodecContext->sample_rate, // 输出的采样率 0, 0); ret = swr_init(pSwrContext); if(ret < 0) { LOG << "Failed to swr_init(pSwrContext);"; goto END; } // 最大缓存区,1152个采样样本,16字节,反对最长8个通道 outData[0] = (uint8_t *)av_malloc(1152 * 2 * 8); ret = SDL_Init(SDL_INIT_AUDIO); // SDL步骤一:初始化音频子系统 ret = SDL_Init(SDL_INIT_AUDIO); if(ret) { LOG << "Failed"; return; } // SDL步骤二:关上音频设备 sdlAudioSpec.freq = outSampleRate; sdlAudioSpec.format = AUDIO_S16LSB; sdlAudioSpec.channels = outChannel; sdlAudioSpec.silence = 0; sdlAudioSpec.samples = 1024; sdlAudioSpec.callback = callBack_fillAudioData; sdlAudioSpec.userdata = 0; ret = SDL_OpenAudio(&sdlAudioSpec, 0); if(ret) { LOG << "Failed"; return; } SDL_PauseAudio(0); _audioBuffer = (uint8_t *)malloc(102400); file.open(QIODevice::WriteOnly | QIODevice::Truncate); // 步骤八:读取一帧数据的数据包 while(av_read_frame(pAVFormatContext, pAVPacket) >= 0) { if(pAVPacket->stream_index == audioIndex) { // 步骤九:将封装包发往解码器 ret = avcodec_send_packet(pAVCodecContext, pAVPacket); if(ret) { LOG << "Failed to avcodec_send_packet(pAVCodecContext, pAVPacket) ,ret =" << ret; break; } // 步骤十:从解码器循环拿取数据帧 while(!avcodec_receive_frame(pAVCodecContext, pAVFrame)) { // nb_samples并不是每个包都雷同,遇见过第一个包为47,第二个包开始为1152的// LOG << pAVFrame->nb_samples; // 步骤十一:获取每个采样点的字节大小 numBytes = av_get_bytes_per_sample(outFormat); // 步骤十二:批改采样率参数后,须要从新获取采样点的样本个数 dstNbSamples = av_rescale_rnd(pAVFrame->nb_samples, outSampleRate, pAVCodecContext->sample_rate, AV_ROUND_ZERO); // 步骤十三:重采样 swr_convert(pSwrContext, outData, dstNbSamples, (const uint8_t **)pAVFrame->data, pAVFrame->nb_samples); // 第一次显示 static bool show = true; if(show) { LOG << numBytes << pAVFrame->nb_samples << "to" << dstNbSamples; show = false; } // 缓存区大小,小于一次回调获取的4097就得提前增加,否则声音会开盾 while(_audioLen > 4096 * 1)// while(_audioLen > 4096 * 0) { SDL_Delay(1); } _mutex.lock(); memcpy(_audioBuffer + _audioLen, outData[0], numBytes * dstNbSamples * outChannel); file.write((const char *)outData[0], numBytes * dstNbSamples * outChannel); _audioLen += numBytes * dstNbSamples * outChannel; _mutex.unlock(); } av_free_packet(pAVPacket); } }END: file.close(); LOG << "开释回收资源"; SDL_CloseAudio(); SDL_Quit(); if(outData[0]) { av_free(outData[0]); outData[0] = 0; LOG << "av_free(outData)"; } if(pSwrContext) { swr_free(&pSwrContext); pSwrContext = 0; } if(pAVFrame) { av_frame_free(&pAVFrame); pAVFrame = 0; LOG << "av_frame_free(pAVFrame)"; } if(pAVPacket) { av_free_packet(pAVPacket); pAVPacket = 0; LOG << "av_free_packet(pAVPacket)"; } if(pAVCodecContext) { avcodec_close(pAVCodecContext); pAVCodecContext = 0; LOG << "avcodec_close(pAVCodecContext);"; } if(pAVFormatContext) { avformat_close_input(&pAVFormatContext); avformat_free_context(pAVFormatContext); pAVFormatContext = 0; LOG << "avformat_free_context(pAVFormatContext)"; }}void FFmpegManager::callBack_fillAudioData(void *userdata, uint8_t *stream, int len){ SDL_memset(stream, 0, len); _mutex.lock(); if(_audioLen == 0) { _mutex.unlock(); return; } LOG << _audioLen << len; len = (len > _audioLen ? _audioLen : len); SDL_MixAudio(stream, _audioBuffer, len, SDL_MIX_MAXVOLUME); _audioLen -= len; memmove(_audioBuffer, _audioBuffer + len, _audioLen); _mutex.unlock(); // 每次加载4096// LOG << _audioLen << len;} ...

September 30, 2020 · 4 min · jiezi

关于ffmpeg:FFmpeg开发笔记七ffmpeg解码音频保存为PCM并使用软件播放

若该文为原创文章,未经容许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062本文章博客地址:https://blog.csdn.net/qq21497936/article/details/108799279各位读者,常识无穷而人力有穷,要么改需要,要么找专业人士,要么本人钻研 红瘦子(红模拟)的博文大全:开发技术汇合(蕴含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬联合等等)继续更新中...(点击传送门) FFmpeg和SDL开发专栏(点击传送门)上一篇:《FFmpeg开发笔记(六):ffmpeg解码视频并应用SDL同步工夫显示播放》下一篇:敬请期待 前言 本篇解码音频,包含从mp3等文件中抽取音频流的pcm,从视频文件中抽取音频流的pcm。 本文章篇幅绝对较长,码字作图不易,请各位读者且行且珍惜。 音频基础知识 音频的几个关键因素请查看:《SDL开发笔记(二):音频根底介绍、应用SDL播放音频》 Demo 导入原始文件,设置好数据类型、升到、采样率 软件下载地址 CSDN:https://download.csdn.net/download/qq21497936/12888731 QQ群:1047134658(点击“文件”搜寻“audacity”,群内与博文同步更新) FFmpeg解码音频ffmpeg解码音频流程 ffmpeg解码音频转码根本流程如下: 步骤一:注册: 应用ffmpeg对应的库,都须要进行注册,能够注册子项也能够注册全副。 步骤二:关上文件: 关上文件,依据文件名信息获取对应的ffmpeg全局上下文。 步骤三:探测流信息: 肯定要探测流信息,拿到流编码的编码格局,不探测流信息则其流编码器拿到的编码类型可能为空,后续进行数据转换的时候就无奈通晓原始格局,导致谬误。 步骤四:查找对应的解码器 根据流的格局查找解码器,软解码还是硬解码是在此处决定的,然而特地留神是否反对硬件,须要本人查找本地的硬件解码器对应的标识,并查问其是否反对。广泛操作是,枚举反对文件后缀解码的所有解码器进行查找,查找到了就是能够硬解了(此处,不做过多的探讨,对应硬解码后续会有文章进行进一步钻研)。 (留神:解码时查找解码器,编码时查找编码器,两者函数不同,不要弄错了,否则后续能关上然而数据是错的) 步骤五:关上解码器 关上获取到的解码器。 步骤六:申请重采样构造体 此处特地留神,基本上解码的数据都是pcm格局,pcm格局也分很多种,若8位整形,无符号8为整形,32位浮点,带P和不带P的,带P的数据真存储为LRLRLRLR不带P的为LLLLRRRR,还有单通道、双通道和多通道,通道又波及到了声道的定位枚举,所以pcm原始数据也多种多样,对齐进行重弄采样使其输入的pcm格局参数特点统一。 步骤七:重采样初始化 重采样构造体设置好后,须要设置失效。 步骤八:解封装获取其中一个数据包。 数据包是封装在容器中的一个数据包。 步骤九:分组数据包送往解码器 拿取封装的一个packet后,判断packet数据的类型进行送往解码器解码。 步骤十:从解码器缓存中获取解码后的数据 一个包可能存在多组数据,老的api获取的是第一个,新的api离开后,能够循环获取,直至获取不到跳转“步骤十二” 步骤十一:样本点重采样 应用冲残阳函数联合转换构造体对编码的数据进行转换,拿到重采样后的音频原始数据。 步骤十二:自行处理 拿到了原始数据自行处理。 继续执行“步骤八”,若步骤八获取不到数据则执行“步骤十二” 步骤十三:开释QAVPacket 此处要独自列出是因为,其实很多网上和开发者的代码: 在进入循环解码前进行了av_new_packet,循环中未av_free_packet,造成内存溢出; 在进入循环解码前进行了av_new_packet,循环中进行av_free_pakcet,那么一次new对应无数次free,在编码器上是不合乎前后一一对应标准的。 查看源代码,其实能够发现av_read_frame时,主动进行了av_new_packet(),那么其实对于packet,只须要进行一次av_packet_alloc()即可,解码完后av_free_packet。 执行完后,返回执行“步骤八:获取一帧packet”,一次循环完结。 步骤十四:开释冲重采样构造体 全副解码实现后,依照申请程序,反向顺次进行对应资源的开释。 步骤十五:敞开解码/编码器 敞开之前关上的解码/编码器。 步骤十六:敞开上下文 敞开文件上下文后,要对之前申请的变量依照申请的程序,顺次开释。 ffmpeg解码音频相干变量 与视频解码通用变量请参照博文《FFmpeg开发笔记(四):ffmpeg解码的根本流程详解》中的“ffmpeg解码相干变量”。 SwrContext 重采样的构造体,最要害的是几个参数,输出的采样频率、通道布局、数据格式,输入的采样频率、通道布局、数据格式。 ffmpeg解码音频流程相干函数原型 与视频解码通用函数原型请参照博文《FFmpeg开发笔记(四):ffmpeg解码的根本流程详解》中的"ffmpeg解码相干函数原型。 swr_alloc_set_optsstruct SwrContext *swr_alloc_set_opts(struct SwrContext *s, int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate, int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate, int log_offset, void *log_ctx); 调配并设置重采样的构造体上下文。 ...

September 27, 2020 · 7 min · jiezi

关于ffmpeg:SDL开发笔记三使用SDL渲染窗口颜色和图片

若该文为原创文章,未经容许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062本文章博客地址:https://blog.csdn.net/qq21497936/article/details/108602694 红瘦子(红模拟)的博文大全:开发技术汇合(蕴含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬联合等等)继续更新中…(点击传送门) Qt开发专栏:三方库开发技术(点击传送门)上一篇:《SDL开发笔记(二):音频根底介绍、应用SDL播放音频》下一篇:敬请期待 前言 对于Qt利用来说,为了更大的跨平台通用性,应用SDL播放音频,同样也风行应用SDL渲染视频,基本上很大一部分市面上的sdk播放器都是基于sdl的,传入窗口句柄应用sdl渲染。 Demo 循环渲染色彩: 按键渲染色彩: 按键渲染图片: SDL渲染流程解析 根本流程如下: 步骤一:初始化子系统 SDL_Init()初始化视频零碎,其余多余的零碎不必初始化。 步骤二:创立窗口 SDL_CreateWindow()创立windows窗口,设置一些罕用属性。 步骤三:创立渲染器(与窗口绑定) SDL_CreateRenderer()创立渲染器,该渲染器创立时曾经与显示的窗口进行了绑定。 步骤四:渲染色彩/渲染图片步骤 本篇有3个demo,别离为渲染了简略的色彩,同构按键工夫渲染不同的色彩,通过按键渲染不同的图片。 渲染简略的色彩:设置渲染色彩->清空->渲染 // 步骤四:开始渲染-渲染简略的色彩for(int index = 0; index < 100000; index++){ SDL_SetRenderDrawColor(pSDLRenderer, index/255%255, index/10%255, index/20%255, 128); SDL_RenderClear(pSDLRenderer); SDL_RenderPresent(pSDLRenderer); SDL_PollEvent(&event);} 按键渲染简略的色彩:设置渲染色彩->清空->渲染->按键不同的色彩 // 步骤四:开始渲染-渲染简答的色彩,承受按键输出0~9对应不同的色彩,// 对键盘事件进行解决bool out = false;int r = 0;int g = 0;int b = 0;while(true){ SDL_SetRenderDrawColor(pSDLRenderer, r, g, b, 255); SDL_RenderClear(pSDLRenderer); SDL_RenderPresent(pSDLRenderer); SDL_PollEvent(&event); switch (event.type) { case SDL_KEYDOWN: switch (event.key.keysym.sym) { case SDLK_ESCAPE: out = true; break; case SDLK_1: r = 255; g = 0; b = 0; break; case SDLK_2: r = 0; g = 255; b = 0; break; case SDLK_3: r = 0; g = 0; b = 255; break; case SDLK_4: r = 255; g = 255; b = 0; break; case SDLK_5: r = 0; g = 255; b = 255; break; case SDLK_6: r = 255; g = 0; b = 255; break; case SDLK_7: r = 255; g = 255; b = 255; break; case SDLK_8: r = 255; g = 140; b = 0; break; case SDLK_9: r = 0; g = 191; b = 255; break; case SDLK_0: r = 255; g = 215; b = 0; break; default: break; } break; case SDL_QUIT: out = true; break; default: break; } if(out) { break; }} 渲染图片:加载图片->创立纹理->清空->复制纹理到渲染->渲染。 ...

September 16, 2020 · 5 min · jiezi

关于ffmpeg:FFmpeg开发笔记四ffmpeg解码的基本流程详解

若该文为原创文章,未经容许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062本文章博客地址:https://blog.csdn.net/qq21497936/article/details/108573195各位读者,常识无穷而人力有穷,要么改需要,要么找专业人士,要么本人钻研 红瘦子(红模拟)的博文大全:开发技术汇合(蕴含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬联合等等)继续更新中...(点击传送门) FFmpeg开发专栏(点击传送门)上一篇:《FFmpeg开发笔记(三):ffmpeg介绍、windows编译以及开发环境搭建》下一篇:敬请期待 前言 ffmpeg波及了很多,循序渐进,本篇形容根本的解码流程。 Demo ffmpeg解码流程 ffmpeg的解码和编码都遵循其根本的执行流程。 根本流程如下: 步骤一:注册: 应用ffmpeg对应的库,都须要进行注册,能够注册子项也能够注册全副。 步骤二:关上文件: 关上文件,依据文件名信息获取对应的ffmpeg全局上下文。 步骤三:探测流信息: 肯定要探测流信息,拿到流编码的编码格局,不探测流信息则其流编码器拿到的编码类型可能为空,后续进行数据转换的时候就无奈通晓原始格局,导致谬误。 步骤四:查找对应的解码器 根据流的格局查找解码器,软解码还是硬解码是在此处决定的,然而特地留神是否反对硬件,须要本人查找本地的硬件解码器对应的标识,并查问其是否反对。广泛操作是,枚举反对文件后缀解码的所有解码器进行查找,查找到了就是能够硬解了(此处,不做过多的探讨,对应硬解码后续会有文章进行进一步钻研)。 (留神:解码时查找解码器,编码时查找编码器,两者函数不同,不要弄错了,否则后续能关上然而数据是错的) 步骤五:关上解码器 关上获取到的解码器。 步骤六:申请缩放数据格式转换构造体 此处特地留神,基本上解码的数据都是yuv系列格局,然而咱们显示的数据是rgb等相干色彩空间的数据,所以此处转换构造体就是进行转换前到转换后的形容,给后续转换函数提供转码根据,是很要害并且十分罕用的构造体。 步骤七:申请缓存区 申请一个缓存区outBuffer,fill到咱们指标帧数据的data上,比方rgb数据,QAVFrame的data上存是有指定格局的数据,且存储有规定,而fill到outBuffer(本人申请的指标格局一帧缓存区),则是咱们须要的数据格式存储程序。 举个例子,解码转换后的数据为rgb888,理论间接用data数据是谬误的,然而用outBuffer就是对的,所以此处应该是ffmpeg的fill函数做了一些转换。进入循环解码: 步骤八:获取一帧packet 拿取封装的一个packet,判断packet数据的类型进行解码拿到存储的编码数据 步骤九:数据转换 应用转换函数联合转换构造体对编码的数据进行转换,那拿到须要的指标宽度、高度和指定存储格局的原始数据。 步骤十:自行处理 拿到了原始数据自行处理。 一直循环,直到拿取pakcet函数胜利,然而无奈got一帧数据,则代表文件解码曾经实现。 帧率须要本人管制循环,此处只是循环拿取,可加提早等。 步骤十一:开释QAVPacket 此处要独自列出是因为,其实很多网上和开发者的代码: 在进入循环解码前进行了av_new_packet,循环中未av_free_packet,造成内存溢出; 在进入循环解码前进行了av_new_packet,循环中进行av_free_pakcet,那么一次new对应无数次free,在编码器上是不合乎前后一一对应标准的。 查看源代码,其实能够发现av_read_frame时,主动进行了av_new_packet(),那么其实对于packet,只须要进行一次av_packet_alloc()即可,解码完后av_free_packet。 执行完后,返回执行“步骤八:获取一帧packet”,一次循环完结。 步骤十二:开释转换构造体 全副解码实现后,装置申请程序,进行对应资源的开释。 步骤十三:敞开解码/编码器 敞开之前关上的解码/编码器。 步骤十四:敞开上下文 敞开文件上下文后,要对之前申请的变量依照申请的程序,顺次开释。 另附上实现的具体解码流程图: 本文章博客地址:https://blog.csdn.net/qq21497936/article/details/108573195 ffmpeg解码相干变量AVFormatContext AVFormatContext形容了一个媒体文件或媒体流的形成和根本信息,位于avformat.h文件中。 AVInputFormat AVInputFormat 是相似COM 接口的数据结构,示意输出文件容器格局,着重于性能函数,一种文件容器格局对应一个AVInputFormat 构造,在程序运行时有多个实例,位于avoformat.h文件中。 AVDictionary AVDictionary 是一个字典汇合,键值对,用于配置相干信息。 AVCodecContext AVCodecContext是一个形容编解码器上下文的数据结构,蕴含了泛滥编解码器须要的参数信息,位于avcodec.h文件中。 AVPacket AVPacket是FFmpeg中很重要的一个数据结构,它保留理解复用(demuxer)之后,解码(decode)之前的数据(依然是压缩后的数据)和对于这些数据的一些附加的信息,如显示工夫戳(pts),解码工夫戳(dts),数据时长(duration),所在流媒体的索引(stream_index)等等。 应用前,应用av_packet_alloc()调配, ...

September 14, 2020 · 4 min · jiezi

关于ffmpeg:FFmpeg开发笔记三ffmpeg介绍windows编译以及开发环境搭建

若该文为原创文章,未经容许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062本文章博客地址:https://blog.csdn.net/qq21497936/article/details/108542400各位读者,常识无穷而人力有穷,要么改需要,要么找专业人士,要么本人钻研红瘦子(红模拟)的博文大全:开发技术汇合(蕴含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬联合等等)继续更新中...(点击传送门) FFmpeg开发专栏(点击传送门)上一篇:《FFmpeg开发笔记(二):ffmpeg在ubuntu编译以及开发环境搭建》下一篇:敬请期待 前言 本篇章是对之前windows环境的补充,之前windows的是无需进行编译的,此篇应用源码进行编译,版本就应用3.4.8。 FFmpeg简介 FFmpeg是当先的多媒体框架,可能解码,编码, 转码,mux,demux,流,过滤和播放人类和机器创立的简直所有内容。它反对最含糊的现代格局,直至最前沿。无论它们是由某些规范委员会,社区还是公司设计的。它还具备高度的可移植性:FFmpeg能够在各种构建环境,机器体系结构和配置下,跨Linux,Mac OS X,Microsoft Windows,BSD,Solaris等编译,运行并通过咱们的测试基础架构FATE。 库性能介绍 FFmpeg下载 官网地址:http://ffmpeg.org/download.html#releases CSDN下载地址:https://download.csdn.net/download/qq21497936/12838391开发应用以后3.4.8稳固版本: 三个都点击了,下载了,如下图: 通过查看,源码中只有configure和makefile,那么是在linux上编译的,笔者想编译windows平台上的mingw32版本的,说不定哪天就要批改编码呢,别说opencv遇到几次了。 FFmpeg编译步骤一:筹备msys环境 下个msys装置,当然也能够应用msys2,笔者偏向msys,本人配置本人的开发环境。 当然装置msys之后,须要将咱们Qt5.9.3的mingw32编译工具链拷贝进去,并关上终端窗口将环境输出进去,后果如下: export PATH=$PATH:/mingw530_32/bin/&esmp;&esmp; ## 步骤二:重新部署库的源码地位,须要拷贝到msys上来 解压后,如下: 步骤三:配置configure./configure --prefix=/home/21497/compile/ffmpeg/ffmpeg-3.4.8/install ./configure --prefix=/home/21497/compile/ffmpeg/ffmpeg-3.4.8/install --disable-x86asm 步骤四:解决问题“pr: command not found” 配置coreutils 下载地址:http://gnuwin32.sourceforge.net/packages/coreutils.htm 间接下载bin文件。 全拷贝过来,笼罩。 本文章博客地址:https://blog.csdn.net/qq21497936/article/details/108542400 步骤五:msys有平台问题,msys2没有,配置msys2环境 下载安装msys2,自带了很多环境,此处留神,咱们要用Qt5.9.3的mingw32,如下图: export PATH=$PATH:/mingw530_32/bin/ 步骤六:配置configure切换msys2./configure --prefix=/home/21497/compile/ffmpeg/ffmpeg-3.4.8/install --disable-x86asm --enable-shared 应用mingw32的环境变量,如下图: 步骤七:编译make -j4 同样的问题,ar,参照步骤四,后持续: 间接转用make,简略粗犷,原理读者本人了解 步骤八:装置make install 模块化 &esmp; 测试DemoFFmpegManager.h #ifndef FFMPEGMANAGER_H#define FFMPEGMANAGER_H#include <QObject>extern "C" { #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libswscale/swscale.h> #include <libavdevice/avdevice.h> #include <libavformat/version.h> #include <libavutil/time.h> #include <libavutil/mathematics.h>}class FFmpegManager : public QObject{ Q_OBJECTpublic: explicit FFmpegManager(QObject *parent = nullptr);signals:public slots:};#endif // FFMPEGMANAGER_HFFmpegManager.cpp ...

September 11, 2020 · 1 min · jiezi

关于ffmpeg:项目实战Qtffmpeg摄像头检测工具

若该文为原创文章,未经容许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062本文章博客地址:https://blog.csdn.net/qq21497936/article/details/108416332红瘦子(红模拟)的博文大全:开发技术汇合(蕴含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬联合等等)继续更新中…(点击传送门) Qt开发专栏:我的项目实战(点击传送门)Qt开发专栏:三方库开发技术 需要 关上检测摄像头工具,包含分辨率和帧率。 Demo 体验下载地址 CSDN:https://download.csdn.net/download/qq21497936/12815691 QQ群:1047134658(点击“文件”搜寻“ffmpegCameraTool”,群内与博文同步更新) 波及其余技术 QCameraInfo关上摄像头偶然拿不到摄像头; QCamera动静切换分辨率会导致解体; QCamera解决高分辨率存在卡顿问题; OpenCV无奈拿取摄像头; OpenCV设置高分辨率存在帧率跟不上,卡顿问题; OpenCV保留高分辨率视频须要批改源码,否则限度mat下限大小为0xFFFF; OpenCV保留高分辨率批改源码后存储视频会导致通道凌乱,须要手动改正色彩通道。 v1.0.0性能程序启动关上计算机默认第一个摄像头,最高分辨率最高帧率关上;反对动静切换分辨率和帧率;反对原图显示,等比例显示;多个设施终端测试可用; 本文章博客地址:https://blog.csdn.net/qq21497936/article/details/108416332 外围代码FfmpegCameraManager.h #ifndef FFMPEGCAMERAMANAGER_H#define FFMPEGCAMERAMANAGER_H/************************************************************\ * 控件名称: FfmpegCameraManager, ffmpeg治理类(用于摄像头操作) * 控件形容: * 1.关上摄像头 * 2.反对动静切换分辨率 * 作者:红模拟 联系方式:QQ21497936 * 博客地址:https://blog.csdn.net/qq21497936 * 日期 版本 形容 * 2018年09年14日 v1.0.0 ffmpeg模块封装空类 * 2020年09年05日 v1.1.0 ffmpeg关上摄像头,反对的动静分辨率切换\************************************************************/#include <QObject>#include <QString>#include <QDebug>#include <QTimer>#include <QThread>#include <QImage>#include <QProcess>#include <QMessageBox>extern "C" { #include "libavcodec/avcodec.h" #include "libavformat/avformat.h" #include "libswscale/swscale.h" #include "libavdevice/avdevice.h" #include "libavformat/version.h" #include "libavutil/time.h" #include "libavutil/mathematics.h" #include "libavformat/avformat.h" #include "libswscale/swscale.h" #include "libswresample/swresample.h" #include "errno.h" #include "error.h"}#define LOG qDebug()<<__FILE__<<__LINE__class FfmpegCameraManager : public QObject{ Q_OBJECTpublic:public: explicit FfmpegCameraManager(QObject *parent = nullptr);signals: void signal_captureOneFrame(QImage image);public: static QString getAvcodecConfiguration();public: bool init(); bool openUsbCamera(); QString getUsbCameraName(); QList<QString> getUsbCameraInfo();public slots: void slot_start(); void slot_stop(); void slot_setSizeFps(int index);protected slots: void slot_captureOneFrame();signals:public slots:private: static bool _init; AVFormatContext *_pAVFormatContext; // 全局上下文 AVInputFormat *_pAVInputFormat; AVDictionary* _pAVDictionary; // 关上编码器的配置 AVCodecContext *_pAVCodecContextForAudio; // 音频解码器上下文 AVCodecContext *_pAVCodecContextForVideo; // 视频解码器上下文(不带音频) AVCodec * _pAVCodecForAudio; // 音频解码器 AVCodec * _pAVCodecForVideo; // 视频解码器(不带音频) int _streamIndexForAudio; // 音频流序号 int _streamIndexForVideo; // 视频流序号 SwrContext *_pSwrContextForAudio; // 音频转换上下文 bool _running; bool _first; bool _opened; uint8_t *_pOutBuffer; AVFrame * _pFrame; AVFrame * _pFrameRGB; AVPacket *_pAVPacket; SwsContext *_pSwsContext; int _videoIndex; QString _cameraDescription; QList<QSize> _listSize; QList<int> _listFps; QList<QString> _listSizeFpsInfo; int _currentSuzeFpsIndex;};#endif // FfmpegCameraManager_HFfmpegCameraManager.cpp ...

September 5, 2020 · 3 min · jiezi

关于ffmpeg:FFmpeg-不完全实战

本文会介绍一些FFmpeg的常用命令(也蕴含FFplay,FFprobe)。笔者在一开始接触FFmpeg时也是从网上找一些文章来看,但都是零零散散,也不知为什么是这个命令,最近为了实现一些工作啃了啃FFmpeg的文档,总结了一些罕用且实用的命令。浏览之前本文介绍的内容不是从零开始的,不会教你去装置,也不会特地难,然而有点长。倡议浏览本文之前浏览一下以下2篇文章: 【必看】阮一峰——FFmpeg 视频解决入门教程又拍云——看视频常见的 720p、1080p、4k,这些分辨率到底蕴含了什么?对于音视频的格局如何查看一个媒体文件的详细信息ffprobe 是一个用来收集媒体文件信息的工具,能够以指定的格局打印出媒体文件信息。你能够用ffprobe查看视频,音频甚至是一张图片的信息。 ffprobe -loglevel quiet -of json -show_format -show_streams video.webmffprobe -v quiet -of json -show_format -show_streams video.webmffprobe -v 8 -of json -show_format -show_streams video.webm# -v = -loglevel 日志的级别,罕用的参数就是 -v quiet / -v 8,这样就能够取得一个比拟洁净的输入。# -of = -print_format 输入的格局,json应该算是可读性比拟高的,也能够抉择 xml, csv 等。# -show_format 打印格局信息# -show_streams 打印流信息拓展:如何比拟两个文件的差别这里会用到 vimdiff,如果会用 vim 的同学能够尝试一下。 vimdiff 的根本用法是: vimdiff file1 file2所以比拟两个媒体文件的差别还是比较简单的: vimdiff <(ffprobe -v quiet -of json -show_format -show_streams video1.mp4) <(ffprobe -v quiet -of json -show_format -show_streams video2.mp4)罕用的音视频格局阮一峰老师的文章中讲的不错,不再赘述。 ...

August 30, 2020 · 6 min · jiezi

关于ffmpeg:前端初识视频原理和ffmpeg

本文导读 浏览本文你将取得一下常识:理解视频的基本原理。 理解FFmpeg是什么,和一些罕用的用法。 用FFmpeg搭建简略的视频直播推流。 FFmpeg在nodeJs中的一些用法。 背景短视频大行其道的年代,作为程序员势必须要理解:视频编辑背地的原理和技术。本文简略的形容了视频的组成原理,和罕用的视频编辑工具,顺便提及了 NodeJs 中的用法。 想要理解视频原理,首先应该从图像原理开始说起。 图像根底1. 像素图像画面由一个数字序列示意的图像中的一个最小单位色块,被称之像素(pixel/px)。 留神:像素只有位图才会有,是用来记录位图图像的。<div align=center><img src="http://blog.toringo.cn/20200626111029.png" style="zoom:50%;" /></div> 咱们所说的图像大小为1920*1080,指的就是长宽各有1920和1080的像素点,那么一张1920*1080的图片总共有的像素点为:1920*1080 = 2073600个像素点。 图像的大小如何计算? 图像的大小:像素数量 * 像素大小 = 图片大小,而像素大小 和 像素深度 有关系。RGB示意的真彩色能示意256×256×256=16,777,216,就是咱们常见的1600万色,是人眼可见的全副色调,超出没有意义。RGB的像素深度有1bit、4bit、8bit、16bit、24bit、32bit,如在ps中下图在新建一张画布抉择8bit(指rgb每种色彩占8bit),那这样1 px = 3 * 8bit = 24bit,俗称24位图。依据以上公式就能算出如下图图像的大小:500 * 378 * 24 / 8 = 567000Byte = 567000Byte / 1024 = 553.7109375 Kb,和ps显示的图像大小一样。 但往往实在的图片大小远比以上计算的后果小很多, 这是因为导出的图片都通过压缩的,对于图片压缩技术可自行搜寻学习。 视频根底1. 视频和图像的关系? 视频就是图片一帧一帧连起来的产物,连起来的越快看着越晦涩,用帧率(就是每秒播放图片的数量FPS)来掂量视频的晦涩度。那么依据图片大小的算法就能算出视频的大小。 视频的大小 = 时长(秒) * 帧率(FPS)* 图片大小; 那么1920×1280分辨率, 30FPS,时长1秒的视频的大小就是:1920 * 1280 * 24 / 8 * 30 / 1024 / 1024 = 210.9375 M,那么1小时的影片须要:210.9 * 60 * 60 / 1024 = 741.4453125 G,不禁一句我x,为啥我下载的大片才1G多,莫慌,视频要是这么简略,那咱们太天真了,所以就有了下文「视频编码」。 ...

August 14, 2020 · 5 min · jiezi

关于ffmpeg:ffmepg的常见使用

ffmpeg -i a.mp4 -i b.wav -shortest -q:v 0 a_av.mp4 -loglevel error -yAdd an audio to a silent video. The -y means overwriting same output video. ffmpeg -i a.wav -ss ${hour}:${min}:${sec} clip.wav -loglevel error -yClip the audio from a specific time step. ffmpeg -i a.mp4 b.acc -yffmpeg -i b.acc b.wav -yExtract the wav audio from a mp4 video.

August 8, 2020 · 1 min · jiezi

关于ffmpeg:ffmepg的常见使用

ffmpeg -i a.mp4 -i b.wav -shortest -q:v 0 a_av.mp4 -loglevel error -yAdd an audio to a silent video. The -y means overwriting same output video. ffmpeg -i a.wav -ss ${hour}:${min}:${sec} clip.wav -loglevel error -yClip the audio from a specific time step. ffmpeg -i a.mp4 b.acc -yffmpeg -i b.acc b.wav -yExtract the wav audio from a mp4 video.

August 8, 2020 · 1 min · jiezi

关于ffmpeg:ffmpeg转换多媒体文件真香

【转载请注明出处】:https://blog.csdn.net/huahao1989/article/details/107877488 1. 装置yasm(如果曾经装置能够略过)先在官网http://yasm.tortall.net/Download.html下载最新版yasm源码 执行上面的命令进行装置 wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gztar -zxvf yasm-1.3.0.tar.gzcd yasm-1.3.0./configuremake make install2. 装置amr编码库(如果须要转amr,mp3相似)下载官网 wget https://sourceforge.net/projects/opencore-amr/files/opencore-amr/opencore-amr-0.1.5.tar.gztar -zxvf opencore-amr-0.1.5.tar.gzcd opencore-amr-0.1.5./configure --enable-shared=no --enable-static=yesmake make install3. 装置ffmpeg先在官网http://www.ffmpeg.org/download.html下载最新版ffmpeg wget https://ffmpeg.org/releases/ffmpeg-4.0.2.tar.bz2tar -xvjf ffmpeg-4.0.2.tar.bz2cd ffmpeg-4.0.2## ./configure --prefix=/usr/local/ffmpeg./configure --enable-version3 --enable-nonfree --disable-ffplay --disable-ffprobe --enable-libopencore-amrnb --enable-libopencore-amrwb --prefix=/usr/local/ffmpegmake make install注:如果无奈解压,请先装置bzip2 之后再解压 yum -y install bzip2装置实现之后配置环境变量 vi /etc/profile在最初PATH增加环境变量: PATH=$PATH:/usr/local/ffmpeg/binexport PATHsource /etc/profileffmpeg -version测试 ffmpeg -i input.mp4 output.aviffmpeg -i 123.aac -ac 1 -ar 8000 123.amr欢送关注 “后端老鸟” 公众号,接下来会发一系列的专题文章,包含Java、Python、Linux、SpringBoot、SpringCloud、Dubbo、算法、技术团队的治理等,还有各种脑图和学习材料,NFC技术、搜寻技术、爬虫技术、举荐技术、音视频互动直播等,只有有工夫我就会整顿分享,敬请期待,现成的笔记、脑图和学习材料如果大家有需要也能够公众号留言提前获取。因为自己在所有团队中根本都处于攻坚和探路的角色,搞过的货色多,遇到的坑多,解决的问题也很多,欢送大家加公众号进群一起交流学习。【转载请注明出处】:https://blog.csdn.net/huahao1989/article/details/107877488

August 8, 2020 · 1 min · jiezi

关于ffmpeg:QuickCut一款基于-FFmpeg功能强大且开源的音视频处理工具

随着视频内容越来越风行,「会剪视频」仿佛逐步成为了大家很有必要学会的一项技能,然而那些业余的视频剪辑软件学习老本以及价格都十分的昂扬,收费的软件性能却很难令人满意。Gitee 上的一名开发者就存在这样的苦恼,直到他发现了 FFmpeg,并基于它应用 PyQt 开发出了一款轻量弱小的音视频处理软件,一起来卡看看吧 项目名称:QuickCut 我的项目作者:淳帅二代 开源许可协定:MIT 我的项目地址:https://gitee.com/haujet/QuickCut 我的项目简介Quick Cut 是一款轻量、弱小、好用的视频处理软件。它是一个轻量的工具,而不是像 Davinci Resolve、Adobe Premiere 那样业余的、简单的硕大无朋。Quick Cut 能够满足普通人个别的视频解决需要:压缩视频、转码视频、倒放视频、合并片段、依据字幕裁切片段、主动配字幕、主动剪辑等等。 界面预览 我的项目个性简略的界面FFmpeg 预设丰盛可自定义预设合并视频片段逐句提取每句字幕对应的视频片段主动转字幕主动剪辑……界面和性能介绍FFmpeg 界面在这个界面,你能够应用许多 ffmpeg 预设,对音视频进行解决,比如说: 我想将手机上录制的视频压抑下,减小它的大小,那么只须要:先在 输出1 框输出待压抑的视频文件(此时会主动生成输入文件名),再在右侧预设列表抉择 H264压抑 预设(此时会主动生成总命令),最初点击底部的 运行 按钮,就会启动压抑了。 宰割视频界面这个界面有三个性能:依据字幕宰割视频、依据大小宰割视频、依据时长宰割视频。 依据字幕宰割视频是个神级性能,尤其适宜于制作外语学习的视频素材。将例如美剧的视频放进去,再把相应的字幕文件放进去,就能够将每一句字幕对应的视频片段剪进去!如果你的字幕时间轴和视频时间轴有偏差,还能够进行手动的校准。 合并片段界面这个简略,要合并的视频拖进去,调整下程序,点击运行,就能够将这些视频合并成一个文件。从 ig 下载的 15 秒 story 视频片段就能够轻松合并啦! 下载视频界面这个界面提供了两个命令行工具的图形界面用于下载视频,最简略的用法就是将链接复制进去,而后点击下载。反对的网站有很多比方优酷、B站、YouTube、P站(逃)…… 另外你还能够在外面设置cookies,就可能用你大会员身份登录的 cookie 信息下载大会员视频画质了。 主动剪辑界面主动剪辑的原理是通过给视频中有声音的片段和没有声音的片段施加不同的播放速度,达到只保留有要害信息局部的成果,非常适合做vlog和视频教程。 主动转字幕界面只有将你的视频或者音频文件拖进去,而后点击运行,就能够生成一个srt格局的字幕。 如此丰盛的性能,一点都不亚于那些业余的视频处理软件,当初作者曾经将源代码开源在了 Gitee 上,如果你感兴趣想要让他变得更弱小,那么就点击前面的链接返回我的项目主页看看吧:https://gitee.com/haujet/QuickCut

July 28, 2020 · 1 min · jiezi

关于ffmpeg:QuickCut一款基于-FFmpeg功能强大且开源的音视频处理工具

随着视频内容越来越风行,「会剪视频」仿佛逐步成为了大家很有必要学会的一项技能,然而那些业余的视频剪辑软件学习老本以及价格都十分的昂扬,收费的软件性能却很难令人满意。Gitee 上的一名开发者就存在这样的苦恼,直到他发现了 FFmpeg,并基于它应用 PyQt 开发出了一款轻量弱小的音视频处理软件,一起来卡看看吧 项目名称:QuickCut 我的项目作者:淳帅二代 开源许可协定:MIT 我的项目地址:https://gitee.com/haujet/QuickCut 我的项目简介Quick Cut 是一款轻量、弱小、好用的视频处理软件。它是一个轻量的工具,而不是像 Davinci Resolve、Adobe Premiere 那样业余的、简单的硕大无朋。Quick Cut 能够满足普通人个别的视频解决需要:压缩视频、转码视频、倒放视频、合并片段、依据字幕裁切片段、主动配字幕、主动剪辑等等。 界面预览 我的项目个性简略的界面FFmpeg 预设丰盛可自定义预设合并视频片段逐句提取每句字幕对应的视频片段主动转字幕主动剪辑……界面和性能介绍FFmpeg 界面在这个界面,你能够应用许多 ffmpeg 预设,对音视频进行解决,比如说: 我想将手机上录制的视频压抑下,减小它的大小,那么只须要:先在 输出1 框输出待压抑的视频文件(此时会主动生成输入文件名),再在右侧预设列表抉择 H264压抑 预设(此时会主动生成总命令),最初点击底部的 运行 按钮,就会启动压抑了。 宰割视频界面这个界面有三个性能:依据字幕宰割视频、依据大小宰割视频、依据时长宰割视频。 依据字幕宰割视频是个神级性能,尤其适宜于制作外语学习的视频素材。将例如美剧的视频放进去,再把相应的字幕文件放进去,就能够将每一句字幕对应的视频片段剪进去!如果你的字幕时间轴和视频时间轴有偏差,还能够进行手动的校准。 合并片段界面这个简略,要合并的视频拖进去,调整下程序,点击运行,就能够将这些视频合并成一个文件。从 ig 下载的 15 秒 story 视频片段就能够轻松合并啦! 下载视频界面这个界面提供了两个命令行工具的图形界面用于下载视频,最简略的用法就是将链接复制进去,而后点击下载。反对的网站有很多比方优酷、B站、YouTube、P站(逃)…… 另外你还能够在外面设置cookies,就可能用你大会员身份登录的 cookie 信息下载大会员视频画质了。 主动剪辑界面主动剪辑的原理是通过给视频中有声音的片段和没有声音的片段施加不同的播放速度,达到只保留有要害信息局部的成果,非常适合做vlog和视频教程。 主动转字幕界面只有将你的视频或者音频文件拖进去,而后点击运行,就能够生成一个srt格局的字幕。 如此丰盛的性能,一点都不亚于那些业余的视频处理软件,当初作者曾经将源代码开源在了 Gitee 上,如果你感兴趣想要让他变得更弱小,那么就点击前面的链接返回我的项目主页看看吧:https://gitee.com/haujet/QuickCut

July 28, 2020 · 1 min · jiezi

关于ffmpeg:ffmpeg视频添加多段配音音频ffmpeg视频指定时间点插入音频

需要:咱们有一个无声的视频,有字幕,用户能够本人录制多段音频插入到视频,给视频配音 例如:有一个无声视频video.mp4,视频长度90s有三段音频:1.mp3须要在视频第2s插入2.mp3须要在视频第38s插入3.mp3须要在视频第59s插入 搜寻:在网上搜寻了很久没找到,比方搜寻:ffmpeg视频音频合并ffmpeg给视频增加多段音频ffmpeg给视频增加多段配音ffmpeg在视频指定工夫点插入音频 钻研一番搜寻后没有找到想要的,就只好本人钻研钻研,功夫不负有心人,终于搞进去了 如须要可分割我,wexin: Tomener,请备注ffmpeg,付费。

July 23, 2020 · 1 min · jiezi

FFmpeg-命令行视频处理拼接实战

涉及ffmpeg效果如下:截取、拼接、添加文字、图片转视频、混音、横批转竖屏 效果:固定的片头片尾+视频中间内容是对用户之前提交过的n个历史视频的截取片段的拼接+固定片尾,视频片段切换添加了转场特效。 示例描述:片头 +第一次提交视频的相关信息展示(2s 时长) +第一次提交的视频截取片段 +第N次提交视频的相关信息展示(2s 时长) +第N次提交的视频截取片段 +片尾 大致操作步骤:对n个MP4视频进行截取。对n个截取片段进行缩放,保证每个视频的宽高是一样的。生成介绍视频拼接添加背景音乐实际命令公共编码参数: -c:v libx264 -profile:v high -crf 18 -r 30 -b:v 665k -acodec aac -ar 48000 -ab 128k -c:v libx264 -profile:v high -crf 18 -r 30 -b:v 665k -acodec aac -ar 48000 -ab 128k1.截取视频-ss 5 视频开始时长-t 25 截取时长-vbsf h264_mp4toannexb mp4 转 ts 文件的时候添加这个参数,不太清楚。 /var/ffmpeg_build/bin/ffmpeg -i /video_splicing/2077357_0_55257.mp4 -ss 5 -t 25 -c:v libx264 -profile:v high -crf 18 -r 30 -b:v 665k -acodec aac -ar 48000 -ab 128k -y -vbsf h264_mp4toannexb /video_splicing/2077357_0_55257_cut.ts > /dev/null 2>&1 参数位置与截取速度-ss 在 -i 参数之前,截取处理数据快,但是时间时长偏差较大。(时长偏差值大概 1-10 s之间,实际值好像解决取视频中关键帧的位置)-ss 在 -i 参数之后,时间时长偏差较小,但截取处理数据慢。 ...

June 9, 2020 · 2 min · jiezi

ffmpeg423libavutil硬件编码接口hwcontext

硬件编解码如何利用日益强大的硬件来实现高效的编解码有则非比寻常的意义,对于开发者来说,面对日益增加的不同硬件,带来的不同的接口,如何快速的使用和对接,本身就是一个问题,还好ffmpeg为了我们提供非常好的解决方案,完全不用去关心底层的实现,一切面向接口的良好体现。 hwcontext模块支持的平台static const char *const hw_type_names[] = { [AV_HWDEVICE_TYPE_CUDA] = "cuda", //CUDA是Nvidia出的一个GPU计算库 [AV_HWDEVICE_TYPE_DRM] = "drm", //DRM 是linux 下的图形渲染架构(Direct Render Manager) [AV_HWDEVICE_TYPE_DXVA2] = "dxva2",//微软dx套件,使用D3D9 [AV_HWDEVICE_TYPE_D3D11VA] = "d3d11va",//微软dx套件,使用D3D11 [AV_HWDEVICE_TYPE_OPENCL] = "opencl",//第一个面向异构系统(此系统中可由CPU,GPU或其它类型的处理器架构组成)的并行编程的开放式标准。面向GPU编程 [AV_HWDEVICE_TYPE_QSV] = "qsv",//英特尔Quick Sync Video,号称地球最强 [AV_HWDEVICE_TYPE_VAAPI] = "vaapi", //Video Acceleration Api,UNINX下的编码接口,intel提供 [AV_HWDEVICE_TYPE_VDPAU] = "vdpau", //Video Decode and Presentation API for Unix ,NVIDIA提供的 [AV_HWDEVICE_TYPE_VIDEOTOOLBOX] = "videotoolbox", // mac iOS [AV_HWDEVICE_TYPE_MEDIACODEC] = "mediacodec", // Android};查看状态或者指定使用某种解码器ffmpeg -hwaccels hwcontext 核心接口创建初始化av_hwdevice_ctx_createav_hwdevice_ctx_allocdevice_ctx->internal->hw_type->device_create 绑定到具体硬件的指针函数上av_hwdevice_ctx_init创建初始化AVHWFramesContext描述硬件frame的一个pool,包括大小,格式,AVHWDeviceContext,长/宽等内容 ...

June 5, 2020 · 2 min · jiezi

使用NDK编译ffmpeg41fdkaac20

基本配置ubuntu18ffmpeg4.1.3fdk-aac2.0.0NDK r20b 编译fdkaac静态库脚本 #!/bin/bashNDK=/系统ndk路径/android-ndk-r20bHOST_TAG=linux-x86_64TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAGANDROID_LIB_PATH="$(pwd)/android"API=21function build_android_arm{echo "build for android $CPU"./configure \--host=$HOST \--disable-shared \--enable-static \--prefix="$ANDROID_LIB_PATH/$CPU" \ CPPFLAGS="-fPIC"make cleanmake -j8make installecho "building for android $CPU completed"}# armv7CPU=armv7HOST=arm-linux-androidexport AR=$TOOLCHAIN/bin/arm-linux-androideabi-arexport AS=$TOOLCHAIN/bin/arm-linux-androideabi-asexport LD=$TOOLCHAIN/bin/arm-linux-androideabi-ldexport RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlibexport STRIP=$TOOLCHAIN/bin/arm-linux-androideabi-stripexport CC=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clangexport CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++build_android_arm# armv8CPU=armv8HOST=aarch64-linux-androidexport AR=$TOOLCHAIN/bin/aarch64-linux-android-arexport AS=$TOOLCHAIN/bin/aarch64-linux-android-asexport LD=$TOOLCHAIN/bin/aarch64-linux-android-ldexport RANLIB=$TOOLCHAIN/bin/aarch64-linux-android-ranlibexport STRIP=$TOOLCHAIN/bin/aarch64-linux-android-stripexport CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clangexport CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++build_android_arm编译ffmpeg静态库脚本 NDK=/home/kyun/work/ndk/android-ndk-r20bHOST_TAG=linux-x86_64TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAGANDROID_LIB_PATH="$(pwd)/android"SYSROOT=$NDK/toolchains/llvm/prebuilt/$HOST_TAG/sysrootAPI=21function build_android_arm{echo "Compiling FFmpeg for $CPU"./configure \--disable-stripping \--disable-ffmpeg \--disable-ffplay \--disable-ffprobe \--disable-avdevice \--disable-devices \--disable-indevs \--disable-outdevs \--disable-asm \--disable-doc \--enable-gpl \--enable-nonfree \--enable-version3 \--enable-static \--disable-shared \--enable-small \--enable-dct \--enable-dwt \--enable-lsp \--enable-mdct \--enable-rdft \--enable-fft \--disable-filters \--disable-postproc \--disable-bsfs \--enable-bsf=h264_mp4toannexb \--enable-decoder=h264 \--enable-bsf=aac_adtstoasc \--disable-encoders \--enable-encoder=pcm_s16le \--disable-decoders \--enable-decoder=mp3 \--enable-decoder=pcm_s16le \--disable-parsers \--enable-parser=aac \--enable-parser=mpegaudio \--disable-muxers \--enable-muxer=flv \--enable-muxer=wav \--enable-muxer=adts \--enable-muxer=mp3 \--disable-demuxers \--enable-demuxer=flv \--enable-demuxer=wav \--enable-demuxer=aac \--enable-demuxer=mp3 \--disable-protocols \--enable-protocol=rtmp \--enable-protocol=file \--disable-runtime-cpudetect \--enable-libfdk-aac \--enable-encoder=libfdk_aac \ --enable-decoder=libfdk_aac \--prefix="$PREFIX" \--cross-prefix="$CROSS_PREFIX" \--target-os=android \--arch="$ARCH" \--cpu="$CPU" \--cc="$CC" \--cxx="$CXX" \--enable-cross-compile \--sysroot="$SYSROOT" \--extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS" \--extra-ldflags="-Lexternal-lib/fdk-aac/$CPU/"make cleanmake -j8make installecho "The Compilation of FFmpeg for $CPU is completed"}#armv8-aARCH=arm64CPU=armv8-aCC=$TOOLCHAIN/bin/aarch64-linux-android$API-clangCXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-PREFIX=$ANDROID_LIB_PATH/$CPUOPTIMIZE_CFLAGS="-march=$CPU -Iexternal-lib/fdk-aac/include"build_android_armTips:集成到Android工程里时,由于是静态库,除引入ffmpeg静态库外,还需引入libfdk-aac.a本文参考最新FFMPEG移植Android ...

June 2, 2020 · 1 min · jiezi

ffmpeg423libavutil模块内存管理

核心模块内存管理buffer.h / buffer_internal.h主要是ffmpeg缓存数据的主要接口,主要包含以下几个数据结构:AVBuffer,AVBufferRef,BufferPoolEntry,AVBufferPool。 AVBuffer/AVBufferRef 结构struct AVBuffer { uint8_t *data; /**< data described by this buffer */ //缓冲区地址 int      size; /**< size of data in bytes */ //缓冲区大小 /** * number of existing AVBufferRef instances referring to this buffer */ atomic_uint refcount; //引用计数值 ,原子操作 /** * a callback for freeing the data */ void (*free)(void *opaque, uint8_t *data); //用于释放缓冲区内存的回调函数 /** * an opaque pointer, to be used by the freeing callback */ void *opaque; //提供给free回调函数的参数 /** * A combination of BUFFER_FLAG_* */ int flags; // 缓冲区标志 }; ...

May 30, 2020 · 4 min · jiezi