Search in sources :

Example 6 with InputProcessor

use of org.fagu.fmv.ffmpeg.operation.InputProcessor in project fmv by f-agu.

the class FFMPEGExecutorBuilderTestCase method testInputProcessor_format.

/**
 */
@Test
public void testInputProcessor_format() {
    MediaInput input = mockInput("/path/file");
    InputProcessor inputProcessor = ffmpegExecutorBuilder.addMediaInput(input);
    inputProcessor.format("forMAT");
    assertArgs("-f", "forMAT", "-i", "/path/file");
}
Also used : InputProcessor(org.fagu.fmv.ffmpeg.operation.InputProcessor) MediaInput(org.fagu.fmv.ffmpeg.operation.MediaInput) Test(org.junit.Test)

Example 7 with InputProcessor

use of org.fagu.fmv.ffmpeg.operation.InputProcessor in project fmv by f-agu.

the class Reduce method doIt.

/**
 * @param sourceFile
 * @throws IOException
 */
private static void doIt(File sourceFile) throws IOException {
    String extension = FilenameUtils.getExtension(sourceFile.getName()).toLowerCase();
    if (!"mkv".equals(extension)) {
        extension = "mp4";
    }
    File destinationFile = new File(sourceFile.getParentFile(), FilenameUtils.getBaseName(sourceFile.getName()) + "-new." + extension);
    FFMPEGExecutorBuilder builder = FFMPEGExecutorBuilder.create();
    builder.hideBanner();
    InputProcessor inputProcessor = builder.addMediaInputFile(sourceFile);
    MovieMetadatas videoMetadatas = inputProcessor.getMovieMetadatas();
    boolean doVideo = !videoMetadatas.getVideoStream().isTreatedByFMV();
    boolean doAudio = doVideo;
    Collection<AudioStream> audioStreams = StreamOrder.sort(videoMetadatas.getAudioStreams());
    for (AudioStream audioStream : audioStreams) {
        if ("vorbis".equals(audioStream.codecName().get())) {
            doAudio |= true;
            break;
        }
        if ("aac".equals(audioStream.codecName().get())) {
            doAudio = false;
            break;
        }
    }
    if (!doVideo && !doAudio) {
        return;
    }
    OutputProcessor outputProcessor = builder.addMediaOutputFile(destinationFile);
    outputProcessor.qualityScale(0);
    // video
    for (Stream stream : videoMetadatas.getVideoStreams()) {
        outputProcessor.map().streams(stream).input(inputProcessor);
    }
    // audio
    for (Stream stream : audioStreams) {
        outputProcessor.map().streams(stream).input(inputProcessor);
    }
    // subtitle
    Collection<SubtitleStream> subtitleStreams = StreamOrder.sort(videoMetadatas.getSubtitleStreams());
    for (Stream stream : subtitleStreams) {
        outputProcessor.map().streams(stream).input(inputProcessor);
    }
    // other stream
    for (Stream stream : videoMetadatas.getStreams()) {
        Type type = stream.type();
        if (type != Type.AUDIO && type != Type.VIDEO && type != Type.SUBTITLE) {
            outputProcessor.map().streams(stream).input(inputProcessor);
        }
    }
    // ------------------------ disposition default ------------------------
    // 
    int count = 0;
    for (Stream stream : audioStreams) {
        boolean beDefault = count == 1;
        if (stream.isDefaultStream() != beDefault) {
            outputProcessor.metadataStream(Type.AUDIO, count, "disposition:default", beDefault ? "1" : "0");
        }
        ++count;
    }
    count = 0;
    for (Stream stream : subtitleStreams) {
        boolean beDefault = count == 1;
        if (stream.isDefaultStream() != beDefault) {
            outputProcessor.metadataStream(Type.SUBTITLE, count, "disposition:default", beDefault ? "1" : "0");
        }
        ++count;
    }
    // video
    if (doVideo) {
        outputProcessor.codec(H264.findRecommanded().strict(Strict.EXPERIMENTAL).quality(23));
    } else {
        outputProcessor.codecCopy(Type.VIDEO);
    }
    // audio
    if (doAudio) {
        outputProcessor.codecAutoSelectAAC();
    } else {
        outputProcessor.codecCopy(Type.AUDIO);
    }
    // subtitle
    if (videoMetadatas.contains(Type.SUBTITLE)) {
        outputProcessor.codecCopy(Type.SUBTITLE);
    }
    // outputProcessor.overwrite();
    FFExecutor<Object> executor = builder.build();
    System.out.println(executor.getCommandLine());
}
Also used : FFMPEGExecutorBuilder(org.fagu.fmv.ffmpeg.executor.FFMPEGExecutorBuilder) SubtitleStream(org.fagu.fmv.ffmpeg.metadatas.SubtitleStream) InputProcessor(org.fagu.fmv.ffmpeg.operation.InputProcessor) AudioStream(org.fagu.fmv.ffmpeg.metadatas.AudioStream) Type(org.fagu.fmv.ffmpeg.operation.Type) MovieMetadatas(org.fagu.fmv.ffmpeg.metadatas.MovieMetadatas) OutputProcessor(org.fagu.fmv.ffmpeg.operation.OutputProcessor) SubtitleStream(org.fagu.fmv.ffmpeg.metadatas.SubtitleStream) Stream(org.fagu.fmv.ffmpeg.metadatas.Stream) AudioStream(org.fagu.fmv.ffmpeg.metadatas.AudioStream) File(java.io.File)

