Flash+fms视频录制在项目中的实际应用
Flash+fms视频录制在项目中的实际应用
前言:以下只是记录本人在项目中的应用,而flash+fms视频录制有多种实现方式,具体可根据实际情况而定!
1:古人云:工欲善其事,必先利其器,首先安装flash+flash media server(fms),以下主要介绍fms,具体下载以及安装过程略!安装完成之后,可以在windows所有程序Adobe文件夹中找到如下:

接下来 点击 (start adobe media server 5)开启服务,之后,如图:

打开控制台,在接一下关于控制台的一些介绍就省略了(更多详情网上很多,可以自行搜索!)
2:接下来在看看fms对应那些文件夹是我们需要多了解的(只是针对视频录制方面):

以上几个文件夹中,重点说一下conf文件夹,因为在实际项目中,如果需要把录制的视频文件直接放到我们自定义的文件夹下面,那么需要在conf文件夹下的ams.ini 中添加对应的站点文件夹路径,举例如下截图:

注:以上 (e:\webtemp\video.abc.com\为服务器上站点路径),这样在视频录制完成之后,视频就会保存到自己设定的文件夹中了,更多关于fms的还需要自己去查询资料学习(我知道的已差不多就这些了......)
3:flash编写as(actionScript)代码:具体代码如下(代码实现方式多种多样,以下只是其中一种实现方式,仅供参考):
as代码:
package
{
import flash.display.MovieClip;
import flash.media.*;
import flash.display.*;
import flash.net.*;
//import fl.controls.*;
import flash.events.*;
import flash.geom.*;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.display.MovieClip;
import flash.net.Responder;
import flash.events.MouseEvent;
import flash.events.NetStatusEvent;
import flash.events.AsyncErrorEvent;
import fl.motion.MotionEvent;
import flash.utils.Timer;
import flash.external.ExternalInterface;
import flash.utils.ByteArray;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.net.URLRequest;
import flash.net.navigateToURL;
//需要在脚本设置里面添加abobe核心类库
import com.adobe.images.JPGEncoder;
public class ASflashVideo extends Sprite
{
private var cam:Camera;
private var nc:NetConnection;
private var ns:NetStream = null;
private var myVideo:Video;
private var mic:Microphone;
private var mystage:Stage;
private var videoName:String = null;
private var flag:Boolean = false;
private var bitmapData:BitmapData = null;
public function ASflashVideo():void
{
//注册JavaScript:;
/*方法名用as开头表示此方法是js与as交互的方法*/
ExternalInterface.addCallback("asInit",Init);
ExternalInterface.addCallback("asStartRecord",StartRecord);
ExternalInterface.addCallback("asStopRecord",StopRecord);
ExternalInterface.addCallback("asPlayBackVideo",PlayBackVideo);
//截图:;
ExternalInterface.addCallback("asPrintScreen",PrintScreen);
}
/*初始化,连接fms*/
public function Init(fmsUrl:String):void
{
nc = new NetConnection();
nc.addEventListener(NetStatusEvent.NET_STATUS,onNetStatus);
nc.connect("rtmp://"+fmsUrl);
}
public function onNetStatus(event:NetStatusEvent):Boolean
{
trace(event.info.code);
if (event.info.code == "NetConnection.Connect.Success")
{
ExternalInterface.call("Tips","连接服务器成功!");
return true;
}
else if (event.info.code=="NetStream.Play.Stop")
{
//监听回放处理:
this.ns.pause();
ExternalInterface.call("Tips","视频回放结束!");
return true;
}
else
{
return false;
}
}
/*点击开始录像
初始化摄像头,当用户点击了允许之后才开始录像
*/
public function StartRecord(myVideoName:String):Boolean
{
videoName = myVideoName;
if (flag)
{
ExternalInterface.call("Tips","您刚才点击了拒绝摄像头请重新刷新页面");
}
else
{
ExternalInterface.call("Tips","录像名称为:"+videoName);
}
cam = Camera.getCamera();
//判断是否有摄像头:
if (cam!=null)
{
//初始化摄像头到舞台:(监听用户点击事件)
cam.addEventListener(StatusEvent.STATUS,statusHandler);
//默认为320*240
myVideo = new Video();
myVideo.width = 640;
myVideo.height = 480;
cam.setQuality(0,80);
myVideo.x = 10;
myVideo.y = 10;
//设置带宽与图片品质;
cam.setMode(640,480,20,false);
cam.setLoopback(true);
//设置压缩:;
myVideo.attachCamera(cam);
addChild(myVideo);
return true;
}
else
{
return false;
}
}
/*捕捉用户点击按钮行为*/
public function statusHandler(event:StatusEvent):void
{
switch (event.code)
{
case "Camera.Muted" :
trace("User clicked Deny.");
//将监听事件注册到JavaScript:
flag = true;
ExternalInterface.call("Tips","您点击了拒绝调用摄像头!");
break;
case "Camera.Unmuted" :
trace("User clicked Accept.");
//(用户点击了接受)
//开始录像:
mic = Microphone.getMicrophone();
ns = new NetStream(nc);
ns.attachCamera(cam);
ns.attachAudio(mic);
ns.publish(""+videoName+"","record");
break;
}
}
/*停止录像*/
public function StopRecord():void
{
this.myVideo.attachCamera(null);
this.myVideo.clear();
this.ns.attachCamera(null);
this.ns.close();
ExternalInterface.call("Tips","视频录像已经停止!");
}
public function PlayBackVideo()
{
if (videoName!=null)
{
this.ns.play(videoName);
this.myVideo.attachNetStream(this.ns);
//监听回放完成!
this.ns.addEventListener(NetStatusEvent.NET_STATUS,onNetStatus);
}
else
{
ExternalInterface.call("Tips","当前没有录像可以回放!");
}
}
/*截图*/
public function PrintScreen():void
{
var jpgSource:BitmapData = new BitmapData(this.myVideo.width,this.myVideo.height);
jpgSource.draw(this.myVideo);
var jpgEncoder:JPGEncoder = new JPGEncoder(85);
var jpgStream:ByteArray = jpgEncoder.encode(jpgSource);
var header:URLRequestHeader = new URLRequestHeader("Content-type","application/octet-stream");
//此处只是随便写的URL,做请求演示(以下URL将会被重定向,http状态码:302-200),实际过程中需要在后台代码中读取流并转换为图片:
var jpgURLRequest:URLRequest = new URLRequest("http://www.baidu.com?name=myVideo.jpg");
jpgURLRequest.requestHeaders.push(header);
jpgURLRequest.method = URLRequestMethod.POST;
jpgURLRequest.data = jpgStream;
var uploadURLLoader:URLLoader = new URLLoader();
//可以添加监听事件
uploadURLLoader.load(jpgURLRequest);
ExternalInterface.call("Tips","ok");
}
}
}
view 代码:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<script src="Scripts/jquery-1.10.2.min.js"></script>
</head>
<body>
<div style="width: 640px; height: 480px">
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="640" height="480"
id="ASflashVideo" align="middle">
<!--<param name="flashVars" value="VW=640&VH=480&VFPS=20&VQ=80" />-->
<param name="movie" value="ASflashVideo.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="#000000" />
<param name="play" value="true" />
<param name="loop" value="true" />
<param name="wmode" value="window" />
<param name="scale" value="showall" />
<param name="menu" value="true" />
<param name="devicefont" value="false" />
<param name="salign" value="" />
<param name="allowScriptAccess" value="always" />
<!--[if !IE]>-->
<object type="application/x-shockwave-flash" data="ASflashVideo.swf"
width="640" height="480" id="ASflashVideo">
<!--<param name="flashVars" value="VW=640&VH=480&VFPS=20&VQ=80" />-->
<param name="movie" value="ASflashVideo.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="#000000" />
<param name="play" value="true" />
<param name="loop" value="true" />
<param name="wmode" value="window" />
<param name="scale" value="showall" />
<param name="menu" value="true" />
<param name="devicefont" value="false" />
<param name="salign" value="" />
<param name="allowScriptAccess" value="always" />
<!--<![endif]-->
<a href="http://www.adobe.com/go/getflash">
<img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif"
alt="获得 Adobe Flash Player" />
</a>
<!--[if !IE]>-->
</object>
<!--<![endif]-->
</object>
</div>
<div>
请输入录像名称:<input type="text" id="videoName" />
<input type="button" onclick="StartRecord()" value="开始录像" />
<!--<input type="button" onclick="Init()" value="初始化" />-->
<input type="button" onclick="Stop()" value="停止录制" />
<input type="button" onclick="PlayBackVideo()" value="回放" />
<input type="button" onclick="PrintScreen()" value="截图" /> </div>
</body>
</html>
<script type="text/javascript">
var swfObject = null;
var fmsUrl = "localhost/testFms"; //页面加载完成之后再执行:
window.onload = function () {
Init();
}; function Init() {
getSWFObject();
if (swfObject != null) {
swfObject.asInit(fmsUrl);
console.log("初始化完成!");
} else {
alert("未能获取到对象!");
}
} function StartRecord() {
var videoName = $("#videoName").val();
if (videoName.length > 0) { var flag=swfObject.asStartRecord(videoName);
console.log(flag);
} else {
alert("录像名称不能为空!");
}
}
function Stop() {
swfObject.asStopRecord();
}
//回放:
function PlayBackVideo()
{ swfObject.asPlayBackVideo();
}
function PrintScreen() {
var videoName = $("#videoName").val();
swfObject.asPrintScreen();
}
//信息提示:
function Tips(para)
{
alert(para);
} //获取swf对象:
function getSWFObject() {
var movieName = "ASflashVideo";
if (document[movieName]) {
swfObject = document[movieName];
} else if (window[movieName]) {
swfObject = window[movieName];
} else if (document.embeds && document.embeds[movieName]) {
swfObject = document.embeds[movieName];
} else {
swfObject = document.getElementById(movieName);
}
} </script>
4:在编写as代码需要注意的地方(应该是我之前不会的地方),在需要使用到Adobe核心类库的时候:

