Pregunta

I have a live video stream from FFMpeg, and I am having a hard time viewing the stream using my own custom Java application. Before someone tells me to use VLC or something like that I do want to use my own application. The stream I am trying to read is a H.264 encoded Mpeg-ts stream streamed over UDP. I do know how to decode the H.264 frames, but I am simply wondering about how to receive the Mpeg-ts stream.

¿Fue útil?

Solución

Jon Kittel provided a good answer, anyway in the question comments it is mentioned UNICAST communication, so Jon's code is not usable in this case. A simplified unicast receiver is provided below (credit to P. Tellenbach for the original example).

import java.io.FileOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class DatagramServer
{
   private final static int PACKETSIZE = 2048 ;

   public static void main( String args[] )
   {
    // Check the arguments
    //      if( args.length != 1 )
    //      {
    //         System.out.println( "usage: DatagramServer port" ) ;
    //         return ;
    //      }

      try
      {
         // Convert the argument to ensure that is it valid
         int port = 1234; //Integer.parseInt( args[0] ) ;
         FileOutputStream output = new FileOutputStream("testStream.ts", true);

         // Construct the socket
         DatagramSocket socket = new DatagramSocket( port ) ;

         System.out.println( "The server is ready..." ) ;

         DatagramPacket packet = new DatagramPacket( new byte[PACKETSIZE], PACKETSIZE ) ;
         for( ;; )
         {
            // Receive a packet (blocking)
            socket.receive( packet );
            try {
                output.write(packet.getData());
            } finally {
                output.close();
            }
        }  
     }catch (IOException exception) {
            exception.printStackTrace();
    }
  }
}

This client will listen for UDP stream on localhost address, port 1234, and will write each received packet into testStream.ts file. If the stream is H.264 encoded Mpeg-ts, the outputfile can be opened in any moment with a player to reproduce the video stream captured until that moment.

Otros consejos

In order the receive the multicast stream you will need to create a multicast client that has a buffer to store the video data and uses a socket that can join and listen for multicast streams.

The two properties are the multicast address (239.1.1.1) and the port (49410).

Using ffmpeg start streaming a mp4 video file to a multicast address and port.

ffmpeg -i .\mars.mp4 -c:v libx264 -c:a libmp3lame -f mpegts udp://239.1.1.1:49410

Compile and run the multiclass client which uses the MulticastSocket class to join the multicast group and listen for the UDP stream packets. We pass the buffer into the DatagramPacket object and when the socket receives the UDP packet the buffer is filled with the mpeg-ts data. Then you can copy the buffer to another part of the application to decode the data.

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;

public class Client {

    final static String INET_ADDR = "239.1.1.1";
    final static int PORT = 49410;

    public static void main(String[] args) throws UnknownHostException {
        // Get the multicast address that we are going to connect to.
        InetAddress address = InetAddress.getByName(INET_ADDR);

        // Create a buffer of bytes, which will be used to store
        // the incoming bytes containing the information from the streaming server
        byte[] buffer = new byte[256];

        // Create a new Multicast socket so we can join the multicast group
        try (MulticastSocket clientSocket = new MulticastSocket(PORT)){
            //Joint the Multicast group.
            clientSocket.joinGroup(address);

            // do an infinite loop
            while (true) {
                // Receive the information and print it.
                DatagramPacket msgPacket = new DatagramPacket(buffer, buffer.length);
                clientSocket.receive(msgPacket);

                String data = new String(buffer, 0, buffer.length);

                System.out.println("Data ->  " + data);
            }
        } catch (IOException exception) {
            exception.printStackTrace();
        }
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top