存档

‘Red5’ 分类的存档

ffmpeg的Java封装

2009年8月11日 admin 没有评论
JAVE (Java Audio Video Encoder) 类库是一个 ffmpeg 项目的 Java 语言封装。开发人员可以使用JAVE 在不同的格式间转换视频和音频。例如将 AVI 转成 MPEG 动画,等等 ffmpeg 中可以完成的在 JAVE 都有对应的方法。

Examples

From a generic AVI to a youtube-like FLV movie, with an embedded MP3 audio stream:

File source = new File("source.avi");
File target = new File("target.flv");
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libmp3lame");
audio.setBitRate(new Integer(64000));
audio.setChannels(new Integer(1));
audio.setSamplingRate(new Integer(22050));
VideoAttributes video = new VideoAttributes();
video.setCodec("flv");
video.setBitRate(new Integer(160000));
video.setFrameRate(new Integer(15));
video.setSize(new VideoSize(400, 300));
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("flv");
attrs.setAudioAttributes(audio);
attrs.setVideoAttributes(video);
Encoder encoder = new Encoder();
encoder.encode(source, target, attrs);

Next lines extracts audio informations from an AVI and store them in a plain WAV file:

File source = new File("source.avi");
File target = new File("target.wav");
AudioAttributes audio = new AudioAttributes();
audio.setCodec("pcm_s16le");
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("wav");
attrs.setAudioAttributes(audio);
Encoder encoder = new Encoder();
encoder.encode(source, target, attrs);

Next example takes an audio WAV file and generates a 128 kbit/s, stereo, 44100 Hz MP3 file:

File source = new File("source.wav");
File target = new File("target.mp3");
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libmp3lame");
audio.setBitRate(new Integer(128000));
audio.setChannels(new Integer(2));
audio.setSamplingRate(new Integer(44100));
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("mp3");
attrs.setAudioAttributes(audio);
Encoder encoder = new Encoder();
encoder.encode(source, target, attrs);

Next one decodes a generic AVI file and creates another one with the same video stream of the source and a re-encoded low quality MP3 audio stream:

File source = new File("source.avi");
File target = new File("target.avi");
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libmp3lame");
audio.setBitRate(new Integer(56000));
audio.setChannels(new Integer(1));
audio.setSamplingRate(new Integer(22050));
VideoAttributes video = new VideoAttributes();
video.setCodec(VideoAttributes.DIRECT_STREAM_COPY);
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("avi");
attrs.setAudioAttributes(audio);
attrs.setVideoAttributes(video);
Encoder encoder = new Encoder();
encoder.encode(source, target, attrs);

Next one generates an AVI with MPEG 4/DivX video and OGG Vorbis audio:

File source = new File("source.avi");
File target = new File("target.avi");
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libvorbis");
VideoAttributes video = new VideoAttributes();
video.setCodec("mpeg4");
video.setTag("DIVX");
video.setBitRate(new Integer(160000));
video.setFrameRate(new Integer(30));
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("mpegvideo");
attrs.setAudioAttributes(audio);
attrs.setVideoAttributes(video);
Encoder encoder = new Encoder();
encoder.encode(source, target, attrs);

A smartphone suitable video:

File source = new File("source.avi");
File target = new File("target.3gp");
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libfaac");
audio.setBitRate(new Integer(128000));
audio.setSamplingRate(new Integer(44100));
audio.setChannels(new Integer(2));
VideoAttributes video = new VideoAttributes();
video.setCodec("mpeg4");
video.setBitRate(new Integer(160000));
video.setFrameRate(new Integer(15));
video.setSize(new VideoSize(176, 144));
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("3gp");
attrs.setAudioAttributes(audio);
attrs.setVideoAttributes(video);
Encoder encoder = new Encoder();
encoder.encode(source, target, attrs);

Popularity: unranked [?]

分类: JAVA, Red5 标签:

Red5 0.9下载

2009年8月11日 admin 1 条评论

