博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
流媒体服务器搭建实例——可实现录音,录像功能
阅读量:6507 次
发布时间:2019-06-24

本文共 10683 字,大约阅读时间需要 35 分钟。

流媒体服务器搭建实例

由于我也是刚开始接触这个东东,原理什么的不是很清楚,这里我就不说了,免得误人子弟,嘿嘿!

第一步,下载FlashMediaServer3.5,网上有很多资源,这里就不提供了,大家google一下就可以了,这里给一个序列号:1373-5209-5319-9982-4515-7002,我用地就是这一个。安装完后,打开FlashMediaServer3.5服务,一个是Start Adobe Flash Media Server 3.5.2,另一个是Start Flash Media Administration Server 3.5.2。

第二步:在FlashMediaServer3.5安装目录下的applications文件夹下新建一个测试文件夹“tests”。这个文件夹后面会用到。

第三步:下载Flex Builder 3,地址我也不提供了,网上google一下,有很多资源的。安装Flex Builder3

第四步:编写录音,录像程序MyTest。这里的代码是从网上扒的。原文地址: 其中修改了一下我服务器的地址,具体代码如下:

View Code
t_hs_control.enabled=false; t_btn_play.enabled = false; t_btn_stop.enabled = false; t_btn_rec.enabled = false; t_btn_save.enabled = false; t_lbl_rec.visible = false; initCameraAndMic(); //初始化摄像头 } //初始化摄像头 //判断是否存在摄像头和访问权限 private function initCameraAndMic():void {
_camera = Camera.getCamera(); if(_camera != null) {
_camera.addEventListener(StatusEvent.STATUS,__onStatusHandler); _camera.setMode(320,420,30); //t_flv_video.attachCamera(_camera); _localVideo = new Video(); _localVideo.width = 320; _localVideo.height = 240; _localVideo.attachCamera(_camera); t_flv_video.addChild(_localVideo); } _mic = Microphone.getMicrophone(); if(_mic != null) {
//未添加侦听麦克连接状态 //设置本自本地的麦克风的音频传送到本地系统扬声器 /* _mic.setUseEchoSuppression(true); _mic.setLoopBack(true); */ _mic.setSilenceLevel(0,-1); //设置麦克风保持活动状态并持续接收集音频数据 _mic.gain = 80; //设置麦克风声音大小 } } //开始录制视频 //检测网络连接状态 private function beginOrShowRecVideo():void {
_netConnection = new NetConnection(); _netConnection.addEventListener(NetStatusEvent.NET_STATUS,__onNetStatusHandler); _netConnection.addEventListener(SecurityErrorEvent.SECURITY_ERROR,__onSecurityErrorHandler); _netConnection.connect(_videoServerURL); } //录制视频,向服务器传送视频及音频流 private function beginRecConnectStream():void {
if(_localVideo != null) {
_localVideo.clear(); t_flv_video.removeChild(_localVideo); _localVideo = new Video(); _localVideo.width = 320; _localVideo.height = 240; _localVideo.attachCamera(_camera); t_flv_video.addChild(_localVideo); } _outStream = new NetStream(_netConnection); _outStream.attachCamera(_camera); _outStream.attachAudio(_mic); _outStream.publish("testVideo","record"); } //播放视频 private function showRecConnectStream():void {
_inStream = new NetStream(_netConnection); _inStream.addEventListener(NetStatusEvent.NET_STATUS,__onNetStatusHandler); _inStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR,__onStreamErrorHandler); //定义onMetaData,获取视频相关数据 var customClient:Object = new Object(); customClient.onMetaData = function(metadata:Object):void {
_duration = metadata.duration; //获取视频持续时间 t_hs_control.maximum = _duration; //设置播放进度条最大值 } _inStream.client = customClient; //删除原_localVideo,便于在录制和播放视频之间切换 _localVideo.clear(); t_flv_video.removeChild(_localVideo); _localVideo = new Video(); _localVideo.width = 320; _localVideo.height = 240; _localVideo.attachNetStream(_inStream); _inStream.play("testVideo"); t_flv_video.addChild(_localVideo); } //播放按钮点击后事件:播放视频,同时分析是否播放来调整BUTTON上的标签,显示为播放或者暂停; //并监听播放器 private function flvplay(event:Event):void{
t_hs_control.enabled=true; t_btn_stop.enabled = true; t_btn_rec.enabled = false; if(!isplaying) {
isplaying = true; beginOrShowRecVideo(); } else {
_inStream.togglePause(); //自动在停止和播放之间切换 } if(isplaying) {
if(ispauseing){
t_btn_play.label="播放" }else {
t_btn_play.label="暂停" } ispauseing = !ispauseing; } addEventListener(Event.ENTER_FRAME,__onEnterFrame); } //停止按钮和视频播放完毕 //重设一些值变量、按钮enabled值等 private function resetSomeParam():void {
_inStream.close(); t_btn_play.label = "播放"; t_lbl_playtime.text = "0:00 / "+ formatTimes(_duration); t_hs_control.value = 0; isplaying = false; ispauseing = false; t_hs_control.enabled=false; t_btn_rec.enabled = true; t_btn_stop.enabled = false; } //停止播放按钮点击事件:停止视频,同时调整相关BUTTON上的标签 private function flvStop(event:Event):void {
resetSomeParam(); removeEventListener(Event.ENTER_FRAME,__onEnterFrame); } //拉动进度条 private function thumbPress(event:SliderEvent):void{
_inStream.togglePause(); removeEventListener(Event.ENTER_FRAME,__onEnterFrame); } //进度条改变后,得到的值赋予PLAYPOSITION; private function thumbChanges(event:SliderEvent):void{
playPosition = t_hs_control.value; } //放开进度条,再把PLAYPOSITION的值发给播放器; private function thumbRelease(event:SliderEvent):void{
_inStream.seek(playPosition); _inStream.togglePause(); addEventListener(Event.ENTER_FRAME,__onEnterFrame); } //声音音量控制 private function sound_thumbChanges(event:SliderEvent):void{
soundPosition = hs_sound.value; } private function sound_thumbRelease(event:SliderEvent):void{
t_flv_video.volume = soundPosition; } //格式化时间 private function formatTimes(value:int):String{
var result:String = (value % 60).toString(); if (result.length == 1){
result = Math.floor(value / 60).toString() + ":0" + result; } else {
result = Math.floor(value / 60).toString() + ":" + result; } return result; } //录制按钮点击后事件:录制视频,同时分析是否播放来调整BUTTON上的标签,显示为开始录制或者停止录制; //并监听播放器 private function recVideo(event:MouseEvent):void {
if(!isrecing) //开始录制 {
isrecing = true; t_btn_rec.label = "停止录制"; t_btn_play.enabled = false; t_btn_save.enabled = false; t_lbl_rec.visible = true; beginOrShowRecVideo(); } else //停止录制 {
isrecing = false; t_btn_rec.label = "开始录制"; t_btn_play.enabled = true; t_btn_save.enabled = true; t_lbl_rec.visible = false; _outStream.close(); } } //检测摄像头权限事件 private function __onStatusHandler(event:StatusEvent):void {
if(!_camera.muted) {
t_btn_rec.enabled = true; } else {
trace("错误:无法链接到活动摄像头!") } _camera.removeEventListener(StatusEvent.STATUS,__onStatusHandler); } //网络链接事件 //如果网络连接成功,开始录制或观看视频 private function __onNetStatusHandler(event:NetStatusEvent):void {
switch (event.info.code) {
case "NetConnection.Connect.Success": if(isrecing) {
beginRecConnectStream(); } else {
showRecConnectStream(); } break; case "NetConnection.Connect.Failed": trace("连接失败!"); break; case "NetStream.Play.StreamNotFound": trace("Stream not found: " + event); break; } } private function __onSecurityErrorHandler(event:SecurityErrorEvent):void {
trace("securityErrorHandler:" + event); } private function __onStreamErrorHandler(event:AsyncErrorEvent):void {
trace(event.error.message); } //播放视频实时事件 //实时更改播放进度条值和播放时间值,当视频播放完成时删除实时侦听事件并重新设置一些初始值 private function __onEnterFrame(event:Event):void {
if(_duration > 0 && _inStream.time > 0) {
t_hs_control.value =_inStream.time; t_lbl_playtime.text = formatTimes(_inStream.time) + " / "+ formatTimes(_duration); } if(_inStream.time == _duration) {
removeEventListener(Event.ENTER_FRAME,__onEnterFrame); resetSomeParam(); } } ]]>

