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视频录制在项目中的实际应用的更多相关文章

  1. android 视频录制 混淆打包 之native层 异常的解决

    原文地址:http://www.cnblogs.com/linguanh/    (滑至文章末,直接看解决方法) 问题起因: 前5天,因为项目里面有个类似 仿微信 视频录制的功能, 先是上网找了个 开 ...

  2. Android开发笔记——视频录制播放常见问题

    本文分享自己在视频录制播放过程中遇到的一些问题,主要包括: 视频录制流程 视频预览及SurfaceHolder 视频清晰度及文件大小 视频文件旋转 一.视频录制流程 以微信为例,其录制触发为按下(住) ...

  3. [AS3.0] FMS改变录制视频的默认地址

    FMS默认的视频录制或点播的地址是在{FMS-Install-Dir}\applications,如何指向到其他目录. 1.改变applications的目录指向: 在FMS安装目录下找到/conf/ ...

  4. Android 中使用MediaRecorder进行录像详解(视频录制)

    在这里给出自己的一个测试DEMO,里面注释很详细.简单的视频录制功能. package com.video; import java.io.IOException; import android.ap ...

  5. java项目中使用ffmpeg剪辑部分视频

    在项目中,有个需求是分享视频链接地址到微信.qq或者朋友圈,只能试看两分钟,本想着通过h5界面就能控制实现效果,代码如下,但是前端终究不是安全的,其次监听事件,如果拉播放进度条,中途停顿多次,就会出现 ...

  6. Fms3和Flex打造在线视频录制和回放

    本博推荐文章快速导航: Sql Server2005 Transact-SQL 新兵器学习MCAD学习 代码阅读总结 ASP.NET状态管理 DB(数据库)WAPWinFormFlex,Fms aie ...

  7. github视频录制播放相关功能-参考

    lookingstars/JZVideoDemo  视频播放器 Updated on 11 Aug Objective-C 15 10 caoguoqing/VideoEditDemo  iOS vi ...

  8. iOS开发系列--音频播放、录音、视频播放、拍照、视频录制

    --iOS多媒体 概览 随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制, ...

  9. iOS 视频录制、压缩、上传

    项目中实现功能 视频的录制.压缩.上传 首先调用系统的相机或相册 iOS录制的视频是mov格式的,安卓和PC不支持,因此要转换成MP4,并且要压缩. 获取到视频或者照片,处理的方法 下面两个方法是获取 ...

随机推荐

  1. 这两年在QQGame写过的游戏(2012.7.15-2014.8.25)

    [雷电]  Gamebryo         http://qqgamecdnimg.qq.com/help/rule177.html [英雄杀]          http://yxs.qq.com ...

  2. 你不知道的this—JS异步编程中的this

    Javascript小学生都知道了javascript中的函数调用时会 隐性的接收两个附加的参数:this和arguments.参数this在javascript编程中占据中非常重要的地位,它的值取决 ...

  3. NPOI导出Excel - 自动适应中文宽度(帮助类下载)

    前言 做了好几个Excel.Word导出,用了HTTP流导出伪Excel文件.用过Office组件(这东西在生产环境下相当麻烦,各种权限,**). 最后决定使用NPOI组件来导出,好处很多很多了,这里 ...

  4. C# 先说IEnumerable,我们每天用的foreach你真的懂它吗?

    原文: http://www.cnblogs.com/zhaopei/p/5769782.html

  5. 【转】ArrayList循环遍历并删除元素的常见陷阱

    转自:https://my.oschina.net/u/2249714/blog/612753?p=1 在工作和学习中,经常碰到删除ArrayList里面的某个元素,看似一个很简单的问题,却很容易出b ...

  6. Leetcode Edit Distance

    Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...

  7. Unity Lightmap动态加载研究

    什么情况下需要Lightmap? 移动平台上目前暂时还不能开实时光影效果,会卡成幻灯片.所以就需要将光影烘焙到贴图上. 什么情况下需要动态加载Lightmap? 1.当项目抛弃了Unity的多场景模式 ...

  8. PHP与apache环境配置

    最近想了解一些网页后台的东西,在看Luke Welling,laura Thomson的<php与mysql web开发>,书中环境配置的部分很庞杂,网上的各种教程也很乱,搞了一下午终于成 ...

  9. UVa #11582 Colossal Fibonacci Numbers!

    巨大的斐波那契数 The i'th Fibonacci number f (i) is recursively defined in the following way: f (0) = 0 and  ...

  10. 序列流 SequenceInputStream

    SequenceInputStream:序列流,对多个流进行合并. SequenceInputStream 表示其他输入流的逻辑串联.它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末 ...