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}