Example 8 with InputProcessor

use of org.fagu.fmv.ffmpeg.operation.InputProcessor in project fmv by f-agu.

the class FFReducer method reduceVideo.

/**
 * @param metadatas
 * @param srcFile
 * @param movieMetadatas
 * @param destFile
 * @param consolePrefixMessage
 * @param logger
 * @throws IOException
 */
private boolean reduceVideo(MovieMetadatas metadatas, File srcFile, File destFile, String consolePrefixMessage, Logger logger) throws IOException {
    AudioStream audioStream = metadatas.getAudioStream();
    boolean audioCodecCopy = audioStream.isCodec(Formats.AC3);
    FFMPEGExecutorBuilder builder = FFMPEGExecutorBuilder.create();
    builder.hideBanner();
    InputProcessor inputProcessor = builder.addMediaInputFile(srcFile);
    builder.filter(AutoRotate.create(metadatas));
    applyScaleIfNecessary(builder, metadatas, getMaxSize(), logger);
    VolumeDetect volumeDetect = null;
    if (!audioCodecCopy) {
        volumeDetect = VolumeDetect.build();
        builder.filter(volumeDetect);
    }
    CropDetect cropDetect = CropDetect.build();
    builder.filter(cropDetect);
    MovieMetadatas videoMetadatas = inputProcessor.getMovieMetadatas();
    Collection<AudioStream> audioStreams = StreamOrder.sort(videoMetadatas.getAudioStreams());
    OutputProcessor outputProcessor = builder.addMediaOutputFile(destFile);
    outputProcessor.qualityScale(0);
    // video
    for (Stream stream : videoMetadatas.getVideoStreams()) {
        logger.log("map[" + stream.index() + "] video: " + stream);
        outputProcessor.map().streams(stream).input(inputProcessor);
    }
    // audio
    for (Stream stream : audioStreams) {
        logger.log("map[" + stream.index() + "] audio: " + stream);
        outputProcessor.map().streams(stream).input(inputProcessor);
    }
    // subtitle
    Collection<SubtitleStream> subtitleStreams = StreamOrder.sort(videoMetadatas.getSubtitleStreams());
    for (Stream stream : subtitleStreams) {
        logger.log("map[" + stream.index() + "] subtitle: " + stream);
        outputProcessor.map().streams(stream).input(inputProcessor);
    }
    // other stream (Apple... again bullshit)
    // for (Stream stream : videoMetadatas.getStreams()) {
    // Type type = stream.type();
    // if (type != Type.AUDIO && type != Type.VIDEO && type != Type.SUBTITLE) {
    // logger.log("map other stream: " + stream);
    // outputProcessor.map().streams(stream).input(inputProcessor);
    // }
    // }
    // -------------------------- codec -------------------------
    outputProcessor.codec(H264.findRecommanded().strict(Strict.EXPERIMENTAL).quality(crf));
    // audio
    if (audioCodecCopy) {
        logger.log("Audio: AC3, copy");
        outputProcessor.codecCopy(Type.AUDIO);
    } else {
        logger.log("Audio: force AAC");
        outputProcessor.codecAutoSelectAAC();
    }
    // subtitle
    if (videoMetadatas.contains(Type.SUBTITLE)) {
        outputProcessor.codecCopy(Type.SUBTITLE);
    }
    outputProcessor.overwrite();
    FFExecutor<Object> executor = builder.build();
    executor.addListener(createLogFFExecListener(logger));
    executor.addListener(createCropDetectFFExecListener(logger, cropDetect, videoMetadatas));
    if (!audioCodecCopy) {
        executor.addListener(createVolumeDetectFFExecListener(logger, volumeDetect));
    }
    VideoStream videoStream = metadatas.getVideoStream();
    OptionalInt countEstimateFrames = videoStream.countEstimateFrames();
    Progress progress = executor.getProgress();
    if (countEstimateFrames.isPresent() && progress != null) {
        textProgressBar = FFMpegProgressBar.with(progress).byFrame(countEstimateFrames.getAsInt()).fileSize(srcFile.length()).build().makeBar(consolePrefixMessage);
    } else {
        StringJoiner joiner = new StringJoiner(", ");
        if (progress == null) {
            joiner.add("progress not found");
        }
        if (!countEstimateFrames.isPresent()) {
            joiner.add("nb frames nout found");
        }
        logger.log("No progress bar: " + joiner.toString());
    }
    executor.execute();
    Optional<String> codecName = videoStream.codecName();
    if (codecName.isPresent() && codecName.get().equalsIgnoreCase(Formats.HEVC.getName())) {
        // h265
        return true;
    }
    return false;
}
Also used : FFMPEGExecutorBuilder(org.fagu.fmv.ffmpeg.executor.FFMPEGExecutorBuilder) Progress(org.fagu.fmv.ffmpeg.operation.Progress) VolumeDetect(org.fagu.fmv.ffmpeg.filter.impl.VolumeDetect) SubtitleStream(org.fagu.fmv.ffmpeg.metadatas.SubtitleStream) VideoStream(org.fagu.fmv.ffmpeg.metadatas.VideoStream) InputProcessor(org.fagu.fmv.ffmpeg.operation.InputProcessor) OptionalInt(java.util.OptionalInt) CropDetect(org.fagu.fmv.ffmpeg.filter.impl.CropDetect) AudioStream(org.fagu.fmv.ffmpeg.metadatas.AudioStream) MovieMetadatas(org.fagu.fmv.ffmpeg.metadatas.MovieMetadatas) OutputProcessor(org.fagu.fmv.ffmpeg.operation.OutputProcessor) Stream(org.fagu.fmv.ffmpeg.metadatas.Stream) SubtitleStream(org.fagu.fmv.ffmpeg.metadatas.SubtitleStream) VideoStream(org.fagu.fmv.ffmpeg.metadatas.VideoStream) AudioStream(org.fagu.fmv.ffmpeg.metadatas.AudioStream) StringJoiner(java.util.StringJoiner)

