Search in sources :

Example 6 with MovieMetadatas

use of org.fagu.fmv.ffmpeg.metadatas.MovieMetadatas in project fmv by f-agu.

the class FFReducer method createCropDetectFFExecListener.

/**
 * @param logger
 * @param cropDetect
 * @param videoMetadatas
 * @return
 */
private FFExecListener createCropDetectFFExecListener(Logger logger, CropDetect cropDetect, MovieMetadatas videoMetadatas) {
    return new FFExecListener() {

        /**
         * @see org.fagu.fmv.soft.exec.FMVExecListener#eventPostExecute(org.fagu.fmv.soft.exec.FMVExecutor,
         *      org.apache.commons.exec.CommandLine, java.util.Map, org.apache.commons.exec.ExecuteResultHandler)
         */
        @Override
        public void eventPostExecute(FMVExecutor fmvExecutor, CommandLine command, Map environment, ExecuteResultHandler handler) {
            CropDetection cropDetection = cropDetect.getCropSizeDetected();
            SortedSet<CropSize> orderedCropSizes = cropDetection.getOrderedCropSizes();
            if (!orderedCropSizes.isEmpty()) {
                CropSize first = orderedCropSizes.first();
                Size size = first.toSize();
                if (!videoMetadatas.getVideoStreams().stream().anyMatch(s -> size.equals(s.size()))) {
                    logger.log("CropDetect: " + cropDetection.getTotalCount() + " lines parsed");
                    orderedCropSizes.stream().limit(10).forEach(cs -> logger.log("CropDetect: " + cs));
                    logger.log("CropDetect: Add crop filter: " + first.toCrop());
                }
            }
        }
    };
}
Also used : FFExecListener(org.fagu.fmv.ffmpeg.executor.FFExecListener) Arrays(java.util.Arrays) H264(org.fagu.fmv.ffmpeg.coder.H264) SortedSet(java.util.SortedSet) Stream(org.fagu.fmv.ffmpeg.metadatas.Stream) Duration(org.fagu.fmv.utils.time.Duration) CommandLine(org.apache.commons.exec.CommandLine) StringUtils(org.apache.commons.lang3.StringUtils) Decoders(org.fagu.fmv.ffmpeg.coder.Decoders) Size(org.fagu.fmv.utils.media.Size) ScaleMode(org.fagu.fmv.ffmpeg.filter.impl.ScaleMode) Map(java.util.Map) Formats(org.fagu.fmv.ffmpeg.format.Formats) VolumeDetected(org.fagu.fmv.ffmpeg.filter.impl.VolumeDetected) FilterComplex(org.fagu.fmv.ffmpeg.filter.FilterComplex) MovieMetadatas(org.fagu.fmv.ffmpeg.metadatas.MovieMetadatas) CommandLineUtils(org.fagu.fmv.soft.exec.CommandLineUtils) Rotation(org.fagu.fmv.utils.media.Rotation) Scale(org.fagu.fmv.ffmpeg.filter.impl.Scale) SubtitleStream(org.fagu.fmv.ffmpeg.metadatas.SubtitleStream) InputProcessor(org.fagu.fmv.ffmpeg.operation.InputProcessor) Collection(java.util.Collection) OutputProcessor(org.fagu.fmv.ffmpeg.operation.OutputProcessor) List(java.util.List) Optional(java.util.Optional) ResampleAudio(org.fagu.fmv.ffmpeg.filter.impl.ResampleAudio) VideoStream(org.fagu.fmv.ffmpeg.metadatas.VideoStream) TextProgressBar(org.fagu.fmv.textprogressbar.TextProgressBar) Libx264NotDisibleBy2FFExecFallback(org.fagu.fmv.ffmpeg.executor.fallback.Libx264NotDisibleBy2FFExecFallback) FilenameUtils(org.apache.commons.io.FilenameUtils) FFExecFallback(org.fagu.fmv.ffmpeg.executor.FFExecFallback) CropDetection(org.fagu.fmv.ffmpeg.filter.impl.CropDetection) Strict(org.fagu.fmv.ffmpeg.flags.Strict) FFExecListener(org.fagu.fmv.ffmpeg.executor.FFExecListener) OptionalInt(java.util.OptionalInt) ArrayList(java.util.ArrayList) AutoRotate(org.fagu.fmv.ffmpeg.filter.impl.AutoRotate) StreamOrder(org.fagu.fmv.mymedia.movie.StreamOrder) StringTokenizer(java.util.StringTokenizer) CropSize(org.fagu.fmv.ffmpeg.filter.impl.CropDetection.CropSize) Type(org.fagu.fmv.ffmpeg.operation.Type) FFMPEGExecutorBuilder(org.fagu.fmv.ffmpeg.executor.FFMPEGExecutorBuilder) Loggers(org.fagu.fmv.mymedia.logger.Loggers) FFExecutor(org.fagu.fmv.ffmpeg.executor.FFExecutor) FMVExecutor(org.fagu.fmv.soft.exec.FMVExecutor) IOException(java.io.IOException) Progress(org.fagu.fmv.ffmpeg.operation.Progress) FrameRate(org.fagu.fmv.ffmpeg.utils.FrameRate) FMVExecuteException(org.fagu.fmv.soft.exec.exception.FMVExecuteException) ExecuteResultHandler(org.apache.commons.exec.ExecuteResultHandler) CropDetect(org.fagu.fmv.ffmpeg.filter.impl.CropDetect) File(java.io.File) AudioStream(org.fagu.fmv.ffmpeg.metadatas.AudioStream) FFMpegProgressBar(org.fagu.fmv.ffmpeg.progressbar.FFMpegProgressBar) Logger(org.fagu.fmv.mymedia.logger.Logger) StringJoiner(java.util.StringJoiner) VolumeDetect(org.fagu.fmv.ffmpeg.filter.impl.VolumeDetect) ExecuteResultHandler(org.apache.commons.exec.ExecuteResultHandler) CropSize(org.fagu.fmv.ffmpeg.filter.impl.CropDetection.CropSize) CommandLine(org.apache.commons.exec.CommandLine) Size(org.fagu.fmv.utils.media.Size) CropSize(org.fagu.fmv.ffmpeg.filter.impl.CropDetection.CropSize) Map(java.util.Map) CropDetection(org.fagu.fmv.ffmpeg.filter.impl.CropDetection) FMVExecutor(org.fagu.fmv.soft.exec.FMVExecutor)

