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}