2011年8月4日 星期四

[教學] 在流動電話的Camera + Peer-to-peer (P2P)

由AIR 2.6 開始, 可以在iOS 與Android 之間使用Camera, 我們配合P2P 技術, 可以簡單地模仿Apple 的Facetime 功能, 並且能跨平台使用.

範例製作條件:
  1. 兩個能執行Adobe AIR 的電話
  2. 一個Flash Media Server 4, 我們可以用Adobe 公開伺服器 (rtmfp://stratus.adobe.com/) 作試驗
範例功能:
  • 開啟程式後, 打開相機, 自動分享相機視訊, 雙方能夠在電話互相看見對方.
範例使用類別說明:
  • NetConnection - 會在用戶端與伺服器之間建立雙向連線
  • NetGroup - 實體代表 RTMFP 群組的成員資格
  • NetStream - 會在 NetConnection 上開啟單向串流通道
  • Camera - 從用戶端系統的攝影機擷取視訊


Step 1: 建立連線 (NetConnection 物件)
_nc.addEventListener(NetStatusEvent.NET_STATUS, netStatus);
_nc.connect(SERVER+DEVKEY+"/");

Step 2: 建立P2P 群組 (NetGroup 物件)
var gs:GroupSpecifier = new GroupSpecifier("marcoGroup/g041");
gs.postingEnabled = true;
gs.routingEnabled = true;
gs.serverChannelEnabled = true;
var ng:NetGroup = new NetGroup(_nc, gs.groupspecWithAuthorizations());
ng.addEventListener(NetStatusEvent.NET_STATUS, netStatus);

Step 3: 建立串流 (NetStream 物件)
var ns:NetStream = new NetStream(nc ,NetStream.DIRECT_CONNECTIONS);
ns.addEventListener(NetStatusEvent.NET_STATUS,netStatus);
ns.publish("media");

Step 4 : 開啟相機 (Camera 物件)
var camera:Camera = Camera.getCamera();
if (camera){
 var ui:UIComponent = new UIComponent();
 var width:int = 320;
 var video:Video = new Video(width, width);
 camera.setMode(320, 240, 24.);
 camera.setQuality(1638400, 85);
 video.attachCamera(camera);
 ui.name = _nc.nearID;
 ui.height = width;
 ui.addChild(video);
 vGroup.addElement(ui);
}

Step 5: 當相機開啟後, 將相機與串流聯繫
_ns.attachCamera(_camera);

Step 6: 完成設定後 (或有新用戶完成設定), 把串流身分號碼發送給其他用戶
var message:Object = new Object();
message.nearID = nearID;
ng.sendToAllNeighbors(message);

Step 7: 最後, 假如有新用戶發送串流身分號碼, 便以該串流建立視訊影像
var ui:UIComponent = vGroup.getChildByName(nearID) as UIComponent;
var ns:NetStream = new NetStream(nc, nearID);
ns.play("media");
ns.client = this;

var width:int = 320;
var video:Video = new Video(width, width);
ui = new UIComponent();
ui.name = nearID;
ui.addChild(video);
video.attachNetStream(ns);
vGroup.addElement(ui);

只要理解製作流程, 可以簡單在流動電話上, 完成視訊串流.
大家可以 [下載], 然後一齊玩玩視像通訊.

注意事項:
  • 使用Android 電話作測試平台, 請確定android.permission.INTERNET 和android.permission.CAMERA 權限是開啟

參考資料: http://www.adobe.com/devnet/flashmediaserver/articles/p2p_apps_cirrus_lccs.html

10 則留言:

瑞 提到...

你好,小弟對Flex不熟想實作p2pcamera,以下方式是上網查的但是出現一些問題想像您請教.
我是用FlexSDK 4.6 中的mxmlc p2pcamera.mxml 指令來產生p2pcamera.swf出現一些訊息如下:

必要的RSL:
http://fpdownload.adobe.com/pub/swz/flex/4.6.0.23201/framework_4.6.0.23201.swz 具有1次容錯移轉.
http://fpdownload.adobe.com/pub/swz/tlf/2.0.0.232/textLayout_2.0.0.232.swz 具有1次容錯移轉.
http://fpdownload.adobe.com/pub/swz/flex/4.6.0.23201/spark_4.6.0.23201.swz 具有1次容錯移轉.

再用adt指令adt -package -target apk -storetype pkcs12 -keystone D:\flexsdk46\cert.p12 p2pcamera.apk p2pcamera.mxml p2pcamera.swf 來產生apk.
出現錯誤.
D:\flexsdk46\bin\p2pcamera.mxml: error 102 Invalid namespace library://ns.adobe.com/flex/spark

請問你是如何產生apk file.

Turtler 提到...

我主要用Adobe Flash Professional 或Adobe Flash Builder 產生apk 檔.

以Flash Builder 4.7 為例, 它內建Adobe AIR 3.4 SDK. 我們可以簡單地按一鍵, 產生apk 檔, 不需理會adt 指令如何設定, 這方法較為簡便.

你是否使用eclipse, 然後下載FlexSDK 配合編寫?

瑞 提到...

你好,謝謝您.因為Flash Builder試用期60天,所以才會選擇用指令的方式來做.
而我將Adobe AIR 3.6 SDK換成你說Adobe AIR 3.4 SDK就OK了.太神奇了.謝謝你的幫忙.

瑞 提到...

你好,請問_nc.connect(SERVER+DEVKEY+"/");是不是要改成_nc.connect("rtmfp://xxx.xxx.xxx.xxx");
xxx.xxx.xxx.xxx是FMS server的IP address.
謝謝

Turtler 提到...

正確,SERVER+DEVKEY是FMS 的IP address 和application 名字.

若你已安裝FMS 於同一電腦上, 可以輸入rtmfp://localhost/ 路徑。

而DEVKEY 是一個application 名字, 當中會包含onAppStart, onConnect, onDisconnect 和onAppStop 四個基本動作,內容請參考:
http://flash-adobe.blogspot.hk/2011/10/flash-builder-flash-media-server-fms.html
http://flash-adobe.blogspot.hk/2011/10/flash_11.html

若不自構FMS, 可以利用Adobe 的公開測試server:
rtmfp://stratus.adobe.com/
DEVKEY 需要向Adobe 申請。

瑞 提到...

你好,謝謝您的解釋.我向Adobe 申請了DEVKEY將它填入private const DEVKEY:String = "b7c91353b93c18af12aa73e2-3a866bf4xxxx";其他code部分不變.放到手機執行出現netStatus:NetConnection.Connect.Failed訊息.還有請問p2pcamera.apk執行後還要去執行相機程式嗎?

Turtler 提到...

連接網路和相機, 都是必要. 在Android 手機中運行, 要確定開啟以下兩個權限:
android.permission.INTERNET
android.permission.CAMERA

我建議先在電腦執行, 只要電腦有連接WebCam, 設定上與Android 手機沒有分別, 可以簡化除錯程序.

瑞 提到...

你好,謝謝你的說明.可以了.果真是權限沒有開啟.感謝你的幫忙.

匿名 提到...

你好!我請問版主是否有遇到過跟我一樣的困境,
環境 我是用FLASH AIR3.2 3.4 3.8 但部分手機使用camera , 輸出GPU 跟DIRECT, APP待機再打開之後會導致黑屏的狀況,而輸出CPU是變成輸入文字時會導致黑屏,

測試的手機為samsung GT I8190N 以及小米機

android 版本皆為 4.1.2

Turtler 提到...

你好,這問題相信是Adobe AIR 的Bug, 已經有人提交問題給Adobe 處理.

解決方法是:
1) Need Flex 4.9.0
2) renderMode needs to be set to "gpu" in *-app.xml.
3) Air 3.6 works with above

參考連結:
http://forums.adobe.com/thread/1173838