第五步:编写同步播放的程序VideoPlayer,这个也是从网上扒的,原文地址: 我修改了服务器地址,由于源码是flex4的,所以我修改成了Flex3。我的代码如下:

videoConfig.xml

View Code
rtmp://192.168.2.105/tests/
testVideo.flv

VideoEvent.as

View Code
package {
import flash.events.EventDispatcher; public class VideoEvent extends EventDispatcher {
// 静态常量,定义事件类型 public static const VidoPlay:String="VideoPlay"; // 静态实例 private static var _instance:VideoEvent; public static function getInstance():VideoEvent {
if(_instance==null) _instance=new VideoEvent(); return _instance; } } }

VideoPlayer.mxml

View Code
//发送读取配置的请求 myService.send(); //定义视频播放事件监听 instance.addEventListener("VideoPlay",playVideoHandler); } //视频监听的处理 private function playVideoHandler(event:Event):void {
var myVideo:SharedObject; //将播放头置于视频开始处 myVideo=SharedObject.getLocal("videoCookie"); var vName:String=myVideo.data.vName; //播放选中的视频 film.source=filmSource+vName; } private function changeSource():void {
var myVideo:SharedObject; //将播放头置于视频开始处 myVideo=SharedObject.getLocal("videoCookie"); //将视频的文件名称,存放到共享文件里 myVideo.data.vName="DarkKnight.flv"; //一定要先存放VCODE到共享对象里,再分发事件 instance.dispatchEvent(new Event("VideoPlay")); } //读取配置文件 private function resultHandler(event:ResultEvent):void {
//获取流媒体服务器 地址 filmSource=event.result.videoConfig.item.rtmpUrl; //获取流媒体文件名 var filmName:String=event.result.videoConfig.item.filmName; //获取流媒体完整路径 film.source=filmSource+filmName; } ]]>

