Red5的服务器搭建请看我的另外一篇文章:
http://blog.csdn.net/sunroyi666/article/details/52981639
最近正在开发基于流媒体的资源管理和直播系统,做了不少技术调查,框架的构思,也学到了很多东西。
现在空下来,把最近学到的技术知识和项目的架构分享一下。
/**
* 视频转码 (PC端FLV)
* @param ffmpegPath 转码工具的存放路径
* @param upFilePath 用于指定要转换格式的文件,要截图的视频源文件
* @param codcFilePath 格式转换后的的文件保存路径
* @param mediaPicPath 截图保存路径
* @return
* @throws Exception
*/
public boolean exchangeToFlv(String ffmpegPath, String upFilePath, String codcFilePath,
String mediaPicPath) throws Exception {
// 创建一个List集合来保存转换视频文件为flv格式的命令
List convert = new ArrayList();
convert.add(ffmpegPath); // 添加转换工具路径
convert.add("-i"); // 添加参数"-i",该参数指定要转换的文件
convert.add(upFilePath); // 添加要转换格式的视频文件的路径
convert.add("-qscale"); //指定转换的质量
convert.add("6");
convert.add("-ab"); //设置音频码率
convert.add("64");
convert.add("-ac"); //设置声道数
convert.add("2");
convert.add("-ar"); //设置声音的采样频率
convert.add("22050");
convert.add("-r"); //设置帧频
convert.add("24");
convert.add("-y"); // 添加参数"-y",该参数指定将覆盖已存在的文件
convert.add(codcFilePath);
// 创建一个List集合来保存从视频中截取图片的命令
List cutpic = new ArrayList();
cutpic.add(ffmpegPath);
cutpic.add("-i");
cutpic.add(upFilePath); // 同上(指定的文件即可以是转换为flv格式之前的文件,也可以是转换的flv文件)
cutpic.add("-y");
cutpic.add("-f");
cutpic.add("image2");
cutpic.add("-ss"); // 添加参数"-ss",该参数指定截取的起始时间
cutpic.add("16"); // 添加起始时间为第16秒
cutpic.add("-t"); // 添加参数"-t",该参数指定持续时间
cutpic.add("0.001"); // 添加持续时间为1毫秒
cutpic.add("-s"); // 添加参数"-s",该参数指定截取的图片大小
cutpic.add("350*240"); // 添加截取的图片大小为350*240
cutpic.add(mediaPicPath); // 添加截取的图片的保存路径
boolean mark = true;
ProcessBuilder builder = new ProcessBuilder();
try {
builder.command(convert);
builder.redirectErrorStream(true);
builder.start();
builder.command(cutpic);
builder.redirectErrorStream(true);
// 如果此属性为 true,则任何由通过此对象的 start() 方法启动的后续子进程生成的错误输出都将与标准输出合并,
//因此两者均可使用 Process.getInputStream() 方法读取。这使得关联错误消息和相应的输出变得更容易
builder.start();
} catch (Exception e) {
mark = false;
System.out.println(e);
e.printStackTrace();
}
return mark;
}
// Red5的RTMP协议地址需要自己修改
nc.connect("rtmp://192.168.3.100:1936/oflaDemo");
}
private function connectHandler(evt:NetStatusEvent):void{
trace(evt.info.code);
//由于flash的异步机制,连接成功后才能做处理,否则NetStream会因为conn没能连接报参数错误#2126
var params:Object = FlexGlobals.topLevelApplication.parameters;
var player:String = params.player;
if (evt.info.code == 'NetConnection.Connect.Success') {
ns = new NetStream(nc);
cam = Camera.getCamera();
if(cam == null)
{
Alert.show("没有发现摄像头","提示")
}
mic = Microphone.getMicrophone();
setupCameraMic();
ns.attachAudio(mic);
ns.attachCamera(cam);
var vi:Video = new Video();
vi.width = videoDisplay.width;
vi.height = videoDisplay.height;
vi.attachCamera(cam);
videoDisplay.addChild(vi);
// live 直播不录制, record 边直播边录制
ns.publish(player, recordCheck.selected?"record":"live");
}
else
{
Alert.show("直播服务器连接已断开","提示")
}
}
/***
***设置摄像头和麦克风的参数
***/
private function setupCameraMic():void
{
cam = Camera.getCamera();
cam.setMode(320, 240, 30);
cam.setQuality(0,70);
mic = Microphone.getMicrophone();
mic.rate = 11;
mic.setSilenceLevel(0);
}
/***
***停止直播
***/
private function stopClick():void
{
clickHandler("0");
nc.close();
ns.close();
playButton.enabled = true;
stopButton.enabled = false;
recordCheck.enabled = true;
}
public function onBWCheck(...arg):void
{
//do nothing
}
public function onBWDone(...arg):void
{
//do nothing
}
//更新直播状态
public function clickHandler(status:String):void
{
if(FlexGlobals.topLevelApplication.parameters.roomid==""){
Alert.show("用户名或密码不能为空","提示");return;
}
statusService.request.roomId=FlexGlobals.topLevelApplication.parameters.roomid;
statusService.request.status=status;
statusService.send();
}
]]>
选择录制的话,会在Red5服务器的streams目录下生成“直播流名.flv”文件。
">
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="../jsp/include/taglibs.jsp"%>
JWPlayer
上面的file:"stream1477358653196"是直播流的名字,如果是播放资源的话,改成file:"video.mp4"即可。
ffmpeg -i "rtmp://192.168.8.79:1937/red5/play live=1" -strict -2 -c:v libx264 -c:a aac -f hls "D:\apache-tomcat-8.0.9\webapps\resourcemanager\streams\room\hls\hls.m3u8"
注意:
ffmpeg.exe -i "rtmp://192.168.8.79:1936/vod/video live=1" -i "rtmp://192.168.8.79:1936/vod/audio live=1" -strict -2 -c:v libx264 -c:a aac -f hls D:\apache-tomcat-8.0.9\webapps\mediamanager\streams\room\sun\sun.m3u8
③ 在手机上放两个播放器,一个播放音频,一个播放视频,还是卡死。