001package net.bramp.ffmpeg.progress; 002 003import static com.google.common.base.Preconditions.checkNotNull; 004 005import java.io.IOException; 006import java.net.DatagramSocket; 007import java.net.InetAddress; 008import java.net.SocketException; 009import java.net.URI; 010import java.net.URISyntaxException; 011import java.util.concurrent.CountDownLatch; 012 013/** Parses FFmpeg progress output over a UDP socket connection. */ 014public class UdpProgressParser extends AbstractSocketProgressParser { 015 016 final DatagramSocket socket; 017 final URI address; 018 019 /** Constructs a UDP progress parser listening on a random available port. */ 020 public UdpProgressParser(ProgressListener listener) throws SocketException, URISyntaxException { 021 this(listener, 0, InetAddress.getLoopbackAddress()); 022 } 023 024 /** Creates a new UDP progress parser bound to the given port and address. */ 025 public UdpProgressParser(ProgressListener listener, int port, InetAddress addr) 026 throws SocketException, URISyntaxException { 027 028 super(listener); 029 030 this.socket = new DatagramSocket(port, checkNotNull(addr)); 031 this.address = createUri("udp", socket.getLocalAddress(), socket.getLocalPort()); 032 033 this.socket.setBroadcast(false); 034 // this.socket.setSoTimeout(); // TODO Setup timeouts 035 } 036 037 @Override 038 public synchronized void stop() throws IOException { 039 if (socket.isClosed()) { 040 // Allow double stop, and ignore 041 return; 042 } 043 044 socket.close(); 045 super.stop(); 046 } 047 048 @Override 049 protected String getThreadName() { 050 return "UdpProgressParser"; 051 } 052 053 @Override 054 protected Runnable getRunnable(CountDownLatch startSignal) { 055 return new UdpProgressParserRunnable(parser, socket, startSignal); 056 } 057 058 @Override 059 public URI getUri() { 060 return address; 061 } 062}