5:实现效果图:

tips:实际项目需要在后台代码中将流转换成图片:

6:最后,相关学习资料:
--------------------flash as在线API 文档 -----------------------------------
http://help.adobe.com/zh_CN/FlashPlatform/reference/actionscript/3/flash/external/ExternalInterface.html
--------------------flash+fms入门教程----------------------------------------
http://www.nshen.net/article/2007-08-29/fms-tutorial/
-------------------flash+fms 跨域,安全沙箱 -----------------------------
参考:http://scn.sap.com/thread/3307666
--------------------------------------------------------------------------
adobe核心类库as3corelib-.93.zip下载地址:
http://pan.baidu.com/s/1c0hR7rE
-------------------------------------------------------------------------
Flash+fms视频录制在项目中的实际应用的更多相关文章
- android 视频录制 混淆打包 之native层 异常的解决
原文地址:http://www.cnblogs.com/linguanh/ (滑至文章末,直接看解决方法) 问题起因: 前5天,因为项目里面有个类似 仿微信 视频录制的功能, 先是上网找了个 开 ...
- Android开发笔记——视频录制播放常见问题
本文分享自己在视频录制播放过程中遇到的一些问题,主要包括: 视频录制流程 视频预览及SurfaceHolder 视频清晰度及文件大小 视频文件旋转 一.视频录制流程 以微信为例,其录制触发为按下(住) ...
- [AS3.0] FMS改变录制视频的默认地址
FMS默认的视频录制或点播的地址是在{FMS-Install-Dir}\applications,如何指向到其他目录. 1.改变applications的目录指向: 在FMS安装目录下找到/conf/ ...
- Android 中使用MediaRecorder进行录像详解(视频录制)
在这里给出自己的一个测试DEMO,里面注释很详细.简单的视频录制功能. package com.video; import java.io.IOException; import android.ap ...
- java项目中使用ffmpeg剪辑部分视频
在项目中,有个需求是分享视频链接地址到微信.qq或者朋友圈,只能试看两分钟,本想着通过h5界面就能控制实现效果,代码如下,但是前端终究不是安全的,其次监听事件,如果拉播放进度条,中途停顿多次,就会出现 ...
- Fms3和Flex打造在线视频录制和回放
本博推荐文章快速导航: Sql Server2005 Transact-SQL 新兵器学习MCAD学习 代码阅读总结 ASP.NET状态管理 DB(数据库)WAPWinFormFlex,Fms aie ...
- github视频录制播放相关功能-参考
lookingstars/JZVideoDemo 视频播放器 Updated on 11 Aug Objective-C 15 10 caoguoqing/VideoEditDemo iOS vi ...
- iOS开发系列--音频播放、录音、视频播放、拍照、视频录制
--iOS多媒体 概览 随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制, ...
- iOS 视频录制、压缩、上传
项目中实现功能 视频的录制.压缩.上传 首先调用系统的相机或相册 iOS录制的视频是mov格式的,安卓和PC不支持,因此要转换成MP4,并且要压缩. 获取到视频或者照片,处理的方法 下面两个方法是获取 ...
随机推荐
- windows 8下配置PLSQLDeveloper
Win 8 64位系统上安装64 位Oracle,但是没有64位的PL/SQL,不能连接Oracle数据库,怎么办呢?方法是有的:我们可以通过安装32位的Oracle客户端来实现连接. 工具/原料 P ...
- Note3 :《集体智慧编程》用户相似度计算
欧几里德距离评价: 以经过人们一致评价的物品为坐标轴,然后将参与评价的人绘制到图上,并考察他们彼此之间的距离远近.计算出每一轴向上的差值,求平方之后再相加,最后对总和取平方根. # -*- codin ...
- 《图形学》实验七:中点Bresenham算法画椭圆
开发环境: VC++6.0,OpenGL 实验内容: 使用中点Bresenham算法画椭圆. 实验结果: 代码: #include <gl/glut.h> #define WIDTH 50 ...
- Unix系统引导过程(简单步骤)
1.从MBR中读取引导加载程序(boot loader) 2.初始化内核 3.硬件检测 4.创建内核进程 5.系统管理员干预(仅仅在进入单用户模式或者恢复模式的时候) 6.执行系统启动脚本
- Oracle的优化器介绍
Oracle优化器介绍 本文讲述了Oracle优化器的概念.工作原理和使用方法,兼顾了Oracle8i.9i以及最新的10g三个版本.理解本文将有助于您更好的更有效的进行SQL优化工作. RBO优化器 ...
- AutoMapper搬运工之自定义类型转换
前言 最近还挺忙,还有点累,一直都没更新了,实在是懒呀.正题之前先说点别的,最近公司要扩张了,需要大量开发,领导说推荐有钱可以拿,如此好机会,我就趁机做个广告.ShippingRen.com招募.NE ...
- java中方法的重写与重载的区别
重载: 方法名相同,但是参数必须有区别(参数不同可以使类型不同,顺序不同,个数不同).前提: 同一个类中,方法名相同,参数列表不同的2个或多个方法构成方法的重载 参数列表不同指参数的类型,参数的个数, ...
- HDU 2069 Coin Change(完全背包变种)
题意:给你5种银币,50 25 10 5 1,问你可以拼成x的所有可能情况个数,注意总个数不超过100个 组合数问题,一看就是完全背包问题,关键就是总数不超过100个.所有我们开二维dp[k][j], ...
- html学习第二天—— 第七章——CSS样式基本知识
外部式css样式,写在单独的一个文件中外部式css样式(也可称为外联式)就是把css代码写一个单独的外部文件中,这个css样式文件以“.css”为扩展名,在<head>内(不是在<s ...
- PHP无限极分类
当你学习php无限极分类的时候,大家都觉得一个字“难”我也觉得很难,所以,现在都还在看,因为工作要用到,所以,就必须得研究研究. 到网上一搜php无限极分类,很多,但好多都是一个,并且,写的很乱, ...