Example 7 with MovieMetadatas

use of org.fagu.fmv.ffmpeg.metadatas.MovieMetadatas in project fmv by f-agu.

the class FFReducer method reduceMedia.

/**
 * @see org.fagu.fmv.mymedia.reduce.Reducer#reduceMedia(java.io.File, String, Logger)
 */
@Override
public Reduced reduceMedia(File srcFile, String consolePrefixMessage, Logger logger) throws IOException {
    File destFile = null;
    boolean forceReplace = false;
    MovieMetadatas metadatas = MovieMetadatas.with(srcFile).extract();
    if (isVideo(metadatas, logger)) {
        logger.log("is video");
        if (needToReduceVideo(metadatas)) {
            destFile = getTempFile(srcFile, getVideoFormat(srcFile));
            forceReplace = reduceVideo(metadatas, srcFile, destFile, consolePrefixMessage, logger);
        } else {
            logger.log("Video already reduced by FMV");
        }
    } else if (metadatas.contains(Type.AUDIO)) {
        logger.log("is audio");
        if (needToReduceAudio(metadatas, srcFile)) {
            destFile = getTempFile(srcFile, getAudioFormat(srcFile));
            forceReplace = reduceAudio(metadatas, srcFile, destFile, "128k", consolePrefixMessage, logger);
        } else {
            logger.log("Audio already reduced by FMV");
        }
    }
    return new Reduced(destFile, forceReplace);
}
Also used : MovieMetadatas(org.fagu.fmv.ffmpeg.metadatas.MovieMetadatas) File(java.io.File)

Example 8 with MovieMetadatas

use of org.fagu.fmv.ffmpeg.metadatas.MovieMetadatas 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 MovieMetadatas

use of org.fagu.fmv.ffmpeg.metadatas.MovieMetadatas in project fmv by f-agu.

the class Bootstrap method reduce.

/**
 * @param rootFile
 * @throws IOException
 */
