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