第六步:运行,效果图如下:左图是录像,右图是播放。

(注意:本文中的程序在现实运行中,播放的画面比实时录像的画面要延时几秒钟,谁有更好的解决方案,请不吝赐教!谢谢)

 

 

 

 

转载地址:http://xzzfo.baihongyu.com/

你可能感兴趣的文章
Ansible自动化运维配置与应用(结合实例)
查看>>
下面简要介绍软件工程的七条原理
查看>>
Lua(三)——语句
查看>>
怎么看电脑有没有安装USB3.0驱动
查看>>
overflow清除浮动的原理
查看>>
Spring Boot 使用parent方式引用时 获取值属性方式默认@
查看>>
解决maven下载jar慢的问题(如何更换Maven下载源)
查看>>
linux安装gitLab
查看>>
concurrent包的实现示意图
查看>>
golang os.Args
查看>>
Linux常用命令
查看>>
spring-data-elasticsearch 概述及入门(二)
查看>>
1.12 xshell密钥认证
查看>>
3.2 用户组管理
查看>>
ibatis 动态查询
查看>>
汇编语言之实验一
查看>>
git 调用 Beyond Compare
查看>>
SQL基础-->层次化查询(START BY ... CONNECT BY PRIOR)[转]
查看>>
android实现图片识别的几种方法
查看>>
mvc学习地址
查看>>