public void reduce(File rootFile) throws IOException {
    Logger logger = LoggerFactory.openLogger(LoggerFactory.getLogFile(rootFile, PROPERTY_LOG_FILE, PROPERTY_LOG_FILE_DEFAULT_NAME));
    AppVersion.logMyVersion(logger::log);
    logger.log("#################### Root: " + rootFile.getAbsolutePath());
    // 
    Files.walk(rootFile.toPath()).filter(// 
    p -> p.toFile().isFile()).forEach(p -> {
        logger.log("Reduce to 720p" + p);
        String extension = FilenameUtils.getExtension(p.getName(p.getNameCount() - 1).toString()).toLowerCase();
        if (!"mkv".equals(extension) && !"mp4".equals(extension)) {
            return;
        }
        File srcFile = p.toFile();
        try {
            MovieMetadatas metadatas = MovieMetadatas.with(srcFile).extract();
            if (!isUpperThan720p(metadatas, logger)) {
                return;
            }
            File destFile = new File(srcFile.getParentFile(), FilenameUtils.getBaseName(srcFile.getName()) + "-720p." + extension);
            try (org.fagu.fmv.mymedia.reduce.to720p.FFReducer reducer = new org.fagu.fmv.mymedia.reduce.to720p.FFReducer()) {
                String msg = LocalDateTime.now().format(DATE_TIME_FORMATTER) + ' ' + srcFile.getPath();
                System.out.print(msg);
                reducer.reduceVideo(metadatas, srcFile, metadatas, destFile, msg, logger);
            }
        } catch (IOException e) {
            logger.log(e);
        }
        System.out.println();
    });
    System.out.println();
}
Also used : Arrays(java.util.Arrays) Files(java.nio.file.Files) LocalDateTime(java.time.LocalDateTime) IOException(java.io.IOException) File(java.io.File) Size(org.fagu.fmv.utils.media.Size) AppVersion(org.fagu.fmv.mymedia.utils.AppVersion) Logger(org.fagu.fmv.mymedia.logger.Logger) DateTimeFormatter(java.time.format.DateTimeFormatter) VideoStream(org.fagu.fmv.ffmpeg.metadatas.VideoStream) MovieMetadatas(org.fagu.fmv.ffmpeg.metadatas.MovieMetadatas) Type(org.fagu.fmv.ffmpeg.operation.Type) FilenameUtils(org.apache.commons.io.FilenameUtils) LoggerFactory(org.fagu.fmv.mymedia.logger.LoggerFactory) IOException(java.io.IOException) Logger(org.fagu.fmv.mymedia.logger.Logger) MovieMetadatas(org.fagu.fmv.ffmpeg.metadatas.MovieMetadatas) File(java.io.File)

Example 10 with MovieMetadatas

use of org.fagu.fmv.ffmpeg.metadatas.MovieMetadatas 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

MovieMetadatas (org.fagu.fmv.ffmpeg.metadatas.MovieMetadatas)31 File (java.io.File)17 FFMPEGExecutorBuilder (org.fagu.fmv.ffmpeg.executor.FFMPEGExecutorBuilder)17 VideoStream (org.fagu.fmv.ffmpeg.metadatas.VideoStream)14 InputProcessor (org.fagu.fmv.ffmpeg.operation.InputProcessor)13 OutputProcessor (org.fagu.fmv.ffmpeg.operation.OutputProcessor)12 Stream (org.fagu.fmv.ffmpeg.metadatas.Stream)8 IOException (java.io.IOException)6 AudioStream (org.fagu.fmv.ffmpeg.metadatas.AudioStream)6 OptionalInt (java.util.OptionalInt)5 Size (org.fagu.fmv.utils.media.Size)5 StringJoiner (java.util.StringJoiner)4 SubtitleStream (org.fagu.fmv.ffmpeg.metadatas.SubtitleStream)4 Progress (org.fagu.fmv.ffmpeg.operation.Progress)4 Type (org.fagu.fmv.ffmpeg.operation.Type)4 Logger (org.fagu.fmv.mymedia.logger.Logger)4 Rotation (org.fagu.fmv.utils.media.Rotation)4 Optional (java.util.Optional)3 FilenameUtils (org.apache.commons.io.FilenameUtils)3 FFExecutor (org.fagu.fmv.ffmpeg.executor.FFExecutor)3