Red5 0.9.0 RC1 提供下載,地址如下:

New Features:
- Added AVC/h.264 live streaming based on Tiago Jacobs patches
- Added enums for Audio and Video codec types
- Added capability to add IoFilters to RTMPConnection per application
- Added AAC live streaming code based on Wittawas Nakkasem’s IceSurf code

Bugfixes:
- Fixed bug with recording, where meta files were not removed when using the same name
- Changed VideoCodecFactory into a “true” factory class
- Applied patch for h.264 live stream packet handling from Dave Feltenberger
- Applied FP 10.0.32.18 patch from Ari-Pekka Viitanen

Popularity: unranked [?]

Spring ActionScript 0.8 发布

2009年8月4日 admin 没有评论

IOC功能非常强大,不多说了,看看原文吧:

Dear Community,

I’m pleased to announce that the Spring ActionScript 0.8 release is now available.

DownloadAPI DocumentationHTML DocsPDF DocsChangelog

This release includes the Spring ActionScript framework, the Cairngorm extensions and the PureMVC extensions.

All libraries are available for download at the following Maven repository: http://projects.yoolab.org/maven/content/repositories/

From now on, we will regularly publish new snapshots of the libraries there.

Direct links to the libraries:
- Spring ActionScript 0.8
- Spring ActionScript Cairngorm 0.8
- Spring ActionScript PureMVC 0.8

Dependencies:
- AS3Commons Lang
- AS3Commons Logging
- AS3Commons Reflect

Note: AS3Commons Lang is a snapshot of 1.0. We will work with a release for the following releases of Spring ActionScript

Besides a series of bugfixes, optimizations and improvements, some of the major changes and enhancements include:

Autowiring support

Using autowiring allows you to inject objects managed by the container into view components and other objects. To autowire a property, annotate it with the [Autowired] metadata tag. The support we build in is pretty enhanced and allows you to customize the autowire behavior in many different ways. Within the Autowired metadata tag you can specify the object name and you can also configure the container to filter autowire candidates using your own filter specifications. Please see the documentation on autowiring for more info.

Custom Namespaces

The XML configuration now supports namespaces and allows you to create custom namespaces yourself. A few namespaces have been added to simplify the configuration of common objects for RMI and Messaging. More info on available namespaces and schemas and creating custom ones can be found in the documentation. The XSD schemas are available http://www.springactionscript.org/schema/

MXML Configuration

We now also support configuration through MXML. The markup is very similar to the regular XML config, but with some slight differences. Please see the documentation on MXML Configuration

AS3Commons

As a side project, we have started the AS3Commons project that offers reusable ActionScript 3.0 libraries. Most of the libraries currently available in AS3Commons are build using code from the Spring ActionScript framework. This means that a lot of code has been removed from Spring ActionScript and is now available for use in projects not using Spring ActionScript. Please note that you might have to update quite some import statements to refer to AS3Commons instead of Spring ActionScript. We apologize for any inconvenience this might cause, but this is only a one-time process.

We hope you find the AS3Commons libraries useful. All libraries (releases and snapshots) can also be found at the Maven repository.

Documentation

The documentation has been tremendously improved in this version. Next to the API documentation, we now provide a reference guide in HTML and PDF format. General info can be found at the project website: www.springactionscript.org

Last Words

If you feel like helping us out, we could certainly use your help. This project is entirely created on a volunteer basis and in our spare (and limited) free time so needless to say that the more people, the faster we can deliver new releases and guarantee the quality of the framework. So if you think you have someting to offer, be it as a developer, tester, documentation writer, sample creator, … please contact me (christophe [DOT] herreman [AT] gmail [DOT] com) or leave something in the comments. All help is more than welcome.

Enjoy this release and have fun coding!

Popularity: unranked [?]

今天完成了Red5通讯框架并测试通过

2009年6月29日 admin 6 条评论

先看看下面介绍,更多功能将在下个版本更新.

