我正在尝试寻找流式传输Java应用程序中生成的实时视频的方法.应用程序需要截取自身的屏幕截图并将其编码为视频流并发布流.
到目前为止,我一直在使用Xuggler(FFMPEG之上的Java库)将屏幕截图编码为视频文件.这非常有效.Xuggler声称能够通过RTMP传输实时视频,但我还没有找到任何关于如何以编程方式执行此操作的文档.
我没有找别人问一个非常类似的问题在Xuggler论坛这里没有响应.
我已经研究过JMF,但由于其他原因,这不是一个选择.
我对媒体流非常陌生,我有一些基本的疑虑要明确:
据我所知,HTTP流(通过Apache)和RTMP流(通过Red5)之间的区别在于流媒体服务器提供缓冲和提前控制,如搜索等.我是对的吗?
我可以只传输来自RT5服务器(如Red5)的Flash视频吗?如果我必须传输不同格式的文件,我是否必须使用HTTP流?我可以使用像xuggler这样的工具来动态转码文件并根据Red5服务器的请求发送吗?
我提出了所有这些疑虑,因为我必须为所有移动客户端提供流媒体 - iPhone,黑莓,Android - iPhone不支持闪存,所以去Red5是个好主意吗?
是的,我知道FAQ假装回答这个问题,但事实并非如此.相反,它指示您从源构建项目(并且构建指令非常复杂).那种打败了整点:)
让我们为世界上的每个人节省必须建立另一个开源项目的麻烦,以便找出它是否真正解决了他们的问题.Xuggler支持哪些编解码器?
我正在尝试执行以下代码:
import com.xuggle.mediatool.IMediaReader;
import com.xuggle.mediatool.IMediaWriter;
import com.xuggle.mediatool.ToolFactory;
public class vidcon {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
IMediaReader reader = ToolFactory.makeReader("test.m4v");
IMediaWriter writer = ToolFactory.makeWriter("out.flv");
reader.addListener(writer);
while(reader.readPacket() == null)
;
}
}
Run Code Online (Sandbox Code Playgroud)
但这是给我这个错误:
Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
at com.xuggle.ferry.JNILibrary.<clinit>(JNILibrary.java:42)
at com.xuggle.ferry.FerryJNI.<clinit>(FerryJNI.java:14)
at com.xuggle.ferry.Ferry.<clinit>(Ferry.java:25)
at com.xuggle.xuggler.XugglerJNI.<clinit>(XugglerJNI.java:19)
at com.xuggle.xuggler.IContainer.<clinit>(IContainer.java:1622)
at com.xuggle.mediatool.MediaReader.<init>(MediaReader.java:137)
at com.xuggle.mediatool.ToolFactory.makeReader(ToolFactory.java:77)
at vidcon.main(vidcon.java:11)
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown …Run Code Online (Sandbox Code Playgroud) 我和xuggle一起工作了一周,我写了一个通过视频获取帧的方法但是如果视频很长,这个方法需要花费太多时间:
public static void getFrameBySec(IContainer container, int videoStreamId, IStreamCoder videoCoder, IVideoResampler resampler, double sec)
{
BufferedImage javaImage = new BufferedImage(videoCoder.getWidth(), videoCoder.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
IConverter converter = ConverterFactory.createConverter(javaImage, IPixelFormat.Type.BGR24);
IPacket packet = IPacket.make();
while(container.readNextPacket(packet) >= 0)
{
if (packet.getStreamIndex() == videoStreamId)
{
IVideoPicture picture = IVideoPicture.make(videoCoder.getPixelType(), videoCoder.getWidth(), videoCoder.getHeight());
int offset = 0;
while(offset < packet.getSize())
{
int bytesDecoded = videoCoder.decodeVideo(picture, packet, offset);
if (bytesDecoded < 0)
throw new RuntimeException("got error decoding video");
offset += bytesDecoded;
if (picture.isComplete())
{
IVideoPicture newPic = picture; …Run Code Online (Sandbox Code Playgroud) 所以如果我跑:
ffmpeg -t 10 -re -i "rtmp://170.93.143.150/rtplive/ app=rtplive/ playpath=e000990f025f0075004d823633235daa swfUrl=http://www.chart.state.md.us/video/mediaplayer/player.swf pageUrl=http://www.chart.state.md.us/video/video.asp?feed=e000990f025f0075004d823633235daa stop=5000 flashver=`LNX 11,2,202,262` live=true" test.flv -report
Run Code Online (Sandbox Code Playgroud)
它给了我5秒钟来自该网络流的视频,并将其投入test.flv.现在我想在java中使用xuggle做同样的事情,除非我每次尝试打开容器时都会出错,并将x设置为-1:
public IMediaReader grabStream(IMediaReader reader) throws IOException
{
String rtmp = "rtmp://170.93.143.150/rtplive/";
rtmp = rtmp + " app=rtplive/";
rtmp = rtmp + " playpath=e000990f025f0075004d823633235daa";
rtmp = rtmp + " swfUrl=http://www.chart.state.md.us/video/mediaplayer/player.swf";
rtmp = rtmp + " pageUrl=http://www.chart.state.md.us/video/video.asp?feed=e000990f025f0075004d823633235daa";
rtmp = rtmp + " flashver=`LNX 11,2,202,262`";
rtmp = rtmp + " live=true";
IContainer container = IContainer.make();
IMediaReader newReader = ToolFactory.makeReader(container);
int x = container.open(rtmp, IContainer.Type.READ, null, …Run Code Online (Sandbox Code Playgroud) 我想从视频中提取帧并在其上应用一些过滤器,例如gabor/hough等.哪个Java库非常适合处理各种视频编码?我一直在关注GStreamer,JMF,Xuggler等,但我无法确定哪一个是最好的.我也希望编辑帧并使用新帧制作视频.
如何使用Xuggle将flv视频转换为Mp4格式?我需要研究哪种api方法?任何链接/指针都会有所帮助
我是否可以采取具体步骤从Windows 32位,Windows 64位,Linux 32位和Linux 64位构建Xuggle Xuggler源代码?我已经在多个系统上多次尝试并且不断遇到很多不同的错误.
更新
我花了几天时间试图让Xuggle Xuggler编译(并交叉编译).我成功地编译了原始GPL版本的代码和LGPL版本.我以为我会在Stack Overflow上发布我自己的问题的答案来分享我的知识.
Raspberry Pi的更新
我还能够按照以下相同的基本说明在Raspberry Pi上构建和运行Xuggler.我刚刚使用了我在Github上维护的代码的LGPL版本,并对Pi进行了修改.我也可以在我的Radxa Rock(另一个ARM设备)上使用已编译的JAR文件和二进制文件.如果你有兴趣在Pi上构建,你可以使用我的pi分支:
https://github.com/ed/xuggle-xuggler
如果你很懒,只想要Pi/ARM的预编译.jar文件:
我刚刚开始使用Xuggle,我已将所有内容下载到Eclipse中,并将其包含在Referenced Libraries中,但我做了一个非常简单的测试,
package com.xuggle.xuggler.demos;
import com.xuggle.xuggler.IContainer;
public class getContainerInfo {
public static void main (String [] args){
IContainer myContainer = IContainer.make();
}
}
Run Code Online (Sandbox Code Playgroud)
它会引发一堆错误,
2011-06-12 16:26:52,142 [main] ERROR com.xuggle.ferry.JNILibraryLoader - Could not load library: xuggle-xuggler; version: 3; Visit http://www.xuggle.com/xuggler/faq/ to find common solutions to this problem
Exception in thread "main" java.lang.UnsatisfiedLinkError: no xuggle-xuggler in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1734)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1028)
at com.xuggle.ferry.JNILibraryLoader.loadLibrary0(JNILibraryLoader.java:265)
at com.xuggle.ferry.JNILibraryLoader.loadLibrary(JNILibraryLoader.java:168)
at com.xuggle.xuggler.XugglerJNI.<clinit>(XugglerJNI.java:19)
at com.xuggle.xuggler.IContainer.<clinit>(IContainer.java:1457)
at com.xuggle.xuggler.demos.getContainerInfo.main(getContainerInfo.java:9)
Run Code Online (Sandbox Code Playgroud)