Example 9 with InputProcessor

use of org.fagu.fmv.ffmpeg.operation.InputProcessor in project fmv by f-agu.

the class Ripper method encode.

/**
 * @param vobFile
 * @param mp4File
 * @param mPlayerDump
 * @param progressEncode
 * @throws IOException
 */
private void encode(File vobFile, File mp4File, MPlayerDump mPlayerDump, AtomicInteger progressEncode, AtomicInteger currentEncoding, CountDownLatch encodingLatch) throws IOException {
    FFMPEGExecutorBuilder builder = ffMPEGExecutorBuilderSupplier.get();
    builder.hideBanner();
    InputProcessor inputProcessor = builder.addMediaInputFile(vobFile);
    MovieMetadatas movieMetadatas = inputProcessor.getMovieMetadatas();
    OutputProcessor outputProcessor = builder.addMediaOutputFile(mp4File);
    // video
    for (VideoStream stream : movieMetadatas.getVideoStreams()) {
        outputProcessor.map().streams(stream).input(inputProcessor);
    }
    // audio
    filterAndMap(inputProcessor, outputProcessor, movieMetadatas.getAudioStreams().iterator(), mPlayerDump.getAudioStreams());
    // subtitle
    filterAndMap(inputProcessor, outputProcessor, movieMetadatas.getSubtitleStreams().iterator(), mPlayerDump.getSubtitles());
    outputProcessor.codec(H264.findRecommanded().strict(Strict.EXPERIMENTAL).quality(21)).overwrite();
    int nbFrames = 0;
    OptionalInt countEstimateFrames = movieMetadatas.getVideoStream().countEstimateFrames();
    if (countEstimateFrames.isPresent()) {
        nbFrames = countEstimateFrames.getAsInt();
    } else {
    // TODO
    }
    builder.progressReadLine(new FFMpegProgress(progressEncode, nbFrames));
    FFExecutor<Object> executor = builder.build();
    logger.log(executor.getCommandLine());
    ffmpegService.submit(() -> {
        try {
            currentEncoding.incrementAndGet();
            executor.execute();
        } catch (Exception e) {
            logger.log(e);
        } finally {
            encodingLatch.countDown();
            vobFile.delete();
        }
    });
}
Also used : FFMPEGExecutorBuilder(org.fagu.fmv.ffmpeg.executor.FFMPEGExecutorBuilder) MovieMetadatas(org.fagu.fmv.ffmpeg.metadatas.MovieMetadatas) VideoStream(org.fagu.fmv.ffmpeg.metadatas.VideoStream) OutputProcessor(org.fagu.fmv.ffmpeg.operation.OutputProcessor) InputProcessor(org.fagu.fmv.ffmpeg.operation.InputProcessor) MutableObject(org.apache.commons.lang3.mutable.MutableObject) OptionalInt(java.util.OptionalInt) IOException(java.io.IOException)

Example 10 with InputProcessor

use of org.fagu.fmv.ffmpeg.operation.InputProcessor in project fmv by f-agu.

the class Test method concatFade1.

public static void concatFade1(File in1VideoFile, File in2VideoFile, Duration fadeDuration, File outFile) throws IOException {
    FFMPEGExecutorBuilder builder = FFMPEGExecutorBuilder.create();
    InputProcessor video1InputProcessor = builder.addMediaInputFile(in1VideoFile);
    InputProcessor video2InputProcessor = builder.addMediaInputFile(in2VideoFile);
    VideoStream videoStream1 = video1InputProcessor.getMovieMetadatas().getVideoStream();
    VideoStream videoStream2 = video2InputProcessor.getMovieMetadatas().getVideoStream();
    Time startTime_T1 = Time.valueOf(videoStream1.duration().get().toSeconds() - fadeDuration.toSeconds());
    Duration duration_0_T1 = Duration.valueOf(startTime_T1.toSeconds());
    Time startTime_T2 = Time.valueOf(videoStream2.duration().get().toSeconds() - fadeDuration.toSeconds());
    Duration duration_T2_END = Duration.valueOf(startTime_T2.toSeconds());
    // source 1
    NullSourceVideo nullSourceVideo1 = NullSourceVideo.build().size(videoStream1.size()).duration(duration_T2_END);
    AudioGenerator audioGenerator1 = AudioGenerator.build().silence().duration(duration_T2_END);
    Concat concat1 = Concat.create(builder, video1InputProcessor, FilterComplex.create(nullSourceVideo1), FilterComplex.create(audioGenerator1));
    FilterComplex fadeAudio1 = FilterComplex.create(FadeAudio.out().startTime(startTime_T1).duration(fadeDuration)).addInput(concat1);
    // source 2
    NullSourceVideo nullSourceVideo2 = NullSourceVideo.build().size(videoStream2.size()).duration(duration_0_T1);
    AudioGenerator audioGenerator2 = AudioGenerator.build().silence().duration(duration_0_T1);
    Concat concat2 = Concat.create(builder, FilterComplex.create(nullSourceVideo2), FilterComplex.create(audioGenerator2), video2InputProcessor);
    FilterComplex fadeAudio2 = FilterComplex.create(FadeAudio.in().startTime(startTime_T1).duration(fadeDuration)).addInput(concat2);
    // blend for fade / merge
    // video
    SetSAR setSAR = SetSAR.toRatio("1");
    Format formatRGBA = Format.with(PixelFormat.RGBA);
    FilterComplex vfc1 = FilterComplex.create(setSAR, formatRGBA).addInput(concat1);
    FilterComplex vfc2 = FilterComplex.create(setSAR, formatRGBA).addInput(concat2);
    Blend blend = Blend.build().mode(Mode.ADDITION).repeatLast(true).opacity(1).exprFade(startTime_T1, fadeDuration);
    Format formatYUV = Format.with(PixelFormat.YUVA422P10LE);
    FilterComplex vfcBlend = FilterComplex.create(blend, formatYUV).addInput(vfc1).addInput(vfc2);
    builder.filter(vfcBlend);
    // audio
    FilterComplex audioMix = AudioMix.build().duration(MixAudioDuration.SHORTEST).addInput(fadeAudio1).addInput(fadeAudio2);
    builder.filter(audioMix);
    // out
    OutputProcessor outputProcessor = builder.addMediaOutputFile(outFile);
    outputProcessor.overwrite();
    FFExecutor<Object> executor = builder.build();
    System.out.println(executor.getCommandLine());
    FilterGraphUI.show(builder.getFFMPEGOperation());
// executor.execute();
}
Also used : FilterComplex(org.fagu.fmv.ffmpeg.filter.FilterComplex) FFMPEGExecutorBuilder(org.fagu.fmv.ffmpeg.executor.FFMPEGExecutorBuilder) SetSAR(org.fagu.fmv.ffmpeg.filter.impl.SetSAR) Blend(org.fagu.fmv.ffmpeg.filter.impl.Blend) VideoStream(org.fagu.fmv.ffmpeg.metadatas.VideoStream) InputProcessor(org.fagu.fmv.ffmpeg.operation.InputProcessor) Time(org.fagu.fmv.utils.time.Time) MixAudioDuration(org.fagu.fmv.ffmpeg.filter.impl.AudioMix.MixAudioDuration) Duration(org.fagu.fmv.utils.time.Duration) Concat(org.fagu.fmv.ffmpeg.filter.impl.Concat) NullSourceVideo(org.fagu.fmv.ffmpeg.filter.impl.NullSourceVideo) PixelFormat(org.fagu.fmv.ffmpeg.utils.PixelFormat) Format(org.fagu.fmv.ffmpeg.filter.impl.Format) AudioGenerator(org.fagu.fmv.ffmpeg.filter.impl.AudioGenerator) OutputProcessor(org.fagu.fmv.ffmpeg.operation.OutputProcessor)