版本:
v0.1

主要功能:
1,客戶端任意CALL服務端,反之亦然
2,實現消息轉發,Application所有事件分發.
3,運用反射實現服務的動態查找.
4,對客戶端發送的ByteArray進行解包及封裝.
5,服務端CALL客戶端(單CALL和廣播)
6,所有數據傳遞都採用基於AMF的二進制流

Popularity: unranked [?]

Red5 0.8.1正式版发布

2009年6月8日 admin 6 条评论

用了2天了,感觉还是挺不错的,增加了许多新功能,

例如: 支持H.264 ,支持1080P等

一些新特性在这里就不介绍了,直接到官方下载.

http://code.google.com/p/red5/

Popularity: 15% [?]

Red5实现直播

2009年6月8日 admin 2 条评论

程序如下:

发布端(Publish):

var nc:NetConnection = new NetConnection();
 
nc.connect("rtmp://125.67.234.97/Red5Stream");
nc.addEventListener(NetStatusEvent.NET_STATUS,connectHandler);
 
function connectHandler(par:NetStatusEvent):void {
    
trace(par.info.code);   
    
var camera:Camera = Camera.getCamera();
    
camera.setQuality(163854,100);
        
    
var stream:NetStream = new NetStream(nc);
    
stream.attachCamera(camera);
    
stream.publish("red5");
}

接收端

package {
    
import flash.display.*;
    
import flash.utils.*;
    
import flash.events.*;
    
import flash.net.*;
    
import flash.media.Video;
    
import fl.data.DataProvider;
    
import flash.media.Camera;
 
    
public class NetStreamTestDocument extends Sprite {
        
var nc:NetConnection;
        
public function NetStreamTestDocument() {
            
nc= new NetConnection();
            
nc.connect("rtmp://125.67.234.97/Red5Stream");
            
nc.addEventListener(NetStatusEvent.NET_STATUS,connectHandler);
            
            
        
}
        
public function connectHandler(par:NetStatusEvent):void {
            
var ns:NetStream = new NetStream(nc);
            
var video:Video=new Video(320,240) ;
                    
video.attachNetStream(ns);
            
ns.play("red5");
            
addChild(video);
        
}
    
}
}

服务端:

package com.conjs;
 
import org.red5.server.adapter.MultiThreadedApplicationAdapter;
import org.red5.server.api.IConnection;
import org.red5.server.api.Red5;
import org.red5.server.api.stream.IBroadcastStream;
import org.red5.server.api.stream.IStreamCapableConnection;
import org.red5.server.api.stream.support.SimpleConnectionBWConfig;
 
public class OtherApplication extends MultiThreadedApplicationAdapter {
    @
Override
    
public void streamPublishStart(IBroadcastStream stream) {
        
IConnection conn=Red5.getConnectionLocal();
        
measureBandwidth(conn);
        
if (conn instanceof IStreamCapableConnection) {
            
IStreamCapableConnection streamConn = (IStreamCapableConnection) conn;
            
SimpleConnectionBWConfig bwConfig = new SimpleConnectionBWConfig();
            
bwConfig.getChannelBandwidth()[3] = 1048576L;
 
            
bwConfig.getChannelInitialBurst()[3] = 131072L;
 
            
streamConn.setBandwidthConfigure(bwConfig);
 
            
super.streamPublishStart(stream);
        
}
    
}
 
    @
Override
    
public void streamBroadcastClose(IBroadcastStream arg0) {
        
super.streamBroadcastClose(arg0);
    
}
 
}

以下是官方在 H.264 和 1080P 方面支持的Demo ,我没有测试过,代码如下:

package org.red5.demos.oflaDemo;
import org.red5.server.adapter.ApplicationAdapter;
import org.red5.server.api.IBandwidthConfigure;
import org.red5.server.api.IConnection;
import org.red5.server.api.IScope;
import org.red5.server.api.stream.IServerStream;
import org.red5.server.api.stream.IStreamCapableConnection;
import org.red5.server.api.stream.support.SimpleConnectionBWConfig;
 
