001package net.bramp.ffmpeg.job;
002
003import static com.google.common.base.Preconditions.checkNotNull;
004
005import com.google.common.base.Throwables;
006import java.io.IOException;
007import java.nio.file.DirectoryStream;
008import java.nio.file.Files;
009import java.nio.file.Path;
010import java.nio.file.Paths;
011import java.util.List;
012import java.util.UUID;
013import javax.annotation.Nullable;
014import net.bramp.ffmpeg.FFmpeg;
015import net.bramp.ffmpeg.builder.FFmpegBuilder;
016import net.bramp.ffmpeg.progress.ProgressListener;
017
018public class TwoPassFFmpegJob extends FFmpegJob {
019
020  final String passlogPrefix;
021  final FFmpegBuilder builder;
022
023  public TwoPassFFmpegJob(FFmpeg ffmpeg, FFmpegBuilder builder) {
024    this(ffmpeg, builder, null);
025  }
026
027  public TwoPassFFmpegJob(
028      FFmpeg ffmpeg, FFmpegBuilder builder, @Nullable ProgressListener listener) {
029    super(ffmpeg, listener);
030
031    // Random prefix so multiple runs don't clash
032    this.passlogPrefix = UUID.randomUUID().toString();
033    this.builder = checkNotNull(builder).setPassPrefix(passlogPrefix);
034
035    // Build the args now (but throw away the results). This allows the illegal arguments to be
036    // caught early, but also allows the ffmpeg command to actually alter the arguments when
037    // running.
038    List<String> unused = this.builder.setPass(1).build();
039  }
040
041  protected void deletePassLog() throws IOException {
042    final Path cwd = Paths.get("");
043    try (DirectoryStream<Path> stream = Files.newDirectoryStream(cwd, passlogPrefix + "*.log*")) {
044      for (Path p : stream) {
045        Files.deleteIfExists(p);
046      }
047    }
048  }
049
050  @Override
051  public void run() {
052    state = State.RUNNING;
053
054    try {
055      try {
056        // Two pass
057        final boolean override = builder.getOverrideOutputFiles();
058
059        FFmpegBuilder b1 = builder.setPass(1).overrideOutputFiles(true);
060        ffmpeg.run(b1, listener);
061
062        FFmpegBuilder b2 = builder.setPass(2).overrideOutputFiles(override);
063        ffmpeg.run(b2, listener);
064
065      } finally {
066        deletePassLog();
067      }
068      state = State.FINISHED;
069
070    } catch (Throwable t) {
071      state = State.FAILED;
072
073      Throwables.throwIfUnchecked(t);
074      throw new RuntimeException(t);
075    }
076  }
077}