一、视频相关的基础知识

1、容器

  • 固定格式的多媒体文件
  • mp4、flv、avi、mkv

2、媒体流

  • 时间轴上一段连续的数据
  • 一段视频数据、一段声音数据、一段字幕数据
  • 压缩的数据需要关联特定的编解码器

3、数据帧

  • 一个媒体流由大量的数据帧组成
  • 对于压缩数据,帧对应着编解码器的最小处理单元
  • 不同媒体流的数据帧交错存储在容器中
  • Frame对应压缩前的数据,Packet对应压缩后的数据

4、编解码器

  • 以帧为单位实现压缩数据和原始数据之间的相互转换
  • 例如图象YUV数据可以通过H264编码器编码为H264帧,H264帧又可以通过H264解码器变为图像数据
  • 声音的PCM数据可以通过AAC编码器编码为ACC帧

5、复用

  • 将不同的流按照某种规则放入容器

6、解复用

  • 将不同的流从某种容器中解析出来

7、帧率

  • 视频文件中每一秒的帧数,肉眼想看连续移动的画面至少要15帧/s

8、码率

  • 也叫比特率,表示每秒处理的字节数,码率越高视频质量越好,单位是bps
  • 知道码率和时长就可以算出文件大小

9、ffmpeg/ffplay/ffprobe

  • ffmpeg:超快音视频编码器
  • ffplay:媒体播放器
  • ffprobe:多媒体流分析器

二、ffplay

  • ffplay -ss 00:10:00 -t 10 -x 800 test.mp4 (从10分钟处开始播放test.mp4 10秒,限制画面大小为800*-1)
  • ffplay test.mp4 -vf tranpose=1 (旋转视频播放)

三、ffmpeg

查看编码器详细参数 ffmpeg -encoders | findstr 264

音视频参数

  • -vcodec 设定视频编解码器,如果是copy表示拷贝输入视频的编码数据,不作新的处理

  • -vf 视频过滤器

  • -vn 不处理视频,即没有视频

  • -an 不处理音频,即没有音频

  • 音频参数就是把v变为a

  • ffmpeg -i in.mp4 -ss 10 -t 10 out.mp4(截取从in.mp4的10-20s内容输出为out.mp4)

  • ffmpeg -i in.mp4 -b:a 192k -ar 48000 -ac 2 -acodec libmp3lame -aframes 200 out.mp3(-b:a 音频码率,-ar采样率, -ac声音的channel数一般为2,-aframes输出音频的帧数)

  • ffmpeg -i in.mp4 -vframes 1000 -b:v 5000k -r 100 -s 1000x700 -aspect 16:9 out.mp4

    • -r 100表示每秒100帧,-vframes 1000表示视频一共1000帧,这样视频一共10s
    • -b:v 5000k 表示视频码率,即视频每秒的多少比特,越大视频越清晰,生成的视频大小为5000/8/1024*10s=6.14M字节
    • -s 表示将视频画面设置的宽高
    • -aspect 表示画布的宽高
  • 像素格式指定

    • -pix_fmt yuv420p
    • -pix_fmt rgb24
  • preset crf

  • 过滤器 -vf(video filter)

    • ffplay -i 100.mp4 -vf crop=iw/2:ih:0:0
    • fflpay -i 100.mp4 -vf drawtext=fontsize=60:text=‘hello’


