Flex 迷你教程 — 基于Stratus的P2P网络电话 (3)

Posted by Kevin Luo at 17 January 2009

Category: Flex 迷你教程, P2P

Tags: , , ,

Flex 迷你教程 — 基于Stratus的P2P网络电话 (2)中我们已经知道如何链接一个客户端并且互相发送短信,今天来扩展下面的这些内容

  1. 呼叫时在被呼叫端显示 “接受”,点击接受后双方建立链接。
  2. 呼叫试或者接通后可以挂机。
  3. 添加视频与音频通信。

首先来看看Demo:

Demo 操作:

1. 输入任意名称,点击链接 (两台机器或者两个浏览器)
2. 输入对方的peerId,点击呼叫
3. 被呼叫方点击 “接受” 建立链接。
4. 开始语音,视频,文字通讯.
5. 挂机

Demo地址:

http://flextheworld.com/flash/p2p/P2pPhoneDemo.html

Demo截图:

e59bbee78987-1

新添加的代码

首先是修改call() function, 根据不同的label执行不同的事件,如果callYou.label是 “接受”,执行accpetHandle()与呼叫者建立链接,如果是”挂断”,那么执行hangup()挂断双方的通讯,如果是其他(也就是”呼叫”),则执行后面的内容。

呼叫时调用publishVide和publishAudio将视频与音频附加到outgoingStream发送。在onConnectSuccesss事件中播放被呼叫者返回的视频和音频。监听onHangup事件来控制挂断。呼叫时将“呼叫”改为“挂断”。

?View Code ACTIONSCRIPT3
//呼叫对方的方法,现在是呼叫者角色
private function call():void{
 
if(callYou.label == "接受"){
accpetHandle();
callYou.label = "挂断"
return;
}else if(callYou.label == "挂断"){
outgoingStream.send("onHangup")
this.hangup()
 
return;
}
 
...............
 
//发送视频
publishVideo();
//发送音频
publishAudio()
 
..........
 
//监听onConnectSuccess事件,确定链接成功
i.onConnectSuccess = function(name:String):void
{
info.text += "与"+name + "链接成功n";
sendMessageBtn.enabled = true;
incomingStream.receiveAudio(true)
incomingStream.receiveAudio(true)
remoteVideo = new Video();
remoteVideo.width = 160;
remoteVideo.height = 120;
remoteVideo.attachNetStream(incomingStream);
remoteVideoDisplay.addChild(remoteVideo);
sendMessageBtn.enabled = true;
}
 
i.onHangup = function():void{
hangup()
}
 
incomingStream.client = i
 
callYou.label = "挂断"

被呼叫者在监听到呼叫者的呼叫时不马上回应,只是提示被呼叫者 “正在被链接”,同时将“呼叫”改为“接受”, 监听onHangup事件

?View Code ACTIONSCRIPT3
private function initSendStream():void{
 
..........
 
//监听onPeerConnect事件
var o:Object = new Object();
o.onPeerConnect = function(subscriberStream:NetStream):Boolean
{
..........
 
incomingStream.receiveAudio(false)
incomingStream.receiveAudio(false)
..........
 
//监听onIncomingCall事件,用于确定链接成功
i.onIncomingCall = function(name:String):void
{
//显示链接成功后,对呼叫者发布我的信息流,名称为callee
info.text += name + " 正在呼叫你n";
callYou.label = "接受"
}
 
i.onHangup = function():void{
hangup()
}
incomingStream.client = i;
 
return true;
}
 
myStream.client = o;
}

点击“接受”后,开始向呼叫者发送信息流,包括视频与音频。同时播放呼叫者发送的视频与音频,最后发出onConnectSuccess事件

?View Code ACTIONSCRIPT3
//同意链接后,发送stream到呼叫端,包括音频,视频的发送。 同时播放呼叫端发出的视频,音频
private function accpetHandle():void{
//向呼叫端发送信息流
outgoingStream = new NetStream(netConnection, NetStream.DIRECT_CONNECTIONS);
outgoingStream.addEventListener(NetStatusEvent.NET_STATUS, outgoingStreamHandler);
outgoingStream.publish("callee");
//将视频,音频附加到outgoingStream
publishAudio();
publishVideo()
 
//播放接受到的视频,音频
incomingStream.receiveAudio(true)
incomingStream.receiveAudio(true)
remoteVideo = new Video();
remoteVideo.width = 160;
remoteVideo.height = 120;
remoteVideo.attachNetStream(incomingStream);
remoteVideoDisplay.addChild(remoteVideo);
//链接成功事件,呼叫端响应
outgoingStream.send("onConnectSuccess",userName.text);
sendMessageBtn.enabled = true;
}

点击挂机后在上面提到的call()中执行hangup(), 同时发送onHangup事件,这样另一方也能挂断电话。挂机后将”挂机”再改为”呼叫”,允许下一次的呼叫和链接

?View Code ACTIONSCRIPT3
//挂断电话,清空所有stream,只保持于stratus的链接
public function hangup():void{
if (incomingStream){
incomingStream.close();
incomingStream.removeEventListener(NetStatusEvent.NET_STATUS, incomingStreamHandler);
}
 
if (outgoingStream){
outgoingStream.close();
outgoingStream.removeEventListener(NetStatusEvent.NET_STATUS, outgoingStreamHandler);
}
 
if (controlStream){
controlStream.close();
controlStream.removeEventListener(NetStatusEvent.NET_STATUS, netStreamHandler);
}
 
incomingStream = null;
outgoingStream = null;
controlStream = null;
if(localVideo != null){
localVideo.attachCamera(null)
}
 
if(remoteVideo != null){
remoteVideo.attachCamera(null)
}
 
info.text += "挂机!"
callYou.label = "呼叫"
sendMessageBtn.enabled = false;
}

publishVideo和publishAudio function

?View Code ACTIONSCRIPT3
//发送视频
private function publishVideo():void{
var cameras:Array = Camera.names;
var camera:Camera;
var findDefaultCamera:Boolean = false
if (cameras && cameras.length >0){
for(var j:int=0; j<cameras.length; j++){
if(cameras[j].toString() == "USB Video Class Video"){
camera = Camera.getCamera(j.toString())
outgoingStream.attachCamera(camera);
findDefaultCamera = true
}
}
if(!findDefaultCamera){
camera = Camera.getCamera()
outgoingStream.attachCamera(camera)
}
camera.setQuality(0,90)
 
localVideo = new Video();
localVideo.width = 160;
localVideo.height = 120;
localVideo.attachCamera(camera)
localVideoDisplay.addChild(localVideo);
}
}
//发送音频
private function publishAudio():void{
var mics:Array = Microphone.names;
if (mics && mics.length >0){
outgoingStream.attachAudio(Microphone.getMicrophone(0))
}
}

源文件下载 (装了一个类似论坛的回复才能下载的插件,试试)


P2pPhoneDemo3 (459)

322 Comments

  1. luming says

    回复的真快啊,帖子还是热乎的,赶紧研究一下。
    前面的教程非常精彩,有问题再请教了,谢谢。

    Reply

Leave a Reply

Leave a Reply
  • (required)
  • (required) (will not be published)