Aggregations

InputProcessor (org.fagu.fmv.ffmpeg.operation.InputProcessor)43 FFMPEGExecutorBuilder (org.fagu.fmv.ffmpeg.executor.FFMPEGExecutorBuilder)27 OutputProcessor (org.fagu.fmv.ffmpeg.operation.OutputProcessor)13 MovieMetadatas (org.fagu.fmv.ffmpeg.metadatas.MovieMetadatas)12 FilterComplex (org.fagu.fmv.ffmpeg.filter.FilterComplex)11 MediaInput (org.fagu.fmv.ffmpeg.operation.MediaInput)11 VideoStream (org.fagu.fmv.ffmpeg.metadatas.VideoStream)9 File (java.io.File)8 FilterInput (org.fagu.fmv.ffmpeg.filter.FilterInput)6 Test (org.junit.Test)6 NullSourceVideo (org.fagu.fmv.ffmpeg.filter.impl.NullSourceVideo)5 Duration (org.fagu.fmv.utils.time.Duration)5 Time (org.fagu.fmv.utils.time.Time)5 AudioGenerator (org.fagu.fmv.ffmpeg.filter.impl.AudioGenerator)4 MixAudioDuration (org.fagu.fmv.ffmpeg.filter.impl.AudioMix.MixAudioDuration)4 Blend (org.fagu.fmv.ffmpeg.filter.impl.Blend)4 Concat (org.fagu.fmv.ffmpeg.filter.impl.Concat)4 Format (org.fagu.fmv.ffmpeg.filter.impl.Format)4 SetSAR (org.fagu.fmv.ffmpeg.filter.impl.SetSAR)4 PixelFormat (org.fagu.fmv.ffmpeg.utils.PixelFormat)4