Я сделал приложение AIR, которое передает голос между двумя компьютерами, это код:
package
{
import fl.controls.List;
import flash.events.ProgressEvent;
import flash.events.SampleDataEvent;
import flash.events.ServerSocketConnectEvent;
import flash.media.Microphone;
import flash.media.Sound;
import flash.net.ServerSocket;
import flash.net.Socket;
import flash.utils.ByteArray;
import flash.system.System;
public class VoiceCommunication
{
private var soundBytes:ByteArray;
private var mic:Microphone;
private var voiceReceiver:ServerSocket;
private var voiceSender:Socket;
private var mLocalIP:String;
private var mRemoteIP:String;
private var mPort:uint;
private var sound:Sound;
private var sample:Number;
public function VoiceCommunication(localIP:String, port:uint)
{
mLocalIP = localIP;
mPort = port;
}
public function startSendingVoice(remoteIP:String = null):void
{
mic = Microphone.getMicrophone();//2-null
mic.gain = 100;
mic.rate = 44;
voiceSender = new Socket();//3-null
mRemoteIP = remoteIP;//5-null
mic.addEventListener(SampleDataEvent.SAMPLE_DATA, micSampleDataHandler);//1-remove eventlistener
}
protected function micSampleDataHandler(event:SampleDataEvent):void
{
if(mRemoteIP != null)
{
voiceSender.connect(mRemoteIP, mPort);
while(event.data.bytesAvailable)
{
sample = event.data.readFloat();
voiceSender.writeFloat(sample);
}
voiceSender.flush();
}
}
public function startReceivingVoice():void
{
voiceReceiver = new ServerSocket;//2
voiceReceiver.bind(mPort, mLocalIP);
voiceReceiver.addEventListener(ServerSocketConnectEvent.CONNECT, handleConnection);//1
voiceReceiver.listen();
}
protected function handleConnection(event:ServerSocketConnectEvent):void
{
var s:Socket = event.socket as Socket;
s.addEventListener(ProgressEvent.SOCKET_DATA, handleData);
}
protected function handleData(event:ProgressEvent):void
{
event.target.removeEventListener(ProgressEvent.SOCKET_DATA, handleData);
var s:Socket = event.target as Socket;
soundBytes = null;
soundBytes = new ByteArray();//3
s.readBytes(soundBytes);
playSound();
s = null;
}
private function playSound():void
{
soundBytes.position = 0;
sound = null;
sound = new Sound();//5
sound.addEventListener(SampleDataEvent.SAMPLE_DATA, playbackSampleHandler, false, 0, true);//4
sound.play();
}
protected function playbackSampleHandler(event:SampleDataEvent):void
{
sound.removeEventListener(SampleDataEvent.SAMPLE_DATA, playbackSampleHandler);
for (var i:int = 0; i < 8192 && soundBytes.bytesAvailable > 0; i++)
{
sample = soundBytes.readFloat();
event.data.writeFloat(sample);
event.data.writeFloat(sample);
}
System.gc();
}
public function destroySender():void
{
mic.removeEventListener(SampleDataEvent.SAMPLE_DATA, micSampleDataHandler);
mic = null;
voiceSender = null;
mRemoteIP = null;
System.gc();
}
public function destroyReceiver():void
{
voiceReceiver.removeEventListener(ServerSocketConnectEvent.CONNECT, handleConnection);//1
voiceReceiver = null;
soundBytes = null;
sound.removeEventListener(SampleDataEvent.SAMPLE_DATA, playbackSampleHandler);
sound = null;
System.gc();
}
}
}
Это работает нормально, и когда я попробовал, он отправил голос, но проблема в том, что отправка голоса идет слишком медленно и разделяется. Так есть ли лучший способ сделать это?
Я переписал его с помощью датаграммы, но это не сработало, код:
package
{
import fl.controls.List;
import flash.events.DatagramSocketDataEvent;
import flash.events.ProgressEvent;
import flash.events.SampleDataEvent;
import flash.events.ServerSocketConnectEvent;
import flash.media.Microphone;
import flash.media.Sound;
import flash.net.DatagramSocket;
import flash.net.ServerSocket;
import flash.net.Socket;
import flash.system.System;
import flash.utils.ByteArray;
public class VoiceComm
{
private var soundBytes:ByteArray;
private var mic:Microphone;
private var socket:DatagramSocket
private var mList:List;
private var mLocalIP:String;
private var mRemoteIP:String;
private var mPort:uint;
private var sound:Sound;
private var sample:Number;
private var bytesToBeSent:ByteArray;
public function VoiceComm(localIP:String, port:uint)
{
socket = new DatagramSocket();
mLocalIP = localIP;
mPort = port;
}
public function startSendingVoice(remoteIP:String = null):void
{
mic = Microphone.getMicrophone();
mic.gain = 100;
mic.rate = 44;
mRemoteIP = remoteIP;
mic.addEventListener(SampleDataEvent.SAMPLE_DATA, micSampleDataHandler);
}
protected function micSampleDataHandler(event:SampleDataEvent):void
{
var sample:Number;
if(mRemoteIP != null)
{
while(event.data.bytesAvailable)
{
sample = event.data.readFloat();
bytesToBeSent = null;
bytesToBeSent = new ByteArray();
bytesToBeSent.writeFloat(sample);
socket.send(bytesToBeSent, 0, 0, mRemoteIP, mPort);
}
}
}
public function startReceivingVoice():void
{
socket.bind(mPort, mLocalIP);
socket.addEventListener(DatagramSocketDataEvent.DATA, handleData);
socket.receive();
}
protected function handleData(event:DatagramSocketDataEvent):void
{
trace("Data inthere!");
soundBytes = null;
soundBytes = new ByteArray();//3
event.data.readBytes(soundBytes);
playSound();
}
private function playSound():void
{
soundBytes.position = 0;
sound = null;
sound = new Sound();//5
sound.addEventListener(SampleDataEvent.SAMPLE_DATA, playbackSampleHandler, false, 0, true);//4
sound.play();
}
protected function playbackSampleHandler(event:SampleDataEvent):void
{
sound.removeEventListener(SampleDataEvent.SAMPLE_DATA, playbackSampleHandler);
for (var i:int = 0; i < 8192 && soundBytes.bytesAvailable > 0; i++)
{
sample = soundBytes.readFloat();
event.data.writeFloat(sample);
event.data.writeFloat(sample);
}
System.gc();
}
public function destroySender():void
{
mic.removeEventListener(SampleDataEvent.SAMPLE_DATA, micSampleDataHandler);
mic = null;
mList = null;
mRemoteIP = null;
System.gc();
}
public function destroyReceiver():void
{
soundBytes = null;
sound.removeEventListener(SampleDataEvent.SAMPLE_DATA, playbackSampleHandler);
sound = null;
System.gc();
}
}
}
** Обновление:
Код после модификации:
package
{
import fl.controls.List;
import flash.events.DatagramSocketDataEvent;
import flash.events.SampleDataEvent;
import flash.media.Microphone;
import flash.media.Sound;
import flash.net.DatagramSocket;
import flash.net.Socket;
import flash.system.System;
import flash.utils.ByteArray;
public class VoiceComm
{
private var mic:Microphone;
private var soundBytes:ByteArray;
private var sample:Number;
private var sound:Sound;
private var socket:DatagramSocket;
private var mLocalIP:String;
private var mPort:uint;
private var mRemoteIP:String;
private var receivedBytes:ByteArray;
public function VoiceComm(localIP:String, port:uint)
{
socket = new DatagramSocket();
mLocalIP = localIP;
mPort = port;
}
//destroyers:
public function destroySender():void
{
mic.removeEventListener(SampleDataEvent.SAMPLE_DATA, sampleData);
mic = null;
soundBytes = null;
System.gc();
}
public function destroyReceiver():void
{
socket.removeEventListener(DatagramSocketDataEvent.DATA, playSound);
receivedBytes = null;
System.gc();
}
//sending part
public function startSendingVoice(ip:String = null):void
{
mRemoteIP = ip;
mic = Microphone.getMicrophone();
mic.rate = 44;
mic.gain = 100;
mic.addEventListener(SampleDataEvent.SAMPLE_DATA, sampleData);
}
protected function sampleData(event:SampleDataEvent):void
{
soundBytes = new ByteArray();
while(event.data.bytesAvailable)
{
var sample:Number = event.data.readFloat();
soundBytes.writeFloat(sample);
}
if(mRemoteIP != null)
{
event.data.position = 0;
socket.send(soundBytes, 0, event.data.length, mRemoteIP, mPort);
}
}
//receiving part
public function startReceivingVoice():void
{
socket.bind(mPort, mLocalIP);
socket.addEventListener(DatagramSocketDataEvent.DATA, playSound);
socket.receive();
}
protected function playSound(event:DatagramSocketDataEvent):void
{
trace("got data!");
receivedBytes = new ByteArray();
event.data.readBytes(receivedBytes);
receivedBytes.position = 0;
var sound:Sound = new Sound();
sound.addEventListener(SampleDataEvent.SAMPLE_DATA, playbackSampleHandler, false, 0, true);
sound.play();
}
protected function playbackSampleHandler(event:SampleDataEvent):void
{
trace("Playing Sound...");
for (var i:int = 0; i < 8192 && receivedBytes.bytesAvailable > 0; i++)
{
var sample:Number = receivedBytes.readFloat();
event.data.writeFloat(sample);
event.data.writeFloat(sample);
System.gc();
}
}
}
}