public class Application extends ApplicationAdapter {
    
    
private IScope appScope;
    
private IServerStream serverStream;
 
    
public boolean appStart(IScope app) {
        
appScope = app;
        
return true;
    
}
 
    
public boolean appConnect(IConnection conn, Object[] params) {
        
measureBandwidth(conn);
        
if (conn instanceof IStreamCapableConnection) {
            
SimpleConnectionBWConfig bwConfig = new SimpleConnectionBWConfig();
            
bwConfig.getChannelBandwidth()[IBandwidthConfigure.OVERALL_CHANNEL] =
                
1024 * 1024;
            
bwConfig.getChannelInitialBurst()[IBandwidthConfigure.OVERALL_CHANNEL] =
                
128 * 1024;
            
bwConfig.setUpstreamBandwidth(1024 * 1024);
        
}         
        
return super.appConnect(conn, params);
    
}
 
    
public void appDisconnect(IConnection conn) {
        
if (appScope == conn.getScope() && serverStream != null) {
            
serverStream.close();
        
}
        
super.appDisconnect(conn);
    
}
}

Popularity: 26% [?]

分类: JAVA, Red5 标签: ,

Red5 Client 调用 Red5 Server

2009年6月5日 admin 没有评论
package com.conjs;

import org.red5.server.api.service.IPendingServiceCall;
import org.red5.server.api.service.IPendingServiceCallback;
import org.red5.server.net.rtmp.RTMPClient;

public class Red5 extends RTMPClient {
public static void main(String[] args) {
String host = "localhost";
String app = "test";
int port = 1935;
final Red5 client = new Red5();

IPendingServiceCallback callback = new IPendingServiceCallback() {
@SuppressWarnings("unchecked")
public void resultReceived(IPendingServiceCall call) {
java.util.Map<String, String> re = (java.util.Map<String, String>) call.getResult();
System.out.println("level:" + re.get("level"));
System.out.println("description:" + re.get("description"));
System.out.println("code:" + re.get("code"));
}
};
client.connect(host, port, app, callback);
}

}

Popularity: 14% [?]

Red5 Media Server and Security

2009年5月6日 admin 1 条评论

收集国外文章,呵呵  Red5的文章很少啊. 大家珍惜
Here are the steps to configure SSL in existing Red5 application. This article is keeping in the mind you have basic knowledge of Red5 or you are aware of how Red5 applications are built.

Software required on machine where Red5 server is installed:-

1: Open SSL //Open source SSL libraries required for compiling Stunnel

2: Stunnel //Open source SSL wrapper software uses open SSL works both on
Windows and Linux.

3: gcc // The GNU C compiler (although it always bundled with Linux
Machine, but I did not find it. Necessary if you are compiling the
Open SSL and Stunnel from source. Not required if using RPM

Configuration needed on server machine:-

1:- Install the Open SSL (if windows use exe RPM or source for Linux machine can be downloaded from openssl website).

2:- Install Stunnel (if windows, use exe otherwise RPM or compilation from source is preferred, can be downloaded from stunnel website). Make sure that you already have compiled Open SSL in your machine before proceeding with the installation of Stunnel; otherwise it will fail to compile.

Under Linux the standard command to compile Stunnel from source are described below. For any update please always follow the installation instructions given their website.

machine# gzip -dc stunnel-VERSION.tar.gz tar -xvzf -
machine# cd stunnel-VERSION
machine# ./configure
machine# make
machine# make install

There are several configurations that differ based on your computer and environment. That can be read from the website itself.

3:- Running Stunnel (There are several ways/mode you can run the stunnel. Follow the FAQ available in their website to choose the best which matches your requirements).
To run stunnel, you always require a configuration file. The process of making sample configuration file (stunnel.conf) is described below.

The sample configuration file used was like this:

sample.conf

