简体   繁体   English

使用ffmpeg为JavaFX MediaPlayer生成视频

[英]Generate video with ffmpeg for JavaFX MediaPlayer

I'm trying to use ffmpeg for generating a video file from timelapse images. 我正在尝试使用ffmpeg从游戏中时光倒流图像生成视频文件。 Somehow I didn't find out which codec resp. 我不知何故找不到哪个编解码器。 which parameters I have to use in ffmpeg, that the video file is playable with JavaFX's MediaPlayer . 我必须在ffmpeg中使用哪些参数,才能使用JavaFX的MediaPlayer播放视频文件。 I tried these codecs: 我尝试了以下编解码器:

  • libx264 ( ffmpeg -f image2 -i %05d.jpg -r 30 -filter:v crop=4000:2250:0:0 -s 1920x1080 -vcodec libx264 -preset ultrafast -qp 0 Timelapse3.mp4 ) libx264ffmpeg -f image2 -i %05d.jpg -r 30 -filter:v crop=4000:2250:0:0 -s 1920x1080 -vcodec libx264 -preset ultrafast -qp 0 Timelapse3.mp4
  • mpeg4 ( ffmpeg -f image2 -i %05d.jpg -r 30 -filter:v crop=4000:2250:0:0 -s 1920x1080 -vcodec mpeg4 -qscale 1 ../Timelapse.avi ) mpeg4ffmpeg -f image2 -i %05d.jpg -r 30 -filter:v crop=4000:2250:0:0 -s 1920x1080 -vcodec mpeg4 -qscale 1 ../Timelapse.avi

But they didn't work with JavaFX. 但是它们不适用于JavaFX。 What codec and parameter do I have to use for a high quality output? 高质量输出必须使用什么编解码器和参数?

The following worked for me if I have an input as mp4 (but it should work accordingly with other input formats, as in your case the image timelapse): 如果我输入的内容为mp4,以下内容对我有用(但它应与其他输入格式相对应,例如您的图像时移):

ffmpeg -i input.mp4 -vcodec h264 -vf scale=1920x1080 -an -pix_fmt yuv420p output.mp4

So the important parts are: 因此重要的部分是:

  • changing the pix_fmt . 更改pix_fmt Apparently the default one is not supported. 显然,不支持默认值。
  • and the resolution seems to be only working if it is lower than or equal to 1920x1080 并且分辨率似乎只有在小于或等于1920x1080时才有效
  • I don't need audio in my case! 我不需要音频! (if you need audio remove the -an or replace with working audio codec conversion) (如果需要音频,请删除-an或将其替换为有效的音频编解码器转换)

The avi container format isn't supported by JavaFX so won't work - your first example should however play ball ok - I've tried it and it works for me. JavaFX不支持avi容器格式,因此无法正常工作-您的第一个示例应该可以正常运行-我已经尝试过了,并且对我有用。

You could also try forcing the mp4 container with the same f switch but just before the output file: 您也可以尝试使用相同的f开关但仅在输出文件之前强制mp4容器:

ffmpeg -f image2 -i %05d.jpg -r 30 -filter:v crop=4000:2250:0:0 -s 1920x1080 -vcodec mpeg4 -qscale 1 -f mp4 ../Timelapse.mp4

(Also try the above with libx264.) (也可以使用libx264尝试上述方法。)

Try this 尝试这个

Replace the file name in the quotes with your file name. 用您的文件名替换引号中的文件名。 The file name numbering should start with 0 then go to 1, 2, 3, 4 and so on 文件名编号应以0开头,然后转到1、2、3、4,依此类推

This is how my file names look 这是我的文件名的样子

Mandibular hollow 1 micron.gizmofill0.gizmoslice.jpg 下颌空心1 micron.gizmofill0.gizmoslice.jpg

Mandibular hollow 1 micron.gizmofill17.gizmoslice.jpg 下颌空心1 micron.gizmofill17.gizmoslice.jpg

Mandibular hollow 1 micron.gizmofill16994.gizmoslice.jpg 下颌骨空心1 micron.gizmofill16994.gizmoslice.jpg

My files range between 198kb and 47kb in size. 我的文件大小在198kb至47kb之间。 I have about 18500 files. 我有大约18500个文件。 All the files combined are about 2.9GB. 所有文件合计约为2.9GB。 This will generate a movie file at 50 frames per second that is around 25MB 这将以每秒50帧的速度生成大约25MB的电影文件

ffmpeg -framerate 50 -i "Mandibular hollow 1 micron.gizmofill%d.gizmoslice.jpg" -s 1638x1004 -c:v libx264 -pix_fmt yuv420p output.mp4 ffmpeg -framerate 50 -i“下颌骨空心1 micron.gizmofill%d.gizmoslice.jpg” -s 1638x1004 -c:v libx264 -pix_fmt yuv420p output.mp4

This controller code works for me 该控制器代码对我有用

package javafxapplication13;

import java.io.File;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;

/**
 *
 * @author kobus
 */
public class FXMLDocumentController implements Initializable {

    @FXML
    private MediaView mediaView;

    @FXML
    private void handleButtonAction(ActionEvent event) {
        final File f = new File("C:/Users/kobus/Dropbox/JavaProjects/Gizmetor/temp/output.mp4");

        Media media = new Media(f.toURI().toString());
        MediaPlayer mediaPlayer = new MediaPlayer(media);
        mediaPlayer.setAutoPlay(true);

        mediaPlayer.play();
        mediaView.setMediaPlayer(mediaPlayer);
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    }
}

This is the .fxml file 这是.fxml文件

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.media.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication13.FXMLDocumentController">
    <children>
        <Button fx:id="button" layoutX="126" layoutY="90" onAction="#handleButtonAction" text="Click Me!" />
        <Label fx:id="label" layoutX="126" layoutY="120" minHeight="16" minWidth="69" />
      <MediaView fx:id="mediaView" fitHeight="1005.0" fitWidth="1638.0" layoutX="14.0" layoutY="165.0" />
    </children>
</AnchorPane>

Here is the application file 这是申请文件

package javafxapplication13;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

/**
 *
 * @author kobus
 */
public class JavaFXApplication13 extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));

        Scene scene = new Scene(root);

        stage.setScene(scene);
        stage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM