实战教程:如何在Java中使用FFmpegFrameRecorder类
最编程
2024-02-15 11:32:55
...
实例1: initRecorder
import org.bytedeco.javacv.FFmpegFrameRecorder; //导入依赖的package包/类
void initRecorder(String filename) {
try {
log.info(String.format("initRecorder %s", filename));
recorder = new FFmpegFrameRecorder(filename, imageSize.width(), imageSize.height(), 1);
//recorder.setFormat("flv");
// recorder.setFormat("mjpeg");
recorder.setFormat("mp4");
recorder.setSampleRate(sampleAudioRateInHz);
recorder.setImageWidth(imageSize.width());
recorder.setImageHeight(imageSize.height());
// re-set in the surface changed method as well
recorder.setFrameRate(frameRate);
recorder.start();
log.info("recorder.setFrameRate(frameRate)");
// Create audio recording thread
// audioRecordRunnable = new AudioRecordRunnable();
// audioThread = new Thread(audioRecordRunnable);
/*
*
* recorder = new FFmpegFrameRecorder(filePath, width, height);
* recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
* recorder.setFormat("mp4"); recorder.setFrameRate(VIDEO_FPS);
* recorder.setVideoBitrate(16384);
* recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
*/
} catch (Exception e) {
Logging.logError(e);
}
}
实例2: initRecorder
import org.bytedeco.javacv.FFmpegFrameRecorder; //导入依赖的package包/类
private void initRecorder() {
Log.w(LOG_TAG,"init recorder");
if (yuvIplimage == null) {
yuvIplimage = IplImage.create(imageWidth, imageHeight, IPL_DEPTH_8U, 2);
Log.i(LOG_TAG, "create yuvIplimage");
}
Log.i(LOG_TAG, "ffmpeg_url: " + ffmpeg_link);
recorder = new FFmpegFrameRecorder(ffmpeg_link, imageWidth, imageHeight, 1);
recorder.setFormat("flv");
recorder.setSampleRate(sampleAudioRateInHz);
// Set in the surface changed method
recorder.setFrameRate(frameRate);
Log.i(LOG_TAG, "recorder initialize success");
audioRecordRunnable = new AudioRecordRunnable();
audioThread = new Thread(audioRecordRunnable);
runAudioThread = true;
}
实例3: onPreviewFrame
import org.bytedeco.javacv.FFmpegFrameRecorder; //导入依赖的package包/类
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
/* get video data */
if (yuvIplimage != null && recording) {
yuvIplimage.getByteBuffer().put(data);
Log.v(LOG_TAG,"Writing Frame");
try {
long t = 1000 * (System.currentTimeMillis() - startTime);
if (t > recorder.getTimestamp()) {
recorder.setTimestamp(t);
}
recorder.record(yuvIplimage);
} catch (FFmpegFrameRecorder.Exception e) {
Log.v(LOG_TAG,e.getMessage());
e.printStackTrace();
}
}
}
实例4: saveVid
import org.bytedeco.javacv.FFmpegFrameRecorder; //导入依赖的package包/类
public void saveVid(File f, int width, int fps, ProgressDisplay d, ActionListener onFinish) {
saveStopped = false;
new Thread(() -> {
try {
d.setProgress(0, "Starting export");
d.setCancel(ae -> saveStopped = true);
String name = f.getName();
int dotIdx = name.lastIndexOf('.');
if(dotIdx !=- 1)
name = name.substring(0, dotIdx);
String ext = ".mp4";
File out = StringUtil.resolveConflictName(f.getParentFile(), name+ext, false);
int height = (int)Math.round(width * getSourceHeight()/(float)getSourceWidth());
height = height %2 == 0 ? height : height + 1;
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(out.getAbsolutePath(), width, height);
recorder.setFrameRate(fps);
recorder.setFormat("mp4");
recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
//recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
recorder.setVideoBitrate(recorder.getImageWidth() * recorder.getImageHeight() * fps * 10);
recorder.setVideoQuality(.1);
recorder.start();
for(int i = 0; i < frames && !saveStopped; i++) {
try {
setX(i/(float)(frames-1));
d.setProgress((i/(float)(frames-1))*.95f, "Writing frame "+i+" of " + frames);
BufferedImage frame = renderFrame(width);
BufferedImage img = new BufferedImage(frame.getWidth(), frame.getHeight(), BufferedImage.TYPE_INT_RGB);
img.getGraphics().drawImage(frame, 0, 0, null);
recorder.record(new Java2DFrameConverter().convert(img), avutil.AV_PIX_FMT_ARGB);
} catch (Exception e) {
e.printStackTrace();
}
}
d.setProgress(.98, "Finishing export...");
recorder.stop();
recorder.close();
} catch (Exception e1) {
e1.printStackTrace();
} finally {
if(onFinish != null)
SwingUtilities.invokeLater(() -> onFinish.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_FIRST, "save")));
}
}).start();
}
实例5: startRecording
import org.bytedeco.javacv.FFmpegFrameRecorder; //导入依赖的package包/类
public void startRecording() {
try {
if (recorder == null){
initRecorder(name);
}
recorder.start();
// startTime = System.currentTimeMillis();
recording = true;
// audioThread.start();
} catch (FFmpegFrameRecorder.Exception e) {
e.printStackTrace();
}
}
推荐阅读
-
Java 类加载器的作用 - 简介:类加载器是 Java™ 中一个非常重要的概念。类加载器负责将 Java 类的字节码加载到 Java 虚拟机中。本文首先详细介绍了 Java 类加载器的基本概念,包括代理模型、加载类的具体过程和线程上下文类加载器等。然后介绍了如何开发自己的类加载器,最后介绍了类加载器在 Web 容器和 OSGi™ 中的应用。 类加载器是 Java 语言的一项创新,也是 Java 语言广受欢迎的重要原因之一。它允许将 Java 类动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 开始出现,最初是为了满足 Java Applets 的需求而开发的,Java Applets 需要从远程位置下载 Java 类文件并在浏览器中执行。现在,类加载器已广泛应用于网络容器和 OSGi。一般来说,Java 应用程序的开发人员不需要直接与类加载器交互;Java 虚拟机的默认行为足以应对大多数情况。但是,如果遇到需要与类加载器交互的情况,而您又不太了解类加载器的机制,就很容易花费大量时间调试异常,如 ClassNotFoundException 和 NoClassDefFoundError。本文将详细介绍 Java 的类加载器,帮助读者深入理解 Java 语言中的这一重要概念。下面先介绍一些基本概念。 类加载器的基本概念 顾名思义,类加载器用于将 Java 类加载到 Java 虚拟机中。一般来说,Java 虚拟机以如下方式使用 Java 类:Java 源程序(.java 文件)经 Java 编译器编译后转换为 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码并将其转换为 java.lang 实例。每个实例都用来表示一个 Java 类。通过该实例的 newInstance 方法创建该类的对象。实际情况可能更加复杂,例如,Java 字节代码可能是由工具动态生成或通过网络下载的。 基本上,所有类加载器都是 java.lang.ClassLoader 类的实例。下面将详细介绍这个 Java 类。 java.lang.ClassLoader 类简介 java.lang.ClassLoader 类的基本职责是根据给定类的名称为其查找或生成相应的字节码,然后根据这些字节码定义一个 Java 类,即 java.lang.Class 类的实例。除此之外,ClassLoader 还负责加载 Java 应用程序所需的资源,如图像文件和配置文件。不过,本文只讨论它加载类的功能。为了履行加载类的职责,ClassLoader 提供了许多方法,其中比较重要的方法如表 1 所示。下文将详细介绍这些方法。 表 1.与加载类相关的 ClassLoader 方法
-
实战教程:如何在Java中使用FFmpegFrameRecorder类
-
实战!Java中ApiController类的使用教程
-
玩转Java底层:JMX详解 - jconsole与自定义MBean监控工具的实际应用与区别" 在日常JVM调优中,我们熟知的jconsole工具通过JMX包装的bean以图形化形式展示管理数据,而像jstat和jmap这类内建监控工具则由JVM直接支持。本文将以jconsole为例,深入讲解其实质——基于JMX的MBean功能,包括可视化界面上的bean属性查看和操作调用。 MBeans在jconsole中的体现是那些可观察的组件属性和方法,如上图所示,通过名为"Verbose"的属性能看到其值为false,同时还能直接操作该bean的方法,例如"closeJerryMBean"。 尽管jconsole给我们提供了直观的可视化界面,但请注意,这里的MBean并非固定不变,开发者可根据JMX提供的接口将自己的自定义bean展示到jconsole。以下步骤展示了如何创建并注册一个名为"StudyJavaMBean"的自定义MBean: 1. 首先定义接口`StudyJavaMBean`,接口需遵循MBean规范,即后缀为"MBean"且包含getter方法代表属性,如`getApplicationName`,和无返回值的setter方法代表操作,如`closeJerryMBean`。 ```java public interface StudyJavaMBean { String getApplicationName(); void closeJerryMBean(); } ``` 2. 编写接口的实现类`StudyJavaMBeanImpl`,实现接口中的方法: ```java public class StudyJavaMBeanImpl implements StudyJavaMBean { @Override public String getApplicationName() { return "每天学Java"; } @Override public void closeJerryMBean() { System.out.println("关闭Jerry应用"); } } ``` 3. 在代码中注册自定义MBean,涉及的关键步骤包括: - 获取平台MBeanServer - 定义ObjectName,指定唯一的MBean标识符 - 注册MBean到服务器 - 启动RMI连接器服务,以便jconsole能够访问 ```java public void registerMBean() throws Exception { // ... 具体实现省略 ... } ``` 实际运行注册后的MBean,您将在jconsole中发现并查看自定义bean的属性和调用相关方法。然而,这种方式相较于传统的属性/日志查看和HTTP接口,实用性相对有限,可能存在潜在的安全风险。但不可否认的是,JMX及其MBean机制对于获取操作系统信息、内存状态等关键性能指标仍然具有重要价值。例如: 1. **获取操作系统信息**:通过JMX MBean,可以直接获取到诸如CPU使用率、操作系统版本等系统级信息,这对于资源管理和优化工作具有显著帮助。
-
实战演示:如何在Java中运用JBTable类
-
实战演示:如何在Java中运用JFontChooser类
-
在Java中,如何在一个包内使用另一个包的类?
-
在Java中,如何在一个类中使用另一个类的参数?
-
实战演示:如何在Java中运用Term类