; Sample stunnel configuration file by Sunil Gupta 2007
; Some options used here may not be adequate for your particular configuration

; Certificate/key is needed in server mode and optional in client mode
; The default certificate is provided only for testing and should not
; be used in a production environment

cert = /etc/stunnel/stunnel.pem
;chroot = /var/run/stunnel/
pid = /stunnel.pid
key = /etc/stunnel/stunnel.pem

; Some performance tunings
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1

; Workaround for Eudora bug
;options = DONT_INSERT_EMPTY_FRAGMENTS

; Authentication stuff
;verify = 2
; Don’t forget to c_rehash CApath
;CApath = certs
; It’s often easier to use CAfile
;CAfile = certs.pem
; Don’t forget to c_rehash CRLpath
;CRLpath = crls
; Alternatively you can use CRLfile
;CRLfile = crls.pem

; Some debugging stuff useful for troubleshooting
debug = 7
Output = /var/log/stunnel.log
foreground=yes
; Use it for client mode
; client = yes
; Service-level configuration

;[pop3s]
;accept = 995
;connect = 110

;[imaps]
;accept = 993
;connect = 143

;[ssmtp]
;accept = 465
;connect = 25

[rtmps - https]
TIMEOUTconnect=20
accept = 443
connect = 80
TIMEOUTclose = 20

; vim:ft=dosin

Finish

Note: – When you install Stunnel, you get a default sample file, which is not enough in most of the cases to run the flash application. The additions to configuration file I made are as follows.
Also the line having ; in the start denotes the commented portion in file.

cert = /etc/stunnel/stunnel.pem
key = /etc/stunnel/stunnel.pem

pem stands for ‘privacy enhanced mail’ used as a key format. The above two lines tells the location of pem files need to be generated. This will be configured by user. The above is the best location for Stunnel although you can change it to any desired location.

;Some performance tunings

socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1

The above two lines are for better performance of Stunnel in our case.

; Workaround for Eudora bug
;options = DONT_INSERT_EMPTY_FRAGMENTS

The above line is a bug in a specific platform, since we are running it in Linux; we commented this line, although it could be needed in some case.

; Some debugging stuff useful for troubleshooting
debug = 7
Output = /var/log/stunnel.log
foreground=yes

The above lines are very important, Because Stunnel by default run in background mode. You will never be able to see if it is running. So better to put it in foreground, so that you can make sure that stunnel is running properly. Also the debug = 7 is very important since by default stunnel does not generate any log. You can direct him to generate log, so that you can debug your application by seeing all those log messages. The above mentioned log directory is default Linux directory where all system logs are generated.

; Use it for client mode
; client = yes

In the sample configuration file, you will always find this option un-commented leading to a different architecture, since we are running Stunnel in server mode not client mode, so we will comment this line.

[rtmps - https]
TIMEOUTconnect=20
accept = 443
connect = 80
TIMEOUTclose = 20

And the very last lines are mentioned above. In the sample configuration file, you will never find rtmps and it is not even mentioned anywhere in Stunnel. The default file contains only https, add rtmps like it is added here. Also accept port is 443, which is the default port used for secure communication and it is open like port 80 in all corporate firewalls in general. This port is to accept the connection from flash and to get the encrypted data. The connect port is 80; this is the port where stunnel will forward the decrypted data to red5 server.
The TIMEOUTconnect and TIMEOUTclose can be useful in some cases when the server where the data is being forwarded by Stunnel is delaying the connection. This is to make sure that connection is closed only when server is not responding at all. The value is in seconds (i.e. 20 sec.)

Now in order to run your application under secure connection, you require a certificate to be created on the machine where the Stunnel is installed. The procedure for creating a certificate and the possible directory to put this certificate is described below.

Use of certificate:-

