Search in sources :

Example 1 with OutputProcessor

use of org.fagu.fmv.ffmpeg.operation.OutputProcessor 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 2 with OutputProcessor

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

the class MovieScriptConverter method convert.

/**
 * @see org.fagu.fmv.mymedia.classify.Converter#convert(org.fagu.fmv.media.Media,
 *      org.fagu.fmv.utils.file.FileFinder.InfosFile, java.io.File, org.fagu.fmv.mymedia.classify.ConverterListener)
 */
@Override
public void convert(Movie srcMedia, FileFinder<Movie>.InfosFile infosFile, File destFile, ConverterListener<Movie> listener) throws IOException {
    openScript();
    File srcFile = srcMedia.getFile();
    MovieMetadatas infos = srcMedia.getMetadatas();
    int audioFrequency = FFMpegUtils.minAudioSampleRate(infos, DEFAULT_AUDIO_SAMPLE_RATE);
    FFMPEGExecutorBuilder builder = FFMPEGExecutorBuilder.create();
    builder.hideBanner();
    builder.addMediaInputFile(srcFile).setMovieMetadatas(infos);
    Rotation rotation = rotateMap.get(srcFile.getName());
    if (rotation != null) {
        if (rotation != Rotation.R_0) {
            builder.filter(Rotate.create(rotation));
        }
    } else {
        builder.filter(AutoRotate.create(infos));
    }
    Size newSize = FFReducer.applyScaleIfNecessary(builder, infos, getMaxSize(), getScaleLogger(), rotation);
    writeLabel();
    script.println("rem " + (newSize.isLandscape() ? "landscape" : newSize.isPortrait() ? "portrait" : "square"));
    builder.filter(ResampleAudio.build().frequency(audioFrequency));
    Optional<VolumeDetected> findFirst = infosFile.getInfos().stream().filter(o -> o instanceof VolumeDetected).map(o -> (VolumeDetected) o).findFirst();
    if (findFirst.isPresent()) {
        VolumeDetected volumeDetected = findFirst.get();
        builder.filter(Volume.build().increaseToMax(volumeDetected));
    }
    File dest = new File(destFile.getParentFile(), FilenameUtils.getBaseName(destFile.getName()) + ".mp4");
    OutputProcessor outputProcessor = builder.addMediaOutputFile(dest);
    outputProcessor.qualityScale(0);
    Transpose.addMetadataRotate(outputProcessor, Rotation.R_0);
    outputProcessor.format("mp4");
    // outputProcessor.overwrite();
    FFExecutor<Object> executor = builder.build();
    try {
        script.println("if exist \"" + dest.getPath() + "\" goto :movie_" + currentVideo);
        script.println("echo.");
        script.println("echo Frame: " + infos.getVideoStream().countEstimateFrames().getAsInt());
        script.println(executor.getCommandLine());
        script.println();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
Also used : FFReducer(org.fagu.fmv.mymedia.reduce.FFReducer) HashMap(java.util.HashMap) Size(org.fagu.fmv.utils.media.Size) AutoRotate(org.fagu.fmv.ffmpeg.filter.impl.AutoRotate) ConverterListener(org.fagu.fmv.mymedia.classify.ConverterListener) Map(java.util.Map) VolumeDetected(org.fagu.fmv.ffmpeg.filter.impl.VolumeDetected) MovieMetadatas(org.fagu.fmv.ffmpeg.metadatas.MovieMetadatas) FFMPEGExecutorBuilder(org.fagu.fmv.ffmpeg.executor.FFMPEGExecutorBuilder) PrintStream(java.io.PrintStream) Rotation(org.fagu.fmv.utils.media.Rotation) Rotate(org.fagu.fmv.ffmpeg.filter.impl.Rotate) FileFinder(org.fagu.fmv.utils.file.FileFinder) FFMpegUtils(org.fagu.fmv.ffmpeg.FFMpegUtils) FFExecutor(org.fagu.fmv.ffmpeg.executor.FFExecutor) OutputProcessor(org.fagu.fmv.ffmpeg.operation.OutputProcessor) IOException(java.io.IOException) File(java.io.File) Volume(org.fagu.fmv.ffmpeg.filter.impl.Volume) Transpose(org.fagu.fmv.ffmpeg.filter.impl.Transpose) Logger(org.fagu.fmv.mymedia.logger.Logger) Optional(java.util.Optional) ResampleAudio(org.fagu.fmv.ffmpeg.filter.impl.ResampleAudio) Converter(org.fagu.fmv.mymedia.classify.Converter) FilenameUtils(org.apache.commons.io.FilenameUtils) FFMPEGExecutorBuilder(org.fagu.fmv.ffmpeg.executor.FFMPEGExecutorBuilder) Size(org.fagu.fmv.utils.media.Size) IOException(java.io.IOException) Rotation(org.fagu.fmv.utils.media.Rotation) MovieMetadatas(org.fagu.fmv.ffmpeg.metadatas.MovieMetadatas) OutputProcessor(org.fagu.fmv.ffmpeg.operation.OutputProcessor) File(java.io.File) VolumeDetected(org.fagu.fmv.ffmpeg.filter.impl.VolumeDetected)

Example 3 with OutputProcessor

use of org.fagu.fmv.ffmpeg.operation.OutputProcessor 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 4 with OutputProcessor

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

the class Reducer method reduce.

public void reduce(File srcFile, File destFile, Logo logo) throws IOException {
    int crf = (int) (getCRF(srcFile).orElse(26));
    FFMPEGExecutorBuilder builder = FFMPEGExecutorBuilder.create();
    builder.hideBanner();
    builder.addMediaInputFile(srcFile);
    if (logo != null) {
        Delogo delogo = logo.generateFilter().show(true);
        builder.filter(delogo);
    }
    OutputProcessor outputProcessor = builder.addMediaOutputFile(destFile);
    outputProcessor.qualityScale(0);
    outputProcessor.duration(Duration.valueOf(60));
    outputProcessor.codec(H264.findRecommanded().strict(Strict.EXPERIMENTAL).quality(crf));
    outputProcessor.overwrite();
    FFExecutor<Object> executor = builder.build();
    executor.execute();
}
Also used : FFMPEGExecutorBuilder(org.fagu.fmv.ffmpeg.executor.FFMPEGExecutorBuilder) Delogo(org.fagu.fmv.ffmpeg.filter.impl.Delogo) OutputProcessor(org.fagu.fmv.ffmpeg.operation.OutputProcessor)

Example 5 with OutputProcessor

use of org.fagu.fmv.ffmpeg.operation.OutputProcessor 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)

Aggregations

OutputProcessor (org.fagu.fmv.ffmpeg.operation.OutputProcessor)23 FFMPEGExecutorBuilder (org.fagu.fmv.ffmpeg.executor.FFMPEGExecutorBuilder)19 InputProcessor (org.fagu.fmv.ffmpeg.operation.InputProcessor)13 MovieMetadatas (org.fagu.fmv.ffmpeg.metadatas.MovieMetadatas)11 File (java.io.File)7 FilterComplex (org.fagu.fmv.ffmpeg.filter.FilterComplex)5 VideoStream (org.fagu.fmv.ffmpeg.metadatas.VideoStream)5 Stream (org.fagu.fmv.ffmpeg.metadatas.Stream)4 Duration (org.fagu.fmv.utils.time.Duration)4 OptionalInt (java.util.OptionalInt)3 AudioStream (org.fagu.fmv.ffmpeg.metadatas.AudioStream)3 SubtitleStream (org.fagu.fmv.ffmpeg.metadatas.SubtitleStream)3 MediaOutput (org.fagu.fmv.ffmpeg.operation.MediaOutput)3 Progress (org.fagu.fmv.ffmpeg.operation.Progress)3 IOException (java.io.IOException)2 StringJoiner (java.util.StringJoiner)2 Executable (org.fagu.fmv.core.exec.Executable)2 Source (org.fagu.fmv.core.exec.Source)2 AudioGenerator (org.fagu.fmv.ffmpeg.filter.impl.AudioGenerator)2 MixAudioDuration (org.fagu.fmv.ffmpeg.filter.impl.AudioMix.MixAudioDuration)2