java视频传输,如何从Java应用程序中传输实时视频?

I'm trying to find ways to stream a live video generated in a Java application. The application needs to take screenshots of itself and encode these into a video stream and publish the stream.

So far I have been using Xuggler (a Java library on top of FFMPEG) to encode the screenshots into a video file. This works great. Xuggler claims to be able to transmit live video via RTMP but I have not found any documentation on how to do this programmatically.

Does anyone know how to stream RTMP video programmatically from Xuggler?

Does anyone have a suggestion on other libraries I could use to achieve the same results? I'd prefer to stream the video in MPEG2 over RTP.

I did find someone else asking a very similar question on the Xuggler forums here with no response.

I have looked into JMF and it is not an option for other reasons.

解决方案

Honestly don't waste your time with JMF, you can consider that offering dead. Here is how you would do screen shotting to an rtmp stream using h.264 (thanks to tyreus@gmail.com for the example). If the code doesn't show up here's pastebin for it: http://pastebin.com/sJHwj0nW

import com.xuggle.xuggler.Configuration;

import com.xuggle.xuggler.ICodec;

import com.xuggle.xuggler.IContainer;

import com.xuggle.xuggler.IContainerFormat;

import com.xuggle.xuggler.IPacket;

import com.xuggle.xuggler.IPixelFormat;

import com.xuggle.xuggler.IRational;

import com.xuggle.xuggler.IStream;

import com.xuggle.xuggler.IStreamCoder;

import com.xuggle.xuggler.IVideoPicture;

import com.xuggle.xuggler.video.ConverterFactory;

import com.xuggle.xuggler.video.IConverter;

import java.awt.AWTException;

import java.awt.Rectangle;

import java.awt.Robot;

import java.awt.image.BufferedImage;

import java.io.IOException;

import java.io.InputStream;

import java.util.Properties;

public class XugglerRtmpReferenceImpl {

private static String url = "rtmp://your.test.server/screen/";

private static String fileName = "test/teststream";

private static int framesToEncode = 60;

private static int x = 0;

private static int y = 0;

private static int height = 480;

private static int width = 640;

public static void main(String[] args) {

IContainer container = IContainer.make();

IContainerFormat containerFormat_live = IContainerFormat.make();

containerFormat_live.setOutputFormat("flv", url + fileName, null);

container.setInputBufferLength(0);

int retVal = container.open(url + fileName, IContainer.Type.WRITE, containerFormat_live);

if (retVal < 0) {

System.err.println("Could not open output container for live stream");

System.exit(1);

}

IStream stream = container.addNewStream(0);

IStreamCoder coder = stream.getStreamCoder();

ICodec codec = ICodec.findEncodingCodec(ICodec.ID.CODEC_ID_H264);

coder.setNumPicturesInGroupOfPictures(5);

coder.setCodec(codec);

coder.setBitRate(200000);

coder.setPixelType(IPixelFormat.Type.YUV420P);

coder.setHeight(height);

coder.setWidth(width);

System.out.println("[ENCODER] video size is " + width + "x" + height);

coder.setFlag(IStreamCoder.Flags.FLAG_QSCALE, true);

coder.setGlobalQuality(0);

IRational frameRate = IRational.make(5, 1);

coder.setFrameRate(frameRate);

coder.setTimeBase(IRational.make(frameRate.getDenominator(), frameRate.getNumerator()));

Properties props = new Properties();

InputStream is = XugglerRtmpReferenceImpl.class.getResourceAsStream("/libx264-normal.ffpreset");

try {

props.load(is);

} catch (IOException e) {

System.err.println("You need the libx264-normal.ffpreset file from the Xuggle distribution in your classpath.");

System.exit(1);

}

Configuration.configure(props, coder);

coder.open();

container.writeHeader();

long firstTimeStamp = System.currentTimeMillis();

long lastTimeStamp = -1;

int i = 0;

try {

Robot robot = new Robot();

while (i < framesToEncode) {

//long iterationStartTime = System.currentTimeMillis();

long now = System.currentTimeMillis();

//grab the screenshot

BufferedImage image = robot.createScreenCapture(new Rectangle(x, y, width, height));

//convert it for Xuggler

BufferedImage currentScreenshot = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_3BYTE_BGR);

currentScreenshot.getGraphics().drawImage(image, 0, 0, null);

//start the encoding process

IPacket packet = IPacket.make();

IConverter converter = ConverterFactory.createConverter(currentScreenshot, IPixelFormat.Type.YUV420P);

long timeStamp = (now - firstTimeStamp) * 1000;

IVideoPicture outFrame = converter.toPicture(currentScreenshot, timeStamp);

if (i == 0) {

//make first frame keyframe

outFrame.setKeyFrame(true);

}

outFrame.setQuality(0);

coder.encodeVideo(packet, outFrame, 0);

outFrame.delete();

if (packet.isComplete()) {

container.writePacket(packet);

System.out.println("[ENCODER] writing packet of size " + packet.getSize() + " for elapsed time " + ((timeStamp - lastTimeStamp) / 1000));

lastTimeStamp = timeStamp;

}

System.out.println("[ENCODER] encoded image " + i + " in " + (System.currentTimeMillis() - now));

i++;

try {

Thread.sleep(Math.max((long) (1000 / frameRate.getDouble()) - (System.currentTimeMillis() - now), 0));

} catch (InterruptedException e) {

e.printStackTrace();

}

}

} catch (AWTException e) {

e.printStackTrace();

}

container.writeTrailer();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实时视频传输需要使用网络传输技术和视频编解码技术,实现起来比较复杂。下面是一个简单的Java实现实时视频传输的示例代码,仅供参考。 1. 服务端代码 ```java import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class Server { public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(8888); System.out.println("服务器已启动,等待客户端连接..."); while (true) { Socket socket = serverSocket.accept(); System.out.println("客户端连接成功:" + socket.getInetAddress()); new Thread(new ServerThread(socket)).start(); } } } class ServerThread implements Runnable { private Socket socket; public ServerThread(Socket socket) { this.socket = socket; } @Override public void run() { try { // TODO: 读取视频流数据并发送到客户端 } catch (IOException e) { e.printStackTrace(); } finally { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } ``` 2. 客户端代码 ```java import java.io.DataInputStream; import java.io.IOException; import java.net.Socket; public class Client { public static void main(String[] args) throws IOException { Socket socket = new Socket("localhost", 8888); System.out.println("连接服务器成功:" + socket.getInetAddress()); DataInputStream dis = new DataInputStream(socket.getInputStream()); // TODO: 接收视频流数据并播放 } } ``` 以上代码仅提供了服务端和客户端的基本框架,具体实现还需要使用视频编解码技术和网络传输技术。建议使用成熟的开源框架,如FFmpeg、Netty等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值