When an SSL client connects to an SSL server, the server presents a certificate, essentially an electronic piece of proof that machine is who it claims to be. This certificate is signed by a ‘Certificate Authority’ (hereafter a CA) — usually a trusted third party like Verisign. A client will accept this certificate only if
The certificate presented matches the private key being used by the remote end.
The certificate has been signed correctly by the CA. The client recognizes the CA as trusted.

Every stunnel server has a private key. This is contained in the pem file which stunnel uses to initialize its identity. If we notice above, we have given the reference of this pem file in the start of our configuration file under cert.

This private key is put in /usr/local/ssl/certs/stunnel.pem.

Note:-Under client mode we need not to have certificate in most of the cases, but if we are running it in server mode, we require a certificate. Since we are using server mode, I have generated a self certificate.

To make certificate:-

1: Go to /etc/stunnel directory and
2: Run the following command:-’

openssl req -new -x509 -days 365 -nodes -config stunnel.cnf -out stunnel.pem -keyout stunnel.pem

This creates a private key and self-signed certificate. More information on the options of this can be read from FAQ section of Stunnel website.

While executing the command, it will ask for some questions like Country, City, Company etc., Give the answer of those and it will generate the key and self certificate.

4:- Put your sample.conf file in /etc/stunnel directory where the .pem file was created earlier.

5:- Start Stunnel by issuing the command -

machine# stunnel stunnel.conf

If you are /etc/stunnel directory otherwise complete path of configuration file-

machine# stunnel /etc/stunnel/stunnel.conf

The above command will start the stunnel and you can verify the log from /var/logs/stunnel.log file.

Red5 server side changes:-

6:- Now stunnel is up and running, we need to change the Red5 configuration to accept the connection from Stunnel.

Go to red5 installation directory and search for conf folder where all red5 configuration files exist.

Open red5.properties file and under rtmps.host_port property put 443. The sample file can be like below.

rtmp.host_port = 0.0.0.0:1935
rtmp.threadcount = 4
debug_proxy.host_port = 0.0.0.0:1936
proxy_forward.host_port = 127.0.0.1:1935
rtmps.host_port = 127.0.0.1:443
http.host=0.0.0.0
http.port=5080
rtmpt.host=0.0.0.0
rtmpt.port=80

Flash client side changes:-

7:-Now we are done with server side, In order to run application under SSL, we need to change the client side protocol from rtmp to rtmps like below. And compile the flash client and run it on browser, a certificate will pop up, accept it and the application will run under SSL.

