【问题标题】:How to receive Mpeg-ts stream over UDP from FFMpeg in Java如何在 Java 中通过 UDP 从 FFMpeg 接收 Mpeg-ts 流
【发布时间】:2014-02-20 14:48:13
【问题描述】:

我有一个来自 FFMpeg 的实时视频流,但我很难使用我自己的自定义 Java 应用程序查看该流。在有人告诉我使用 VLC 或类似的东西之前,我确实想使用我自己的应用程序。我试图读取的流是通过 UDP 流式传输的 H.264 编码的 Mpeg-ts 流。我确实知道如何解码 H.264 帧,但我只是想知道如何接收 Mpeg-ts 流。

【问题讨论】:

  • 多播还是单播?
  • 对不起,我忘了说,单播。
  • 那么发送数据的设备必须配置为发送到特定的 ip/port。只需打开端口并读取数据包即可。

标签: java ffmpeg udp mpeg2-ts


【解决方案1】:

Jon Kittel 提供了一个很好的答案,无论如何在问题 cmets 中提到了 UNICAST 通信,因此 Jon 的代码在这种情况下不可用。 下面提供了一个简化的单播接收器(原始示例归功于P. Tellenbach)。

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();
    }
  }
}

此客户端将在 localhost 地址、端口 1234 上侦听 UDP 流,并将每个接收到的数据包写入 testStream.ts 文件。 如果流是 H.264 编码的 Mpeg-ts,则可以在任何时候用播放器打开输出文件,以重现在那之前捕获的视频流。

【讨论】:

    【解决方案2】:

    为了接收多播流,您需要创建一个多播客户端,它有一个缓冲区来存储视频数据,并使用一个可以加入和侦听多播流的套接字。

    这两个属性是多播地址 (239.1.1.1) 和端口 (49410)。

    使用 ffmpeg 开始将 mp4 视频文件流式传输到多播地址和端口。

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

    编译并运行使用MulticastSocket类的多类客户端加入多播组并监听UDP流数据包。我们将缓冲区传递给DatagramPacket 对象,当套接字接收到 UDP 数据包时,缓冲区会被 mpeg-ts 数据填充。然后您可以将缓冲区复制到应用程序的另一部分以解码数据。

    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();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-06
      • 1970-01-01
      • 2015-08-24
      • 2018-10-22
      • 2014-01-28
      • 2013-03-12
      • 1970-01-01
      相关资源
      最近更新 更多