import org.bytedeco.ffmpeg.avformat.AVFormatContext;
import org.bytedeco.ffmpeg.avformat.AVStream;
import org.bytedeco.javacv.*;import javax.swing.*;
import java.util.Arrays;public class Main {public static void main(String[] args) throws Exception {String filename = "C:\\Users\\程勇\\Videos\\100.mp4";FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(filename);grabber.start();AVFormatContext context = grabber.getFormatContext();// 视频帧率int frameRate = (int)grabber.getVideoFrameRate();// 视频时长int timeLen = (int)grabber.getLengthInTime() / 1000000;System.out.println("视频帧率:" + frameRate + ", 视频时长:" + timeLen + "s");// 视频高度和宽度 1920*1080int frameWidth = grabber.getImageWidth(), frameHeight = grabber.getImageHeight();System.out.println("视频宽度:" + frameWidth + ", 视频高度:" + frameHeight);// 流的数目(一般是两个,视频流+音频流)for(int i = 0; i < context.nb_streams(); i ++ ){AVStream stream = context.streams(i);System.out.println("编码器类型:" + stream.codecpar().codec_type() + ", 编码器id:" + stream.codecpar().codec_id());}Frame frame;// canvas可以显示图象
//        CanvasFrame canvas = new CanvasFrame("aaa");// 记录视频FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("C:\\Users\\程勇\\Videos\\200_new.avi", 720, 405, 2);recorder.setFormat("avi");recorder.start();System.out.println(grabber.getLengthInFrames());int cnt = 0;while((frame = grabber.grab()) != null){//            canvas.showImage(frame);recorder.record(frame);cnt ++ ;if(cnt % 100 == 0) System.out.println(cnt);}System.out.println(cnt);grabber.close();recorder.close();}
}
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;public class VideoConvert {public static void main(String[] args) throws FFmpegFrameRecorder.Exception, FFmpegFrameGrabber.Exception {FFmpegFrameGrabber grabber = new FFmpegFrameGrabber("C:\\Users\\程勇\\Videos\\100.mp4");FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("C:\\Users\\程勇\\Videos\\100.flv",grabber.getImageWidth(), grabber.getImageHeight(), grabber.getAudioChannels());recorder.start(grabber.getFormatContext());for(;;){recorder.recordPacket(grabber.grabPacket());}}
}
import org.bytedeco.javacpp.Loader;
import org.bytedeco.javacv.FFmpegFrameRecorder;import java.io.IOException;public class Cmd {public static void main(String[] args) throws IOException, InterruptedException {String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class);ProcessBuilder pb = new ProcessBuilder(ffmpeg, "-i", "C:\\Users\\程勇\\Videos\\100.mp4","-vcodec", "h264", "C:\\Users\\程勇\\Videos\\100.avi");pb.inheritIO().start().waitFor();}
}
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;public class VideoGrayProcessor {final static String videoFolderPath = "C:\\Users\\程勇\\Videos\\";final static String videoName = "100.mp4";public static void main(String[] args) throws Exception {videoProcess(videoFolderPath + videoName);}//视频水印public static void videoProcess(String filePath) {//抓取视频图像资源FFmpegFrameGrabber videoGrabber = new FFmpegFrameGrabber(filePath);//抓取视频图像资源FFmpegFrameGrabber audioGrabber = new FFmpegFrameGrabber(filePath);try {videoGrabber.start();audioGrabber.start();FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(videoFolderPath + "new" + videoName,videoGrabber.getImageWidth(), videoGrabber.getImageHeight(), videoGrabber.getAudioChannels());recorder.start();//处理图像int videoSize = videoGrabber.getLengthInVideoFrames();for (int i = 0; i < videoSize; i++) {Frame videoFrame = videoGrabber.grabImage();if (videoFrame != null && videoFrame.image != null) {System.out.println("视频共" + videoSize + "帧,正处理第" + (i + 1) + "帧图片");Java2DFrameConverter converter = new Java2DFrameConverter();BufferedImage bi = converter.getBufferedImage(videoFrame);BufferedImage bufferedImage = grayProcess(bi);recorder.record(converter.convert(bufferedImage));}}//处理音频for (int i = 0; i < audioGrabber.getLengthInAudioFrames(); i++) {Frame audioFrame = audioGrabber.grabSamples();if (audioFrame != null && audioFrame.samples != null) {recorder.recordSamples(audioFrame.sampleRate, audioFrame.audioChannels, audioFrame.samples);}}recorder.stop();recorder.release();videoGrabber.stop();audioGrabber.stop();} catch (Exception e) {e.printStackTrace();}}//灰度处理public static BufferedImage grayProcess(BufferedImage bufImg) {int width = bufImg.getWidth();int height = bufImg.getHeight();for (int i = 0; i < width; i++) {for (int j = 0; j < height; j++) {bufImg.setRGB(i, j, grayRGB(bufImg.getRGB(i, j)));}}return bufImg;}//rgb灰度转换private static int grayRGB(int rgb) {int R = (rgb & 0xff0000) >> 16;int G = (rgb & 0x00ff00) >> 8;int B = rgb & 0x0000ff;//平均值String average = Integer.toHexString((R + G + B) / 3);if (average.length() == 1) {average = "0" + average;}//RGB都变成平均值return Integer.parseInt(average + average + average, 16);}
}