nc.connect (”rtmps://yourip/applicationname”); //used rtmps in place of rtmp

To get all Red5 media server related stuffs, visit the website below-

Technology Makes Life Easier (http://sunil-gupta.blogspot.com)

Popularity: 32% [?]

How to record RTMP flash video streams using Red5(使用Red5录制视频)

2009年5月3日 admin 没有评论

Red5 is an open source Flash server written in Java. It does not include a standalone client yet but I was able to write a Java program that uses Red5 to connect to an RTMP video stream and record / save it to a file. Code is provided below and also some tips on how to get the details required to download flash videos that you come across on the internet.

Here’s the code of “MyRtmpClient.java”, you are free to use and modify this in any way you want.

import java.io.File;

import org.apache.mina.common.ByteBuffer;
import org.red5.io.IStreamableFile;
import org.red5.io.ITag;
import org.red5.io.ITagWriter;
import org.red5.io.flv.impl.FLVService;
import org.red5.io.flv.impl.Tag;
import org.red5.io.utils.ObjectMap;
import org.red5.server.api.event.IEvent;
import org.red5.server.api.event.IEventDispatcher;
import org.red5.server.api.service.IPendingServiceCall;
import org.red5.server.api.service.IPendingServiceCallback;
import org.red5.server.net.rtmp.Channel;
import org.red5.server.net.rtmp.RTMPClient;
import org.red5.server.net.rtmp.RTMPConnection;
import org.red5.server.net.rtmp.codec.RTMP;
import org.red5.server.net.rtmp.event.AudioData;
import org.red5.server.net.rtmp.event.IRTMPEvent;
import org.red5.server.net.rtmp.event.Notify;
import org.red5.server.net.rtmp.event.VideoData;
import org.red5.server.net.rtmp.message.Header;
import org.red5.server.net.rtmp.status.StatusCodes;
import org.red5.server.stream.AbstractClientStream;
import org.red5.server.stream.IStreamData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyRtmpClient extends RTMPClient {

	private static final Logger logger = LoggerFactory.getLogger(MyRtmpClient.class);

	private String saveAsFileName = "test.flv";

	public static void main(String[] args) {

		String host = "localhost";
		String app = "oflaDemo";
		final String name = "IronMan.flv";
		int port = 1935;
		final int duration = 10000; // milliseconds, -2 means until end of stream

		final MyRtmpClient client = new MyRtmpClient();
		logger.debug("connecting, host: " + host + ", app: " + app + ", port: " + port);

		IPendingServiceCallback callback = new IPendingServiceCallback() {
			public void resultReceived(IPendingServiceCall call) {
				logger.debug("service call result: " + call);
				if ("connect".equals(call.getServiceMethodName())) {
					client.createStream(this);
				} else if ("createStream".equals(call.getServiceMethodName())) {
					Integer streamId = (Integer) call.getResult();
					logger.debug("createStream result stream id: " + streamId);
					logger.debug("playing video by name: " + name);
					client.play(streamId, name, 0, duration);
				}
			}
		};

		client.connect(host, port, app, callback);

	}

	private RTMPConnection conn;
	private ITagWriter writer;

	private int videoTs;
	private int audioTs;

	@Override
	public void connectionOpened(RTMPConnection conn, RTMP state) {
		logger.debug("connection opened");
		super.connectionOpened(conn, state);
		this.conn = conn;
		init();
	}

	@Override
	public void connectionClosed(RTMPConnection conn, RTMP state) {
		logger.debug("connection closed");
		super.connectionClosed(conn, state);
		if (writer != null) {
			writer.close();
			writer = null;
		}
		System.exit(0);
	}

	@Override
	public void createStream(IPendingServiceCallback callback) {
		logger.debug("create stream");
		IPendingServiceCallback wrapper = new CreateStreamCallBack(callback);
		invoke("createStream", null, wrapper);
	}

	@Override
	protected void onInvoke(RTMPConnection conn, Channel channel, Header header, Notify notify, RTMP rtmp) {
		super.onInvoke(conn, channel, header, notify, rtmp);
		ObjectMap<String, String> map = (ObjectMap) notify.getCall().getArguments()[0];
		String code = map.get("code");
		if (StatusCodes.NS_PLAY_STOP.equals(code)) {
			logger.debug("onInvoke, code == NetStream.Play.Stop, disconnecting");
			disconnect();
		}
	}	

	private void init() {
		File file = new File(saveAsFileName);
		FLVService flvService = new FLVService();
		flvService.setGenerateMetadata(true);
		try {
			IStreamableFile flv = flvService.getStreamableFile(file);
			writer = flv.getWriter();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	private class CreateStreamCallBack implements IPendingServiceCallback {

		private IPendingServiceCallback wrapped;

		public CreateStreamCallBack(IPendingServiceCallback wrapped) {
			this.wrapped = wrapped;
		}

		public void resultReceived(IPendingServiceCall call) {
			Integer streamIdInt = (Integer) call.getResult();
			if (conn != null && streamIdInt != null) {
				MyNetStream stream = new MyNetStream();
				stream.setConnection(conn);
				stream.setStreamId(streamIdInt.intValue());
				conn.addClientStream(stream);
			}
			wrapped.resultReceived(call);
		}

	}

	private class MyNetStream extends AbstractClientStream implements IEventDispatcher {

		public void close() { }

		public void start() { }

		public void stop() { }

		public void dispatchEvent(IEvent event) {
			if (!(event instanceof IRTMPEvent)) {
				logger.debug("skipping non rtmp event: " + event);
				return;
			}
			IRTMPEvent rtmpEvent = (IRTMPEvent) event;
			if (logger.isDebugEnabled()) {
				logger.debug("rtmp event: " + rtmpEvent.getHeader() + ", "
						+ rtmpEvent.getClass().getSimpleName());
			}
			if (!(rtmpEvent instanceof IStreamData)) {
				logger.debug("skipping non stream data");
				return;
			}
			if (rtmpEvent.getHeader().getSize() == 0) {
				logger.debug("skipping event where size == 0");
				return;
			}
			ITag tag = new Tag();
			tag.setDataType(rtmpEvent.getDataType());
			if (rtmpEvent instanceof VideoData) {
				videoTs += rtmpEvent.getTimestamp();
				tag.setTimestamp(videoTs);
			} else if (rtmpEvent instanceof AudioData) {
				audioTs += rtmpEvent.getTimestamp();
				tag.setTimestamp(audioTs);
			}
			ByteBuffer data = ((IStreamData) rtmpEvent).getData().asReadOnlyBuffer();
			tag.setBodySize(data.limit());
			tag.setBody(data);
			try {
				writer.writeTag(tag);
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
	}

}

To compile and run the code you need the following libraries:

commons-collections-3.2.jar
jcl104-over-slf4j-1.4.3.jar
logback-classic-0.9.8.jar
logback-core-0.9.8.jar
mina-core-1.1.6.jar
red5.jar
slf4j-api-1.4.3.jar
spring-beans-2.0.8.jar
spring-context-2.0.8.jar
spring-core-2.0.8.jar

We need the latest Red5 JAR built from version control (not the latest official release) and I have uploaded these files here: red5-rtmp-client-libszip.pdf – just rename the file to end with “.zip” after downloading.

The code shown is hard-coded to connect to “localhost”, app name “oflaDemo” and stream name “IronMan.flv” which can be tested on the official Red5 server distribution which you can download and run. When it comes to downloading flash streams from the internet, WireShark can be used to sniff out the values you need.

Let’s take this site for example: http://videolectures.net/ Start a WireShark capture session before clicking on a video on the site to play it. Let WireShark grab all the information exchanged between your PC and the remote flash server and you can stop the capture once the video begins to play, we are only interested in what goes on during the connection handshake. I will use this video as an example: http://videolectures.net/ff06_chomsky_szmp/ [update Jun-2008: looks like they changed this particular video to Windows media instead of Flash, so try other videos or other sites]

In WireShark you can filter for protocol “rtmpt” and the first few entries would be handshake or “invoke” operations. Examining the “Handshake part 3″ we can easily get the value of the required “app” property. Below we can see it is “video/2006/other/ff06/chomsky_noam”:

For the host name, the IP address should do fine for most sites, but we can easily figure out the host name of the stream server from what appears after “rtmp://”. Note that WireShark allows you to search the text contents of captured packets. Here below we can see that the host name is “velblod.videolectures.net”:

And finally when the “play” command is issued – we need the value of the stream name. Below we see it is “chomsky_noam_01″:

So with the right values of hostname, app and stream name set – you can run the program and download the stream to your local drive for offline viewing. To download the whole stream – just change the duration to ‘-2′ as hinted in the source code comment. There are many free Flash players available you can use to play downloaded content such as FLV Player.

Do let me know if this works for you and if you find any additional parameters that need to be passed for other sites.

Popularity: 40% [?]

解决 Red5 Admin Panel不能登陆的问题

2009年2月12日 admin 没有评论

1.start red5  0.7.0 
2.open this url :  http://localhost:5080/admin/register.html
3. in the form fill your new user and password  and submit 
4.restart red5 and enter http://localhost:5080/demos/adminPanel.html 
using ”localhost” and the user/pass you define in step 3. 

如果还是不能登陆,就把 Red服务重启一下,就可以了。

Popularity: 34% [?]