我有一个来自 FFMpeg 的实时视频流,我很难使用我自己的自定义 Java 应用程序查看该流。在有人告诉我使用 VLC 或类似的东西之前,我确实想使用我自己的应用程序。我试图读取的流是通过 UDP 流式传输的 H.264 编码的 Mpeg-ts 流。我确实知道如何解码 H.264 帧,但我只是想知道如何接收 Mpeg-ts 流。
问问题
5340 次
2 回答
1
为了接收多播流,您需要创建一个多播客户端,该客户端具有一个缓冲区来存储视频数据并使用可以加入和侦听多播流的套接字。
这两个属性是多播地址 (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();
}
}
}
于 2016-01-06T02:30:53.057 回答
1
Jon Kittel提供了一个很好的答案,无论如何在问题评论中提到了 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,则可以在任何时候使用播放器打开输出文件,以重现在那之前捕获的视频流。
于 2016-01-08T08:48:33.073 回答