ffmpeg和JavaCV相关推荐

  1. java 直播媒体流服务(ffmpeg、javacv)支持本地视频、网路视频

    还在为视频推流和拉流而烦恼吗?还在为安装nginx.ffmpeg而头疼吗?只需要两步就可以省去这些烦恼,第一步:推流 第二步:播放,你确定不入手么 一.添加媒体流服务依赖包 maven pom.xml ...

  2. JavaCV音视频开发宝典:使用JavaCV采集windows系统声音并录制成mp3音频文件(FFmpeg采集windows系统声音)

    <JavaCV音视频开发宝典>专栏目录导航 <JavaCV音视频开发宝典>专栏介绍和目录 前言 之前已经写过很多采集windows.macos和linux本机麦克风声音的文章, ...

  3. 使用JavaCV实现海康rtsp转rtmp实现无插件web端直播(无需转码,低资源消耗)

    使用JavaCV实现海康rtsp转rtmp实现无插件web端直播(无需转码,低资源消耗) 目录结构 添加依赖,编写配置文件 创建Bean 创建缓存Cache 修改启动类 拉流.推流.转封装 定时任务T ...

  4. 如何在龙芯架构和国产化操作系统平台上运行javacv

    前言 在上一篇中讲到,在全面国产化替换即将到来之时,聊聊如何在国产芯片龙头"龙芯"和国产操作系统平台上运行c/c++.java.nodejs.等编程语言,go/rust等静态编译型 ...

  5. javacv 简介、中文文档、中英对照文档 下载

    javacv 文档 下载链接(含jar包.源码.pom) 组件名称 中英对照-文档-下载链接 中文-文档-下载链接 javacv-1.5.7.jar javacv-1.5.7-API文档-中英对照版. ...

  6. 20190227最近比较纠结的问题vue的video中视频的播放和nginx-rtmp的推流以及什么时候推流的分析

    1.vue中的video的使用(支持MP4) Vue中引入Video.js视频播放器 参考:https://www.jianshu.com/p/8b8023c7ed37 Video.js是一个有着HT ...

  7. 实时监控、直播流、流媒体、视频网站开发方案设计简要

    快速传送至:javacv入门指南:序章 快速传送至:从零开始开发和搭建直播平台-教程汇总篇 javaCV系列文章: javacv开发详解之1:调用本机摄像头视频 javaCV开发详解之2:推流器实现, ...

  8. 2020 年值得关注的 5 个国产 Java 开源项目

    Java 被发明出来已经三十年了,其流行程度和各方面的成熟度大家都是有目共睹的.在 Gitee 上,Java 语言所编写出的开源项目也是长期霸占排行榜的前列,除了许多经典的开源项目外,Gitee 上也 ...

  9. javacv 写mp4_JavaCV教程篇1之springboot调用ffmpeg将webm视频格式转换为MP4格式

    准备环境: springboot2.x maven 1.第一步,在pom.xml文件中加入JavaCV依赖,如下: org.bytedeco javacv-platform 1.5.4 2.编写如下函 ...

  10. javaCV入门指南:调用FFmpeg原生API和JavaCV是如何封装了FFmpeg的音视频操作?

    JavaCV入门指南系列: JavaCV入门指南:序章(看完本章后,不想看原理的小伙伴可直接跳转到<快速上手篇>) JavaCV入门指南:调用FFmpeg原生API和JavaCV是如何封装 ...

最新文章

  1. Windows下超详细安装Anaconda3以及jupyter notebook
  2. 9032c语言程序设计,2016年中国计量学院机电工程学院9032C语言程序设计考研复试题库...
  3. BuckleScript 1.0发布,面向OCaml的开源JavaScript编译器
  4. 【JZOJ3397】【luoguP4556】雨天的尾巴
  5. 《HTML5和CSS3快速参考》——1.3HTML5的品牌化
  6. python 中指针_【系列】Python源码剖析(base 2.7.18)Note之初见“对象”
  7. Nmap 可能引起cisco路由器Crash
  8. mysql repaire_mysql之repair table 修复表札记
  9. 【05】制作第一个zblog模板第四期,完成首页logo、搜索、文章列表,友情链接等大部分首页自定义模块
  10. 梦三国解析服务器spl文件头失败怎么解决,梦三国 卡顿问题的解决方法
  11. laravel faker数据填充详解
  12. 英文 SCI 论文写作常用句式(保持更新)
  13. unity3d.com国际版下载
  14. 计算机论文致谢词范文500字,2021年论文致谢词范文500字(通用5篇)
  15. python交通调查数据处理_GitHub - unlimitbladeworks/traffic-monitor: 基于高德地图的交通数据分析...
  16. 马士兵MCA架构师读书笔记
  17. 万字长文:盘点2022全球10大数据泄漏事件(红蓝攻防角度)
  18. C语言:记录zmq订阅地址ipc文件问题
  19. 12-1 蓝色天空 : 创建一个背景为蓝色的Pygame窗口 12-2 游戏角色 : 找一幅你喜欢的游戏角色位图图像或将一幅图像转换为位图。 创建一个类, 将该角色绘制到屏幕中央, 并将该图像的背景色
  20. JS实现AST抽象语法树问题

热门文章

  1. FFMPEG硬件编解码器使用
  2. springboot制作补丁包通用解决方案
  3. linux双击脚本不弹出选择框,在安装msicuu2.exe的时候不能安装弹出对话框windows脚本宿主是怎么回事?...
  4. phpcms整站代码分析
  5. 纳多德通过ISO 9001质量、ISO 14001环境、ISO 45001职业健康安全国际管理体系认证
  6. Fedora系统配置中文输入法
  7. CH579 以太网转串口 串口服务器代码
  8. 计算机网络基础试题2,计算机网络基础试题库2
  9. 计算机系统工具没有用户,联想电源管理软件没了怎么办_联想电脑自带的电源管理软件不见了如何找回-win7之家...
  10. 订单明细升级版、淘宝erp、淘宝打单发货接口