Merge branch 'master' of github.com:bigbluebutton/bigbluebutton

This commit is contained in:
Marco Calderon 2011-02-24 16:40:23 +00:00
commit 43046a7338
14 changed files with 581 additions and 516 deletions

View File

@ -19,12 +19,7 @@
**/
package org.bigbluebutton.voiceconf.red5.media;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.net.DatagramSocket;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import org.apache.mina.core.buffer.IoBuffer;
import org.bigbluebutton.voiceconf.red5.media.transcoder.FlashToSipTranscoder;
import org.bigbluebutton.voiceconf.red5.media.transcoder.TranscodedAudioDataListener;
@ -40,13 +35,6 @@ import org.slf4j.Logger;
public class FlashToSipAudioStream {
private final static Logger log = Red5LoggerFactory.getLogger(FlashToSipAudioStream.class, "sip");
private final PipedOutputStream streamFromFlash;
private PipedInputStream streamToSip;
private final Executor exec = Executors.newSingleThreadExecutor();
private Runnable audioDataProcessor;
private volatile boolean processAudioData = false;
private final FlashToSipTranscoder transcoder;
private IStreamListener mInputListener;
@ -54,24 +42,21 @@ public class FlashToSipAudioStream {
private final SipConnectInfo connInfo;
private String talkStreamName;
private RtpStreamSender rtpSender;
public FlashToSipAudioStream(final FlashToSipTranscoder transcoder, DatagramSocket srcSocket, SipConnectInfo connInfo) {
private TranscodedAudioListener transcodedAudioListener;
public FlashToSipAudioStream(final FlashToSipTranscoder transcoder, DatagramSocket srcSocket,
SipConnectInfo connInfo) {
this.transcoder = transcoder;
this.srcSocket = srcSocket;
this.connInfo = connInfo;
talkStreamName = "microphone_" + System.currentTimeMillis();
streamFromFlash = new PipedOutputStream();
try {
streamToSip = new PipedInputStream(streamFromFlash);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
transcodedAudioListener = new TranscodedAudioListener();
transcoder.setTranscodedAudioListener(transcodedAudioListener);
}
public void start(IBroadcastStream broadcastStream, IScope scope) throws StreamException {
log.debug("startTranscodingStream({},{})", broadcastStream.getPublishedName(), scope.getName());
if (log.isDebugEnabled())
log.debug("startTranscodingStream({},{})", broadcastStream.getPublishedName(), scope.getName());
mInputListener = new IStreamListener() {
public void packetReceived(IBroadcastStream broadcastStream, IStreamPacket packet) {
IoBuffer buf = packet.getData();
@ -85,12 +70,8 @@ public class FlashToSipAudioStream {
if (packet instanceof AudioData) {
byte[] data = SerializeUtils.ByteBufferToByteArray(buf);
try {
streamFromFlash.write(data, 1, data.length-1);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Remove the first byte as it is the codec id.
transcoder.handlePacket(data, 1, data.length-1);
}
}
};
@ -98,47 +79,16 @@ public class FlashToSipAudioStream {
broadcastStream.addStreamListener(mInputListener);
rtpSender = new RtpStreamSender(srcSocket, connInfo);
rtpSender.connect();
processAudioData = true;
audioDataProcessor = new Runnable() {
public void run() {
processAudioData();
}
};
exec.execute(audioDataProcessor);
transcoder.start();
}
private void processAudioData() {
int len = 64;
byte[] nellyAudio = new byte[len];
int remaining = len;
int offset = 0;
TranscodedAudioListener transcodedAudioListener = new TranscodedAudioListener();
while (processAudioData) {
try {
int bytesRead = streamToSip.read(nellyAudio, offset, remaining);
remaining -= bytesRead;
if (remaining == 0) {
remaining = len;
offset = 0;
transcoder.transcode(nellyAudio, 0, nellyAudio.length, transcodedAudioListener);
} else {
offset += bytesRead;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void stop(IBroadcastStream broadcastStream, IScope scope) {
broadcastStream.removeStreamListener(mInputListener);
if (broadcastStream != null) {
broadcastStream.stop();
broadcastStream.close();
}
processAudioData = false;
transcoder.stop();
srcSocket.close();
}
@ -146,10 +96,10 @@ public class FlashToSipAudioStream {
return talkStreamName;
}
private class TranscodedAudioListener implements TranscodedAudioDataListener {
public class TranscodedAudioListener implements TranscodedAudioDataListener {
@Override
public void handleTranscodedAudioData(byte[] audioData, long timestamp) {
if (audioData != null && processAudioData) {
if (audioData != null) {
rtpSender.sendAudio(audioData, transcoder.getCodecId(), timestamp);
} else {
log.warn("Transcodec audio is null. Discarding.");

View File

@ -60,12 +60,7 @@ public class RtpStreamReceiver {
}
private void initializeSocket() {
/* try {
rtpSocket.getDatagramSocket().setSoTimeout(SO_TIMEOUT);
} catch (SocketException e1) {
log.warn("SocketException while setting socket block time.");
}
*/ }
}
public void start() {
receivePackets = true;
@ -91,9 +86,6 @@ public class RtpStreamReceiver {
try {
rtpSocket.receive(rtpPacket);
packetReceivedCounter++;
// log.debug("Received packet [" + rtpPacket.getRtcpPayloadType() + "," + rtpPacket.getPayloadType() + ", length=" + rtpPacket.getPayloadLength() + "] seqNum[rtpSeqNum=" + rtpPacket.getSeqNum() + ",lastSeqNum=" + lastSequenceNumber
// + "][rtpTS=" + rtpPacket.getTimestamp() + ",lastTS=" + lastPacketTimestamp + "][port=" + rtpSocket.getDatagramSocket().getLocalPort() + "]");
if (shouldDropDelayedPacket(rtpPacket)) {
continue;
}
@ -107,11 +99,9 @@ public class RtpStreamReceiver {
+ "][rtpTS=" + rtpPacket.getTimestamp() + ",lastTS=" + lastPacketTimestamp + "][port=" + rtpSocket.getDatagramSocket().getLocalPort() + "]");
} else {
if (shouldHandlePacket(rtpPacket)) {
// log.debug("Handling packet [" + rtpPacket.getRtcpPayloadType() + "," + rtpPacket.getPayloadType() + ", length=" + rtpPacket.getPayloadLength() + "] seqNum[rtpSeqNum=" + rtpPacket.getSeqNum() + ",lastSeqNum=" + lastSequenceNumber
// + "][rtpTS=" + rtpPacket.getTimestamp() + ",lastTS=" + lastPacketTimestamp + "][port=" + rtpSocket.getDatagramSocket().getLocalPort() + "]");
lastSequenceNumber = rtpPacket.getSeqNum();
lastPacketTimestamp = rtpPacket.getTimestamp();
processRtpPacket(internalBuffer, RTP_HEADER_SIZE, payloadLength);
processRtpPacket(internalBuffer, RTP_HEADER_SIZE, rtpPacket.getPayloadLength());
} else {
if (log.isDebugEnabled())
log.debug("Corrupt packet [" + rtpPacket.getRtcpPayloadType() + "," + rtpPacket.getPayloadType() + ", length=" + rtpPacket.getPayloadLength() + "] seqNum[rtpSeqNum=" + rtpPacket.getSeqNum() + ",lastSeqNum=" + lastSequenceNumber

View File

@ -19,12 +19,7 @@
**/
package org.bigbluebutton.voiceconf.red5.media;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.net.DatagramSocket;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import org.apache.mina.core.buffer.IoBuffer;
import org.bigbluebutton.voiceconf.red5.media.transcoder.SipToFlashTranscoder;
import org.bigbluebutton.voiceconf.red5.media.transcoder.TranscodedAudioDataListener;
@ -38,16 +33,8 @@ import org.red5.server.stream.BroadcastScope;
import org.red5.server.stream.IBroadcastScope;
import org.red5.server.stream.IProviderService;
import org.slf4j.Logger;
public class SipToFlashAudioStream implements TranscodedAudioDataListener, RtpStreamReceiverListener {
final private Logger log = Red5LoggerFactory.getLogger(SipToFlashAudioStream.class, "sip");
private final PipedOutputStream streamFromSip;
private PipedInputStream streamToFlash;
private final Executor exec = Executors.newSingleThreadExecutor();
private Runnable audioDataProcessor;
private volatile boolean processAudioData = false;
private static final Logger log = Red5LoggerFactory.getLogger(SipToFlashAudioStream.class, "sip");
private AudioBroadcastStream audioBroadcastStream;
private IScope scope;
@ -78,17 +65,10 @@ public class SipToFlashAudioStream implements TranscodedAudioDataListener, RtpSt
rtpStreamReceiver.setRtpStreamReceiverListener(this);
listenStreamName = "speaker_" + System.currentTimeMillis();
scope.setName(listenStreamName);
streamFromSip = new PipedOutputStream();
try {
streamToFlash = new PipedInputStream(streamFromSip);
startNow();
mBuffer = IoBuffer.allocate(1024);
mBuffer = mBuffer.setAutoExpand(true);
audioData = new AudioData();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mBuffer = IoBuffer.allocate(1024);
mBuffer = mBuffer.setAutoExpand(true);
audioData = new AudioData();
transcoder.setTranscodedAudioListener(this);
}
public String getStreamName() {
@ -100,26 +80,22 @@ public class SipToFlashAudioStream implements TranscodedAudioDataListener, RtpSt
}
public void stop() {
log.debug("Stopping stream for {}", listenStreamName);
processAudioData = false;
if (log.isDebugEnabled()) log.debug("Stopping stream for {}", listenStreamName);
transcoder.stop();
rtpStreamReceiver.stop();
log.debug("Stopped RTP Stream Receiver for {}", listenStreamName);
if (log.isDebugEnabled()) log.debug("Stopped RTP Stream Receiver for {}", listenStreamName);
if (audioBroadcastStream != null) {
audioBroadcastStream.stop();
log.debug("Stopped audioBroadcastStream for {}", listenStreamName);
if (log.isDebugEnabled()) log.debug("Stopped audioBroadcastStream for {}", listenStreamName);
audioBroadcastStream.close();
log.debug("Closed audioBroadcastStream for {}", listenStreamName);
if (log.isDebugEnabled()) log.debug("Closed audioBroadcastStream for {}", listenStreamName);
} else
log.debug("audioBroadcastStream is null, couldn't stop");
log.debug("Stream(s) stopped");
if (log.isDebugEnabled()) log.debug("audioBroadcastStream is null, couldn't stop");
if (log.isDebugEnabled()) log.debug("Stream(s) stopped");
}
public void start() {
}
private void startNow() {
log.debug("started publishing stream in " + scope.getName());
public void start() {
if (log.isDebugEnabled()) log.debug("started publishing stream in " + scope.getName());
audioBroadcastStream = new AudioBroadcastStream(listenStreamName);
audioBroadcastStream.setPublishedName(listenStreamName);
audioBroadcastStream.setScope(scope);
@ -136,42 +112,10 @@ public class SipToFlashAudioStream implements TranscodedAudioDataListener, RtpSt
}
audioBroadcastStream.start();
processAudioData = true;
audioDataProcessor = new Runnable() {
public void run() {
processAudioData();
}
};
exec.execute(audioDataProcessor);
transcoder.start();
rtpStreamReceiver.start();
}
private void processAudioData() {
int len = 160;
byte[] pcmAudio = new byte[len];
int remaining = len;
int offset = 0;
while (processAudioData) {
try {
int bytesRead = streamToFlash.read(pcmAudio, offset, remaining);
remaining -= bytesRead;
if (remaining == 0) {
remaining = len;
offset = 0;
transcoder.transcode(pcmAudio, this);
} else {
offset += bytesRead;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void onStoppedReceiving() {
if (observer != null) observer.onStreamStopped();
@ -179,12 +123,7 @@ public class SipToFlashAudioStream implements TranscodedAudioDataListener, RtpSt
@Override
public void onAudioDataReceived(byte[] audioData, int offset, int len) {
try {
streamFromSip.write(audioData, offset, len);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
transcoder.handleData(audioData, offset, len);
}
@Override

View File

@ -19,9 +19,14 @@
**/
package org.bigbluebutton.voiceconf.red5.media.transcoder;
public interface FlashToSipTranscoder {
void transcode(byte[] audioData, int startOffset, int length, TranscodedAudioDataListener listener);
import org.bigbluebutton.voiceconf.red5.media.FlashToSipAudioStream.TranscodedAudioListener;
public interface FlashToSipTranscoder {
void transcode(byte[] audioData, int startOffset, int length);
void handlePacket(byte[] data, int begin, int end);
int getOutgoingEncodedFrameSize();
int getCodecId();
void setTranscodedAudioListener(TranscodedAudioListener transcodedAudioListener);
void start();
void stop();
}

View File

@ -19,10 +19,16 @@
**/
package org.bigbluebutton.voiceconf.red5.media.transcoder;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.nio.FloatBuffer;
import java.util.Random;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import org.slf4j.Logger;
import org.bigbluebutton.voiceconf.red5.media.FlashToSipAudioStream.TranscodedAudioListener;
import org.red5.logging.Red5LoggerFactory;
import org.red5.app.sip.codecs.Codec;
import org.red5.app.sip.codecs.asao.Decoder;
@ -65,6 +71,14 @@ public class NellyFlashToSipTranscoderImp implements FlashToSipTranscoder {
private long timestamp = 0;
private final static int TS_INCREMENT = 180; // Determined from PCAP traces.
private final PipedOutputStream streamFromFlash;
private PipedInputStream streamToSip;
private final Executor exec = Executors.newSingleThreadExecutor();
private Runnable audioDataProcessor;
private volatile boolean processAudioData = false;
private TranscodedAudioListener transcodedAudioListener;
/**
* The transcode process works by taking a 64-byte-array Nelly audio and converting it into a 256-float-array L16 audio. From the
* 256-float-array L16 audio, we take 160-float-array and convert it to a 160-byte-array Ulaw audio. The remaining 96-float-array
@ -79,6 +93,25 @@ public class NellyFlashToSipTranscoderImp implements FlashToSipTranscoder {
Random rgen = new Random();
timestamp = rgen.nextInt(1000);
viewBuffer = l16Audio.asReadOnlyBuffer();
streamFromFlash = new PipedOutputStream();
try {
streamToSip = new PipedInputStream(streamFromFlash);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void start() {
processAudioData = true;
audioDataProcessor = new Runnable() {
public void run() {
processAudioData();
}
};
exec.execute(audioDataProcessor);
}
@Override
@ -91,10 +124,44 @@ public class NellyFlashToSipTranscoderImp implements FlashToSipTranscoder {
return sipCodec.getCodecId();
}
@Override
public void handlePacket(byte[] data, int begin, int end) {
try {
streamFromFlash.write(data, begin, end);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void processAudioData() {
int len = 64;
byte[] nellyAudio = new byte[len];
int remaining = len;
int offset = 0;
while (processAudioData) {
try {
int bytesRead = streamToSip.read(nellyAudio, offset, remaining);
remaining -= bytesRead;
if (remaining == 0) {
remaining = len;
offset = 0;
transcode(nellyAudio, 0, nellyAudio.length);
} else {
offset += bytesRead;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void transcode(byte[] audioData, int startOffset, int length, TranscodedAudioDataListener listener) {
public void transcode(byte[] audioData, int startOffset, int length) {
if (audioData.length != NELLY_AUDIO_LENGTH) {
log.warn("Receiving bad nelly audio. Expecting {}, got {}.", NELLY_AUDIO_LENGTH, audioData.length);
if (log.isWarnEnabled()) log.warn("Receiving bad nelly audio. Expecting {}, got {}.", NELLY_AUDIO_LENGTH, audioData.length);
return;
}
@ -111,7 +178,7 @@ public class NellyFlashToSipTranscoderImp implements FlashToSipTranscoder {
int encodedBytes = sipCodec.pcmToCodec(tempUlawBuffer, ulawEncodedBuffer);
// Send it to the server
listener.handleTranscodedAudioData(ulawEncodedBuffer, timestamp += TS_INCREMENT);
transcodedAudioListener.handleTranscodedAudioData(ulawEncodedBuffer, timestamp += TS_INCREMENT);
if (l16Audio.position() == l16Audio.capacity()) {
/**
@ -125,7 +192,7 @@ public class NellyFlashToSipTranscoderImp implements FlashToSipTranscoder {
viewBuffer.get(tempUlawBuffer);
encodedBytes = sipCodec.pcmToCodec(tempUlawBuffer, ulawEncodedBuffer);
if (encodedBytes == sipCodec.getOutgoingEncodedFrameSize()) {
listener.handleTranscodedAudioData(ulawEncodedBuffer, timestamp += TS_INCREMENT);
transcodedAudioListener.handleTranscodedAudioData(ulawEncodedBuffer, timestamp += TS_INCREMENT);
} else {
log.error("Failure encoding buffer." );
}
@ -134,7 +201,7 @@ public class NellyFlashToSipTranscoderImp implements FlashToSipTranscoder {
viewBuffer.get(tempUlawBuffer);
encodedBytes = sipCodec.pcmToCodec(tempUlawBuffer, ulawEncodedBuffer);
if (encodedBytes == sipCodec.getOutgoingEncodedFrameSize()) {
listener.handleTranscodedAudioData(ulawEncodedBuffer, timestamp += TS_INCREMENT);
transcodedAudioListener.handleTranscodedAudioData(ulawEncodedBuffer, timestamp += TS_INCREMENT);
} else {
log.error("Failure encoding buffer." );
}
@ -143,7 +210,7 @@ public class NellyFlashToSipTranscoderImp implements FlashToSipTranscoder {
viewBuffer.get(tempUlawBuffer);
encodedBytes = sipCodec.pcmToCodec(tempUlawBuffer, ulawEncodedBuffer);
if (encodedBytes == sipCodec.getOutgoingEncodedFrameSize()) {
listener.handleTranscodedAudioData(ulawEncodedBuffer, timestamp += TS_INCREMENT);
transcodedAudioListener.handleTranscodedAudioData(ulawEncodedBuffer, timestamp += TS_INCREMENT);
} else {
log.error("Failure encoding buffer." );
}
@ -153,4 +220,14 @@ public class NellyFlashToSipTranscoderImp implements FlashToSipTranscoder {
viewBuffer.clear();
}
}
public void setTranscodedAudioListener(TranscodedAudioListener transcodedAudioListener) {
this.transcodedAudioListener = transcodedAudioListener;
}
@Override
public void stop() {
processAudioData = false;
}
}

View File

@ -19,9 +19,16 @@
**/
package org.bigbluebutton.voiceconf.red5.media.transcoder;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.nio.FloatBuffer;
import java.util.Random;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import org.slf4j.Logger;
import org.bigbluebutton.voiceconf.red5.media.SipToFlashAudioStream;
import org.red5.logging.Red5LoggerFactory;
import org.red5.server.api.IConnection;
import org.red5.server.api.Red5;
@ -70,6 +77,14 @@ public class NellySipToFlashTranscoderImp implements SipToFlashTranscoder {
private long timestamp = 0;
private final static int TS_INCREMENT = 32; // Determined from PCAP traces.
private final PipedOutputStream streamFromSip;
private PipedInputStream streamToFlash;
private TranscodedAudioDataListener transcodedAudioListener;
private boolean processAudioData;
private final Executor exec = Executors.newSingleThreadExecutor();
private Runnable audioDataProcessor;
/**
* The transcode takes a 160-byte Ulaw audio and converts it to a 160-float L16 audio. Whenever there is an
* available 256-float L16 audio, that gets converted into a 64-byte Nelly audio. Therefore, 8 Ulaw packets
@ -82,17 +97,23 @@ public class NellySipToFlashTranscoderImp implements SipToFlashTranscoder {
Random rgen = new Random();
timestamp = rgen.nextInt(1000);
viewBuffer = l16Audio.asReadOnlyBuffer();
streamFromSip = new PipedOutputStream();
try {
streamToFlash = new PipedInputStream(streamFromSip);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void transcode(byte[] audioData, TranscodedAudioDataListener listener) {
public void transcode(byte[] audioData) {
if (audioData.length != ULAW_AUDIO_LENGTH) {
log.warn("Received corrupt audio. Got {}, expected {}.", audioData.length, ULAW_AUDIO_LENGTH);
if (log.isWarnEnabled()) log.warn("Received corrupt audio. Got {}, expected {}.", audioData.length, ULAW_AUDIO_LENGTH);
return;
}
// Convert Ulaw to L16
int decodedBytes = audioCodec.codecToPcm(audioData, tempL16Buffer);
audioCodec.codecToPcm(audioData, tempL16Buffer);
// Store into the buffer
l16Audio.put(tempL16Buffer);
@ -114,11 +135,12 @@ public class NellySipToFlashTranscoderImp implements SipToFlashTranscoder {
if (pendingMessages > 25) {
// Message backed up probably due to slow connection to client (25 messages * 20ms ptime = 500ms audio)
sendPacket = false;
log.info("Dropping packet. Connection {} congested with {} pending messages (~500ms worth of audio) .", conn.getClient().getId(), pendingMessages);
if (log.isInfoEnabled())
log.info("Dropping packet. Connection {} congested with {} pending messages (~500ms worth of audio) .", conn.getClient().getId(), pendingMessages);
}
}
if (sendPacket) listener.handleTranscodedAudioData(nellyBytes, timestamp += TS_INCREMENT);
if (sendPacket) transcodedAudioListener.handleTranscodedAudioData(nellyBytes, timestamp += TS_INCREMENT);
}
if (l16Audio.position() == l16Audio.capacity()) {
@ -137,5 +159,63 @@ public class NellySipToFlashTranscoderImp implements SipToFlashTranscoder {
public int getCodecId() {
return NELLYMOSER_CODEC_ID;
}
@Override
public void handleData(byte[] audioData, int offset, int len) {
try {
streamFromSip.write(audioData, offset, len);
} catch (IOException e) {
e.printStackTrace();
}
}
private void processAudioData() {
int len = 160;
byte[] pcmAudio = new byte[len];
int remaining = len;
int offset = 0;
while (processAudioData) {
try {
int bytesRead = streamToFlash.read(pcmAudio, offset, remaining);
remaining -= bytesRead;
if (remaining == 0) {
remaining = len;
offset = 0;
transcode(pcmAudio);
} else {
offset += bytesRead;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void start(){
processAudioData = true;
audioDataProcessor = new Runnable() {
public void run() {
processAudioData();
}
};
exec.execute(audioDataProcessor);
}
@Override
public void stop() {
processAudioData = false;
}
@Override
public void setTranscodedAudioListener(SipToFlashAudioStream sipToFlashAudioStream) {
this.transcodedAudioListener = sipToFlashAudioStream;
}
}

View File

@ -19,8 +19,14 @@
**/
package org.bigbluebutton.voiceconf.red5.media.transcoder;
import org.bigbluebutton.voiceconf.red5.media.SipToFlashAudioStream;
public interface SipToFlashTranscoder {
void transcode(byte[] audioData, TranscodedAudioDataListener listener);
void transcode(byte[] audioData);
int getCodecId();
int getIncomingEncodedFrameSize();
void handleData(byte[] audioData, int offset, int len);
void setTranscodedAudioListener(SipToFlashAudioStream sipToFlashAudioStream);
void start();
void stop();
}

View File

@ -20,16 +20,24 @@
package org.bigbluebutton.voiceconf.red5.media.transcoder;
import java.util.Random;
import org.bigbluebutton.voiceconf.red5.media.FlashToSipAudioStream.TranscodedAudioListener;
import org.red5.app.sip.codecs.Codec;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
/**
* Speex wideband to Speex wideband Flash to SIP transcoder.
* This class is just a passthrough transcoder.
*
*/
public class SpeexFlashToSipTranscoderImp implements FlashToSipTranscoder {
protected static Logger log = Red5LoggerFactory.getLogger(SpeexFlashToSipTranscoderImp.class, "sip");
private Codec audioCodec;
private long timestamp = 0;
private final static int TS_INCREMENT = 320; // Determined from PCAP traces.
private TranscodedAudioListener transcodedAudioListener;
public SpeexFlashToSipTranscoderImp(Codec audioCodec) {
this.audioCodec = audioCodec;
@ -37,10 +45,12 @@ public class SpeexFlashToSipTranscoderImp implements FlashToSipTranscoder {
timestamp = rgen.nextInt(1000);
}
public void transcode(byte[] audioData, int startOffset, int length, TranscodedAudioDataListener listener) {
public void transcode(byte[] audioData, int startOffset, int length) {
byte[] transcodedAudio = new byte[length];
// Just copy the audio data removing the codec id which is the first-byte
// represented by the startOffset var.
System.arraycopy(audioData, startOffset, transcodedAudio, 0, length);
listener.handleTranscodedAudioData(transcodedAudio, timestamp += TS_INCREMENT);
transcodedAudioListener.handleTranscodedAudioData(transcodedAudio, timestamp += TS_INCREMENT);
}
public int getCodecId() {
@ -54,4 +64,24 @@ public class SpeexFlashToSipTranscoderImp implements FlashToSipTranscoder {
public int getOutgoingPacketization() {
return audioCodec.getOutgoingPacketization();
}
@Override
public void handlePacket(byte[] data, int begin, int end) {
transcode(data, begin, end);
}
@Override
public void setTranscodedAudioListener(TranscodedAudioListener transcodedAudioListener) {
this.transcodedAudioListener = transcodedAudioListener;
}
@Override
public void start() {
// do nothing. just implement the interface.
}
@Override
public void stop() {
// do nothing. just implement the interface.
}
}

View File

@ -20,10 +20,17 @@
package org.bigbluebutton.voiceconf.red5.media.transcoder;
import java.util.Random;
import org.bigbluebutton.voiceconf.red5.media.SipToFlashAudioStream;
import org.red5.app.sip.codecs.Codec;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
/**
* Speex wideband to speex wideband Sip to Flash Transcoder.
* This is just a passthrough transcoder.
*
*/
public class SpeexSipToFlashTranscoderImp implements SipToFlashTranscoder {
protected static Logger log = Red5LoggerFactory.getLogger(SpeexSipToFlashTranscoderImp.class, "sip");
@ -31,7 +38,8 @@ public class SpeexSipToFlashTranscoderImp implements SipToFlashTranscoder {
private Codec audioCodec = null;
private long timestamp = 0;
private static final int TS_INCREMENT = 20; // Determined from PCAP traces.
private TranscodedAudioDataListener transcodedAudioListener;
public SpeexSipToFlashTranscoderImp(Codec codec) {
this.audioCodec = codec;
Random rgen = new Random();
@ -39,9 +47,8 @@ public class SpeexSipToFlashTranscoderImp implements SipToFlashTranscoder {
}
@Override
public void transcode(byte[] audioData, TranscodedAudioDataListener listener) {
byte[] codedBuffer = audioData;
listener.handleTranscodedAudioData(codedBuffer, timestamp += TS_INCREMENT);
public void transcode(byte[] audioData ) {
transcodedAudioListener.handleTranscodedAudioData(audioData, timestamp += TS_INCREMENT);
}
@Override
@ -54,5 +61,26 @@ public class SpeexSipToFlashTranscoderImp implements SipToFlashTranscoder {
return audioCodec.getIncomingEncodedFrameSize();
}
@Override
public void handleData(byte[] audioData, int offset, int len) {
byte[] data = new byte[len];
System.arraycopy(audioData, offset, data, 0, len);
transcode(data);
}
@Override
public void setTranscodedAudioListener(SipToFlashAudioStream sipToFlashAudioStream) {
this.transcodedAudioListener = sipToFlashAudioStream;
}
@Override
public void start() {
// do nothing
}
@Override
public void stop() {
// do nothing
}
}

View File

@ -1,182 +1,147 @@
# BigBlueButton.mxml
bbb.pageTitle = BigBlueButton
# MainApplicationShell.mxml
bbb.mainshell.locale.version=0.71
bbb.mainshell.statusInfo = Vennligst vent mens {0} moduler lastes:
bbb.mainshell.statusInfo.loaded = {0}(lastet)
bbb.mainshell.statusInfo.testRTMPConnection = Vennligst vent mens vi tester forbindelsen med serveren.
bbb.mainshell.statusInfo2 = NB: Hvis lastingen stopper kan du prøve å slette nettleserens mellomlager.
bbb.mainshell.statusProgress.testRTMPConnection = Kobler opp til RTMP://{0}:1935/{1}.
bbb.mainshell.statusProgress.testRTMPTConnection = Kobler opp til RTMPT://{0}:80/{1}.
bbb.mainshell.statusProgress.loading = Laster:
bbb.mainshell.statusProgress.loaded = Laster: {0} {1}% lastet.
bbb.mainshell.statusProgress.cannotConnectServer = Beklager, vi kan ikke koble til serveren.
bbb.mainshell.copyrightLabel2 = (c) 2010, BigBlueButton versjon {0} - For mer informasjon se http://www.bigbluebutton.org/.
bbb.mainshell.logBtn.toolTip = Åpne Loggvindu
bbb.mainshell.fullScreenBtn.toolTip = Velg mellom normal visning og hele skjermen
bbb.mainshell.resetLayoutBtn.toolTip = Gjenopprett vinduer
# OldLocaleWarnWIndow.mxml
bbb.oldlocalewindow.reminder1=Du har kanskje en gammel språoversettelse til BigBlueButton #You may have an old language translations of BigBlueButton.
bbb.oldlocalewindow.reminder2=Vennligst slett nettleserens mellomlager
bbb.oldlocalewindow.windowTitle=Advarsel: Gammel språkoversettelse
# LogWindow.mxml
bbb.logwindow.title = Loggvindu
bbb.logwindow.highlight = Markere:
bbb.logwindow.turnLoggingOff = Slå av logging
bbb.logwindow.clearBtn = Slett
bbb.logwindow.refreshBtn = Oppfrisk
# JoinFailedWindow.mxml
bbb.joinFailedWindow.title = Mislykket deltakelse
bbb.joinFailedWindow.okBtn = OK
bbb.joinFailedWindow.failedInfo = Ingen gyldig sesjon. Klikk ok for å logge inn.
# MainToolbar.mxml
bbb.mainToolbar.loggedInUserLbl = {1}: Ring: 613-520-7610 85115
bbb.mainToolbar.helpBtn = Hjelp
bbb.mainToolbar.logoutBtn = Logg ut
bbb.mainToolbar.logoutBtn.toolTip = Logg ut
###### modules ######
# ViewersWindow.mxml
bbb.viewers.title = Brukere{0} {1}
bbb.viewers.viewersGrid.nameItemRenderer = Navn
bbb.viewers.viewersGrid.nameItemRenderer.nameLabel.toolTip = Du er innlogget som denne brukeren.
bbb.viewers.viewersGrid.roleItemRenderer = Rolle
bbb.viewers.viewersGrid.statusItemRenderer = Status
bbb.viewers.viewersGrid.statusItemRenderer.raiseHand.toolTip = Håndsopprekking av {0}
bbb.viewers.viewersGrid.statusItemRenderer.streamIcon.toolTip = Klikk for å se på.
bbb.viewers.viewersGrid.statusItemRenderer.presIcon.toolTip = Presenterer
bbb.viewers.presentBtn.toolTip = Velg deltaker som skal presentere.
bbb.viewers.raiseHandBtn.toolTip = Klikk for håndsopprekking.
bbb.viewers.presentBtn.label = Velg ny presenterer
# Presentation
## PresentationWindow.mxml
bbb.presentation.title = Presentasjon
bbb.presentation.uploadPresBtn = Last opp et dokument til presentasjon.
bbb.presentation.uploadPresBtn.toolTip = Last opp et dokument til presentasjon.
bbb.presentation.backBtn.toolTip = Forrige lysark
bbb.presentation.slideNumLbl =
bbb.presentation.forwardBtn.toolTip = Neste lysark
bbb.presentation.resetZoomBtn.toolTip = Nullstill Zoom
bbb.presentation.presenterNameLbl = {0} er presenterer nå.
bbb.presentation.maximizeRestoreBtn.toolTip = Maksimer dette vinduet
bbb.presentation.maximizeRestoreBtn.toolTip2 = Gjenopprett forrige størrelse
bbb.presentation.clickToUpload = Last opp presentasjon
bbb.presentation.maxUploadFileExceededAlert = Feil: Fila er større enn tillatt.
## PresentationWindowMediator.as
bbb.presentation.presenting = {0} er presenterer nå.
bbb.presentation.pages = {0} / {1}
## FileUploadWindowMediator.as
bbb.presentation.uploadcomplete = Opplasting er fullført. Vennligst vent mens dokumentet konverteres..
bbb.presentation.uploadsuccessful = Opplasting er fullført.
bbb.presentation.uploaded = lastet opp.
bbb.presentation.document.supported = Godkjent dokumenttype. Starter konvertering...
bbb.presentation.document.converted = Vellykket konvertering av dokument.
bbb.presentation.error.document.convert.failed = Feil: Mislykket konvertering av dokument.
bbb.presentation.error.io = IO feil: Vennligst kontakt administrator.
bbb.presentation.error.security = Sikkerhetsfeil: Vennligst kontakt administrator.
bbb.presentation.error.convert.format = Feil: Se etter om fila som ble lastet opp er av gyldig filtype.
bbb.presentation.error.convert.notsupported = Feil: Fila som ble lastet opp er ikke av støttet format. Vennligst last opp en kompatibel fil.
bbb.presentation.error.convert.soffice = Feil: Mislykket konvertering av opplastet dokument.
bbb.presentation.error.convert.nbpage = Feil: Antall sider i dokumentet som ble lastet opp kan ikke bestemes.
bbb.presentation.error.convert.maxnbpagereach = Feil: Dokumentet som ble lastet opp har for mange sider.
bbb.presentation.error.convert.swf = Feil ved konvertering av opplastet dokument. Vennligst ta kontakt med administrator.
bbb.presentation.error.convert.swfimage = Feil ved konvertering av bilde til swf: vennligst se etter om bildet er uten feil eller om formatet er JPG/PNG.
bbb.presentation.error.convert.swfpdf = Feil ved konvertering av PDF til swf: vennligst se etter om PDF fila er uten feil.
bbb.presentation.error.convert.thumbnail = Kan ikke lage ikonbilder. Vennligst ta kontakt med administrator.
bbb.presentation.converted = Konverterte {0} av {1} lysark.
bbb.presentation.extracting = Hentet ut lysark {0} av {1} lysark.
bbb.presentation.ok = OK
bbb.presentation.uploadwindow.presentationfile = Presentasjonsfil
bbb.presentation.uploadwindow.pdf = PDF
bbb.presentation.uploadwindow.word = WORD
bbb.presentation.uploadwindow.excel = EXCEL
bbb.presentation.uploadwindow.powerpoint = POWERPOINT
bbb.presentation.uploadwindow.image = BILDE
## FileUploadWindow.mxml
bbb.fileupload.title = Last opp presentasjon
bbb.fileupload.fileLbl = Fil:
bbb.fileupload.selectBtn.toolTip = Se igjennom fil
bbb.fileupload.uploadBtn = Last opp
bbb.fileupload.uploadBtn.toolTip = Last opp fil
bbb.fileupload.presentationNamesLbl = Presentasjoner som er lastet opp:
bbb.fileupload.deleteBtn.toolTip = Slett presentasjon
bbb.fileupload.showBtn = Vis
bbb.fileupload.showBtn.toolTip = Vis presentasjon
bbb.fileupload.okCancelBtn = Avbryt
bbb.fileupload.progressLbl.uploadSuccessful = Vellykket opplasting. Vent litt mens dokumentet konverteres.
bbb.fileupload.progressBar.uploadSuccessful = Vellykket opplasting.
bbb.fileupload.progressLbl.uploading = {0}% lastet opp.
bbb.fileupload.progressBar.uploading = {0}% lastet opp.
bbb.fileupload.progressLbl.converting = Konverterte {0} av {1} lysark.
bbb.fileupload.progressBar.converting = Konverterte {0} av {1} lysark.
bbb.fileupload.progressLbl.extracting = Hentet ut lysark {0} av {1} lysark.
bbb.fileupload.progressBar.extracting = Hentet ut lysark {0} av {1} lysark.
bbb.fileupload.genThumbText = Lager ikoner..
bbb.fileupload.progBarLbl = Framdrift:
# ChatWindow.mxml
bbb.chat.title = Prat
bbb.chat.cmpColorPicker.toolTip = Tekstfarge
bbb.chat.sendBtn = Send
bbb.chat.sendBtn.toolTip = Send melding
bbb.chat.publicChatUsername = Alle
bbb.chat.publicMsgAwaiting = Melding til alle venter
bbb.chat.publicMsgAwaiting2 = * Melding til alle venter *
bbb.chat.privateMsgAwaiting = privat melding venter
bbb.chat.privateMsgAwaiting2 = * privat melding venter *
bbb.chat.privateChatSelect = Velg person til privat prat
bbb.chat.chatOptions = Innstilliner for prat
bbb.chat.fontSize = Fontstørrelse
# ListenersWindow.mxml
bbb.listeners.title = Lyttere{0} {1}
bbb.listeners.muteAllBtn.toolTip = Slå lyd av hos alle
bbb.listeners.unmuteAllBtn.toolTip = Slå lyd på hos alle
bbb.listeners.ejectBtn.toolTip = Velg hvilken deltaker som skal gå ut.
bbb.listeners.ejectTooltip = Klikk for å sende ut deltaker.
# ListenerItem.mxml
bbb.listenerItem.nameLbl.toolTip = Velg denne deltakeren og trykk knappen for å slå av/på lyden.
bbb.listenerItem.talkImg.toolTip = Snakker
bbb.listenerItem.lockImg.toolTip = Klikk for å beholde på eller av
bbb.listenerItem.muteUnmute.toolTip = Slå av eller på denne lytteren
# PublishWindow.mxml
bbb.publishVideo.title = Opptak av webcam
bbb.publishVideo.startPublishBtn.toolTip = Start opptak
# DesktopPublishWindow.mxml
bbb.desktopPublish.title = Skrivebordsdeling - Forhåndsvisning
bbb.desktopPublish.title = Skrivebordsdeling
bbb.desktopView.fitToWindow = Tilpass vinduet
bbb.desktopView.actualSize = Vis normal størrelse
# ToolbarButton.mxml
bbb.toolbar.phone.toolTip = Start min mikrofon
bbb.toolbar.deskshare.toolTip = Skrivebordsdeling
bbb.toolbar.video.toolTip = Start mitt kamera
# HighlighterToolbar.mxml
bbb.highlighter.toolbar.pencil = Markør
bbb.highlighter.toolbar.ellipse = Sirkel
bbb.highlighter.toolbar.rectangle = Rektangel
bbb.highlighter.toolbar.clear = Slett siden
bbb.highlighter.toolbar.undo = Gjenopprett figur
bbb.highlighter.toolbar.color = Velg farge
bbb.highlighter.toolbar.thickness = Velg tykkelse
# WhiteboardButton.mxml
bbb.highlighter.button.toolTipShow = Vis tavle
bbb.highlighter.button.toolTipHide = Skjul tavle
# BigBlueButton.mxml
bbb.pageTitle = BigBlueButton
# MainApplicationShell.mxml
bbb.mainshell.locale.version=0.71
bbb.mainshell.statusProgress.connecting = Kobler opp til serveren
bbb.mainshell.statusProgress.loading = Laster {0} moduler
bbb.mainshell.statusProgress.cannotConnectServer = Beklager, vi kan ikke koble til serveren
bbb.mainshell.copyrightLabel2 = (c) 2010, BigBlueButton build {0} - Mer informasjon finnes hos http://www.bigbluebutton.org/.
bbb.mainshell.logBtn.toolTip = Åpne loggvindu
bbb.mainshell.resetLayoutBtn.toolTip = Nullstill oppsett
# OldLocaleWarnWIndow.mxml
bbb.oldlocalewindow.reminder1=Du har kanskje en gammel språkoversettelse til BigBlueButton.
bbb.oldlocalewindow.reminder2=Vennligst slett nettleserens mellomlager og prøv igjen.
bbb.oldlocalewindow.windowTitle=Advarsel: Gammel språkoversettelse
# MainToolbar.mxml
bbb.mainToolbar.helpBtn = Hjelp
bbb.mainToolbar.logoutBtn = Logg ut
bbb.mainToolbar.logoutBtn.toolTip = Logg ut
###### modules ######
# Viewers
bbb.viewers.title = Users{0} {1}
bbb.viewers.viewersGrid.nameItemRenderer = Navn
bbb.viewers.viewersGrid.nameItemRenderer.nameLabel.toolTip = Du er logget inn som denne brukeren.
bbb.viewers.viewersGrid.roleItemRenderer = Rolle
bbb.viewers.viewersGrid.statusItemRenderer = Status
bbb.viewers.viewersGrid.statusItemRenderer.raiseHand.toolTip = Håndsopprekking hos {0}
bbb.viewers.viewersGrid.statusItemRenderer.streamIcon.toolTip = Klikk for å se på.
bbb.viewers.viewersGrid.statusItemRenderer.presIcon.toolTip = Presenterer
bbb.viewers.presentBtn.toolTip = Velg deltaker som skal presentere.
bbb.viewers.raiseHandBtn.toolTip = Klikk for håndsopprekking.
bbb.viewers.presentBtn.label = Velg ny presenterer
bbb.viewers.kickUserBtn.toolTip = Send ut bruker
# Presentation
bbb.presentation.title = Presentasjon
bbb.presentation.uploadPresBtn = Last opp dokument til presentasjon.
bbb.presentation.uploadPresBtn.toolTip = Last opp dokument til presentasjon.
bbb.presentation.backBtn.toolTip = Forrige lysark.
bbb.presentation.slideNumLbl.toolTip = Klikk for å velge lysark
bbb.presentation.forwardBtn.toolTip = Neste lysark
bbb.presentation.resetZoomBtn.toolTip = Nullstill zoom
bbb.presentation.presenterNameLbl = {0} er nå presenterer.
bbb.presentation.clickToUpload =Last opp presentasjon
bbb.presentation.maxUploadFileExceededAlert = Feil: Fila er større enn tillatt.
bbb.presentation.uploadcomplete = Opplasting er fullført. Vennligst vent mens dokumentet blir konvertert.
bbb.presentation.uploaded = lastet opp.
bbb.presentation.document.supported = Godkjent dokumenttype. Starter konvertering...
bbb.presentation.document.converted = Vellykket konvertering av dokument.
bbb.presentation.error.document.convert.failed = Feil: Mislykket konvertering av dokument.
bbb.presentation.error.io = IO feil: Vennligst kontakt administrator.
bbb.presentation.error.security = Sikkerhetsfeil: Vennligst kontakt administrator.
bbb.presentation.error.convert.format = Feil: Vennligst sjekk at dokumenttypen er korrekt.
bbb.presentation.error.convert.notsupported = Feil: Fila som ble lastet opp er ikke av støttet format. Vennligst last opp en kompatibel fil.
bbb.presentation.error.convert.nbpage = Feil: Antall sider i dokumentet som ble lastet opp kan ikke bestemmes.
bbb.presentation.error.convert.maxnbpagereach = Feil: Dokumentet som ble lastet opp har for mange sider.
bbb.presentation.error.convert.swf = Feil ved konvertering av opplastet dokument. Vennligst ta kontakt med administrator.
bbb.presentation.converted = Konverterte {0} av{1} lysark.
bbb.presentation.ok = OK
bbb.presentation.uploadwindow.presentationfile = Presentasjonsfil
bbb.presentation.uploadwindow.pdf = PDF
bbb.presentation.uploadwindow.word = WORD
bbb.presentation.uploadwindow.excel = EXCEL
bbb.presentation.uploadwindow.powerpoint = POWERPOINT
bbb.presentation.uploadwindow.image = BILDE
bbb.presentation.uploadwindow.closeLabel = Klikk OK for å lukke vindu
bbb.fileupload.title = Last opp presentasjon
bbb.fileupload.fileLbl = Fil:
bbb.fileupload.selectBtn.toolTip = Se etter fil
bbb.fileupload.uploadBtn = Last opp
bbb.fileupload.uploadBtn.toolTip = Last opp fil
bbb.fileupload.presentationNamesLbl = Presentasjoner som er lastet opp:
bbb.fileupload.deleteBtn.toolTip = Slett presentasjon
bbb.fileupload.showBtn = Vis
bbb.fileupload.showBtn.toolTip = Vis presentasjon
bbb.fileupload.okCancelBtn = Avbryt
bbb.fileupload.genThumbText = Lager ikoner..
bbb.fileupload.progBarLbl = Framdrift:
# Chat
bbb.chat.title = Prat
bbb.chat.cmpColorPicker.toolTip = Tekstfarge
bbb.chat.sendBtn = Send
bbb.chat.sendBtn.toolTip = Send melding
bbb.chat.publicChatUsername = Alle
bbb.chat.publicMsgAwaiting = Melding til alle venter
bbb.chat.publicMsgAwaiting2 = * Melding til alle venter *
bbb.chat.privateMsgAwaiting = Privat melding venter
bbb.chat.privateMsgAwaiting2 = * Privat melding venter *
bbb.chat.privateChatSelect = Velg person til privat prat
bbb.chat.chatOptions = Innstillinger for prat
bbb.chat.fontSize = Fontstørrelse
# Listeners
bbb.listeners.title = Lyttere{0} {1}
bbb.listeners.muteAllBtn.toolTip = Slå av lyd for alle
bbb.listeners.unmuteAllBtn.toolTip = Slå på lyd for alle
bbb.listeners.ejectTooltip = Send ut bruker
bbb.listenerItem.nameLbl.toolTip = Velg denne brukeren og klikk for knappen å slå på eller av lyd.
bbb.listenerItem.talkImg.toolTip = Snakker
bbb.listenerItem.lockImg.toolTip = Klikk for å beholde lyd av eller på
bbb.listenerItem.muteUnmute.toolTip = Slå lyd på eller av for denne brukeren
# Video
bbb.publishVideo.title = Vis ditt webkamera
bbb.publishVideo.startPublishBtn.toolTip = Start visning
bbb.video.publish.close.tooltip = Stopp visning av webkamera
bbb.video.publish.close.label = Lukk
# Desktop Sharing
bbb.desktopPublish.title = Skrivebordsdeling: Presenterers forhåndsvisning
bbb.desktopPublish.fullscreen.tooltip = Del ut hele skjermen
bbb.desktopPublish.fullscreen.label = Hele skjermen
bbb.desktopPublish.region.tooltip = Del ut et utsnitt av skjermen
bbb.desktopPublish.region.label = Område
bbb.desktopPublish.stop.tooltip = Lukk skjermdeling
bbb.desktopPublish.stop.label = Lukk
bbb.desktopPublish.maximizeRestoreBtn.toolTip = Du kan ikke maksimere dette vinduet.
bbb.desktopPublish.closeBtn.toolTip = Stopp deling og lukk dette vinduet.
bbb.desktopPublish.minimizeBtn.toolTip = Minimer dette vinduet.
bbb.desktopView.title = Skrivebordsdeling
bbb.desktopView.fitToWindow = Tilpass vindu
bbb.desktopView.actualSize = Vis normal størrelse
# ToolbarButton.mxml
bbb.toolbar.phone.toolTip = Slå på min mikrofon
bbb.toolbar.deskshare.toolTip = Skrivebordsdeling
bbb.toolbar.video.toolTip = Slå på mitt kamera
# Whiteboard
bbb.highlighter.toolbar.pencil = markør
bbb.highlighter.toolbar.ellipse = Sirkel
bbb.highlighter.toolbar.rectangle = Rektangel
bbb.highlighter.toolbar.clear = Slett siden
bbb.highlighter.toolbar.undo = Gjenopprett figur
bbb.highlighter.toolbar.color = Velg farge
bbb.highlighter.toolbar.thickness = Velg tykkelse
bbb.highlighter.button.toolTipShow = Vis tavle
bbb.highlighter.button.toolTipHide = Skjul tavle

View File

@ -1,148 +1,147 @@
# BigBlueButton.mxml
bbb.pageTitle = Конференції BigBlueButton
# MainApplicationShell.mxml
bbb.mainshell.locale.version = 0.71
bbb.mainshell.statusProgress.connecting = Йде підключення до сервера
bbb.mainshell.statusProgress.loading = Завантажується {0} модулів
bbb.mainshell.statusProgress.cannotConnectServer = Не вдалося з’єднатися з сервером.
bbb.mainshell.copyrightLabel2 = © 2011, BigBlueButton версія {0}, додаткова інформація на сайті: http://www.bigbluebutton.org/.
bbb.mainshell.logBtn.toolTip = Відкрити вікно журналу
bbb.mainshell.resetLayoutBtn.toolTip = Скинути розкладку
# OldLocaleWarnWIndow.mxml
bbb.oldlocalewindow.reminder1 = Можливо, у Вас застаріла версія перекладу BigBlueButton.
bbb.oldlocalewindow.reminder2 = Будь ласка, очистіть кеш браузера та спробуйте знову.
bbb.oldlocalewindow.windowTitle = Увага: застаріла версія перекладу.
# MainToolbar.mxml
bbb.mainToolbar.helpBtn = Допомога
bbb.mainToolbar.logoutBtn = Вийти
bbb.mainToolbar.logoutBtn.toolTip = Вийти
###### modules ######
# Viewers
bbb.viewers.title = Учасники {0} {1}
bbb.viewers.viewersGrid.nameItemRenderer = Ім’я
bbb.viewers.viewersGrid.nameItemRenderer.nameLabel.toolTip = Ви увійшли під цим іменем.
bbb.viewers.viewersGrid.roleItemRenderer = Роль
bbb.viewers.viewersGrid.statusItemRenderer = Статус
bbb.viewers.viewersGrid.statusItemRenderer.raiseHand.toolTip = {0} просить слова.
bbb.viewers.viewersGrid.statusItemRenderer.streamIcon.toolTip = Клацніть для перегляду
bbb.viewers.viewersGrid.statusItemRenderer.presIcon.toolTip = Ведучий
bbb.viewers.presentBtn.toolTip = Виберіть учасника, щоб зробити його ведучим.
bbb.viewers.raiseHandBtn.toolTip = Попросити слова
bbb.viewers.presentBtn.label = Переключити ведучого
bbb.viewers.kickUserBtn.toolTip = Виключити з конференції
# Presentation
bbb.presentation.title = Презентація
bbb.presentation.uploadPresBtn = Вивантажити документ для показу.
bbb.presentation.uploadPresBtn.toolTip = Вивантажити документ для презентації.
bbb.presentation.backBtn.toolTip = Попередній слайд.
bbb.presentation.slideNumLbl.toolTip = Натисніть для вибору слайду
bbb.presentation.forwardBtn.toolTip = Наступний слайд
bbb.presentation.resetZoomBtn.toolTip = Відновити вихідний розмір
bbb.presentation.presenterNameLbl = {0} веде презентацію.
bbb.presentation.clickToUpload = Вивантажити презентацію
bbb.presentation.maxUploadFileExceededAlert = Помилка: файл перевищує допустимий розмір.
bbb.presentation.uploadcomplete = Вивантаження завершено. Будь ласк, зачекайте доки ми зконвертуємо документ.
bbb.presentation.uploaded = додано.
bbb.presentation.document.supported = Формат вивантаженого документа підтримується, отож починаємо перетворення для можливості демонстрації.
bbb.presentation.document.converted = Документ успішно перетворений для демонстрації.
bbb.presentation.error.document.convert.failed = Помилка: документ не вдалося перетворити.
bbb.presentation.error.io = Помилка зв’язку: зв’яжіться з системним адміністратором.
bbb.presentation.error.security = Помилка безпеки: зв’яжіться з системним адміністратором.
bbb.presentation.error.convert.format = Помилка: перевірте, що вивантажуваний файл має коректне розширення.
bbb.presentation.error.convert.notsupported = Помилка: формат вивантажуваного файлу не підтримується. Виберіть файл у сумісному з BigBlueButton форматі.
bbb.presentation.error.convert.nbpage = Помилка: не вдалося визначити кількість сторінок у файлі.
bbb.presentation.error.convert.maxnbpagereach = Помилка: у документі занадто багато сторінок.
bbb.presentation.error.convert.swf = При перетворенні формату файлу сталася помилка, зв’яжіться з системним адміністратором.
bbb.presentation.converted = перетворено {0} слайдів із {1}.
bbb.presentation.ok = Гаразд
bbb.presentation.uploadwindow.presentationfile = Файл презентації
bbb.presentation.uploadwindow.pdf = Документ Pdf
bbb.presentation.uploadwindow.word = Документ Word
bbb.presentation.uploadwindow.excel = Таблиця Excel
bbb.presentation.uploadwindow.powerpoint = Презентація PowePoint
bbb.presentation.uploadwindow.image = Зображення
bbb.presentation.uploadwindow.closeLabel = Клацніть „Гаразд“ щоб зачинити вікно
bbb.fileupload.title = Вивантажити презентацію
bbb.fileupload.fileLbl = Файл:
bbb.fileupload.selectBtn.toolTip = Вибрати файл
bbb.fileupload.uploadBtn = Вивантажити
bbb.fileupload.uploadBtn.toolTip = Вивантажити файл
bbb.fileupload.presentationNamesLbl = Вивантажені презентації:
bbb.fileupload.deleteBtn.toolTip = Вилучити презентацію
bbb.fileupload.showBtn = Показати
bbb.fileupload.showBtn.toolTip = Показати презентацію
bbb.fileupload.okCancelBtn = Скасувати
bbb.fileupload.genThumbText = Створення мініатюр …
bbb.fileupload.progBarLbl = Завантаження:
# Chat
bbb.chat.title = Чат
bbb.chat.cmpColorPicker.toolTip = Вибрати колір
bbb.chat.sendBtn = Відправити
bbb.chat.sendBtn.toolTip = Надіслати повідомлення
bbb.chat.publicChatUsername = Усі
bbb.chat.publicMsgAwaiting = Нове повідомлення у чаті
bbb.chat.publicMsgAwaiting2 = * Нове повідомлення у чаті *
bbb.chat.privateMsgAwaiting = Нове особисте повідомлення
bbb.chat.privateMsgAwaiting2 = * Нове особисте повідомлення *
bbb.chat.privateChatSelect = Виберіть користувача для відправки особистого повідомлення
bbb.chat.chatOptions = Налаштування чату
bbb.chat.fontSize = Розмір шрифту
# Listeners
bbb.listeners.title = аудіоконференція: {0} учасників {1}
bbb.listeners.muteAllBtn.toolTip = Вимкнути усі мікрофони
bbb.listeners.unmuteAllBtn.toolTip = Включити усі мірофони
bbb.listeners.ejectTooltip = Клацніть для виключення.
bbb.listenerItem.nameLbl.toolTip = Клацніть, щоб включити/відключити мікрофон у обраного учасника.
bbb.listenerItem.talkImg.toolTip = Каже
bbb.listenerItem.lockImg.toolTip = Клацніть, щоб зберегти приглушеним чи включеним
bbb.listenerItem.muteUnmute.toolTip = Вимкнути/включити мікрофон
# Video
bbb.publishVideo.title = Почати відеотрансляцію з веб-камери
bbb.publishVideo.startPublishBtn.toolTip = Почати відеотрансляцію з веб-камери
bbb.video.publish.close.tooltip = Зупинити відеотрансляцю з веб-камери
bbb.video.publish.close.label = Зачинити
# Desktop Sharing
bbb.desktopPublish.title = Трансляція робочого столу учасника
bbb.desktopPublish.fullscreen.tooltip = Транлювати усього Вашого екрану
bbb.desktopPublish.fullscreen.label = На повний екран
bbb.desktopPublish.region.tooltip = Транлювати частину Вашого екрану
bbb.desktopPublish.region.label = Область
bbb.desktopPublish.stop.tooltip = Зачинити трансляцію екрану
bbb.desktopPublish.stop.label = Зачинити
bbb.desktopPublish.maximizeRestoreBtn.toolTip = Ви не можете розгорнути це вікно.
bbb.desktopPublish.closeBtn.toolTip = Зупинити трансляцію та зачинити це вікно.
bbb.desktopPublish.minimizeBtn.toolTip = Згорнути це вікно.
bbb.desktopView.title = Трансляція робочого столу
bbb.desktopView.fitToWindow = Підігнати під розміри вікна
bbb.desktopView.actualSize = Оригінальний розмір
# ToolbarButton.mxml
bbb.toolbar.phone.toolTip = Увімкнути мікрофон
bbb.toolbar.deskshare.toolTip = Транслювати робочий стіл
bbb.toolbar.video.toolTip = Включити веб-камеру
# Whiteboard
bbb.highlighter.toolbar.pencil = Маркер
bbb.highlighter.toolbar.ellipse = Коло
bbb.highlighter.toolbar.rectangle = Прямокутник
bbb.highlighter.toolbar.clear = Очистити сторінку
bbb.highlighter.toolbar.undo = Скасувати фігуру
bbb.highlighter.toolbar.color = Вибрати колір
bbb.highlighter.toolbar.thickness = Вибрати товщину ліній
bbb.highlighter.button.toolTipShow = Показати віртуальну дошку
bbb.highlighter.button.toolTipHide = Приховати віртуальну дошку
# BigBlueButton.mxml
bbb.pageTitle = Конференції BigBlueButton
# MainApplicationShell.mxml
bbb.mainshell.locale.version=0.71
bbb.mainshell.statusProgress.connecting = Під'єднуюсь до сервера
bbb.mainshell.statusProgress.loading = Завантажується {0} модулів
bbb.mainshell.statusProgress.cannotConnectServer = Не вдалось з'єднатись з сервером.
bbb.mainshell.copyrightLabel2 = © 2011, BigBlueButton версія {0}, додаткова інформація на сайті: http://www.bigbluebutton.org/.
bbb.mainshell.logBtn.toolTip = Відкрити вікно журналу
bbb.mainshell.resetLayoutBtn.toolTip = Скинути розкладку
# OldLocaleWarnWIndow.mxml
bbb.oldlocalewindow.reminder1=Можливо, що у вас застаріла версія перекладу BigBlueButton.
bbb.oldlocalewindow.reminder2=Очистіть кеш веб-переглядача і спробуйте ще раз.
bbb.oldlocalewindow.windowTitle=Увага: застаріла версія перекладу.
# MainToolbar.mxml
bbb.mainToolbar.helpBtn = Допомога
bbb.mainToolbar.logoutBtn = Вийти
bbb.mainToolbar.logoutBtn.toolTip = Вийти
###### modules ######
# Viewers
bbb.viewers.title = Учасники{0} {1}
bbb.viewers.viewersGrid.nameItemRenderer = Ім'я
bbb.viewers.viewersGrid.nameItemRenderer.nameLabel.toolTip = Ви увійшли під цим іменем.
bbb.viewers.viewersGrid.roleItemRenderer = Роль
bbb.viewers.viewersGrid.statusItemRenderer = Статус
bbb.viewers.viewersGrid.statusItemRenderer.raiseHand.toolTip = {0} просить надати слово.
bbb.viewers.viewersGrid.statusItemRenderer.streamIcon.toolTip = Клацніть для перегляду
bbb.viewers.viewersGrid.statusItemRenderer.presIcon.toolTip = Ведучий
bbb.viewers.presentBtn.toolTip = Виберіть учасника, щоби зробити його ведучим.
bbb.viewers.raiseHandBtn.toolTip = Попросити надати слово
bbb.viewers.presentBtn.label = Перемкнути ведучого
bbb.viewers.kickUserBtn.toolTip = Видалити з конференції
# Presentation
bbb.presentation.title = Презентація
bbb.presentation.uploadPresBtn = Завантажити документ для показу.
bbb.presentation.uploadPresBtn.toolTip = Завантажити документ для презентації.
bbb.presentation.backBtn.toolTip = Попередній слайд.
bbb.presentation.slideNumLbl.toolTip = Клацніть для вибору слайда
bbb.presentation.forwardBtn.toolTip = Наступний слайд
bbb.presentation.resetZoomBtn.toolTip = Відновити початковий розмір
bbb.presentation.presenterNameLbl = {0} веде презентацію.
bbb.presentation.clickToUpload = Завантажити презентацію
bbb.presentation.maxUploadFileExceededAlert = Помилка: файл превищує припустимий розмір.
bbb.presentation.uploadcomplete = Завантаження завершено. Зачекайте, поки завершиться перетворення файлу.
bbb.presentation.uploaded = завантажено.
bbb.presentation.document.supported = Формат завантаженого документу підтримується. Йде перетворення для демонстрації.
bbb.presentation.document.converted = Документ успішно перетворений для демонстрації.
bbb.presentation.error.document.convert.failed = Помилка: документ не вдалось перетворити.
bbb.presentation.error.io = Помилка зв'язку: зв'яжіться з системним адміністратором.
bbb.presentation.error.security = Помилка безпеки: зв'яжіться з системним адміністратором.
bbb.presentation.error.convert.format = Помилка: переконайтесь, що файл має коректне розширення.
bbb.presentation.error.convert.notsupported = Помилка: формат завантаженого файла не підтримується. Виберіть файл із сумісним з BigBlueButton форматом.
bbb.presentation.error.convert.nbpage = Помилка: не вдалось визначити число сторінок у файлі.
bbb.presentation.error.convert.maxnbpagereach = Помилка: в документі забагато сторінок.
bbb.presentation.error.convert.swf = При перетворенні формату файла відбулась помилка. Зв'яжіться із системним адміністратором.
bbb.presentation.converted = Перетворено {0} слайдів з {1}.
bbb.presentation.ok = Ок
bbb.presentation.uploadwindow.presentationfile = Файл презентації
bbb.presentation.uploadwindow.pdf = Документ Pdf
bbb.presentation.uploadwindow.word = Документ Word
bbb.presentation.uploadwindow.excel = Таблиця Excel
bbb.presentation.uploadwindow.powerpoint = Презентація PowePoint
bbb.presentation.uploadwindow.image = Зображення
bbb.presentation.uploadwindow.closeLabel = Натисніть Ок для закриття вікна
bbb.fileupload.title = Завантажити презентацію
bbb.fileupload.fileLbl = Файл:
bbb.fileupload.selectBtn.toolTip = Вибрати файл
bbb.fileupload.uploadBtn = Завантажити
bbb.fileupload.uploadBtn.toolTip = Завантажити файл
bbb.fileupload.presentationNamesLbl = Завантаження презентації:
bbb.fileupload.deleteBtn.toolTip = Видалити презентацію
bbb.fileupload.showBtn = Показати
bbb.fileupload.showBtn.toolTip = Показати презентацію
bbb.fileupload.okCancelBtn = Скасувати
bbb.fileupload.genThumbText = Створення мініатюр…
bbb.fileupload.progBarLbl = Завантаження:
# Chat
bbb.chat.title = Чат
bbb.chat.cmpColorPicker.toolTip = Вибрати колір
bbb.chat.sendBtn = Надіслати
bbb.chat.sendBtn.toolTip = Написати повідомлення
bbb.chat.publicChatUsername = Всі
bbb.chat.publicMsgAwaiting = Нове повідомлення в чаті
bbb.chat.publicMsgAwaiting2 = * Нове повідомлення в чаті *
bbb.chat.privateMsgAwaiting = Нове приватне повідомлення
bbb.chat.privateMsgAwaiting2 = * Нове приватне повідомлення *
bbb.chat.privateChatSelect = Виберіть користувача для надсилання приватного повідомлення
bbb.chat.chatOptions = Налаштування чату
bbb.chat.fontSize = Розмір шрифту
# Listeners
bbb.listeners.title = Аудіоконференція:{0} {1}
bbb.listeners.muteAllBtn.toolTip = Вимкнути всі мікрофони
bbb.listeners.unmuteAllBtn.toolTip = Ввімкнути всі мікрофони
bbb.listeners.ejectTooltip = Прибрати користувача.
bbb.listenerItem.nameLbl.toolTip = Клацніть, щоби ввімкнути/вимкнути мікрофон у участника.
bbb.listenerItem.talkImg.toolTip = Говорить
bbb.listenerItem.lockImg.toolTip = Клацніть, щоби зберегти приглушеним або ввімкненим
bbb.listenerItem.muteUnmute.toolTip = Вимкнути/ввімкнути мікрофон
# Video
bbb.publishVideo.title = Розпочати відеотрансляцію
bbb.publishVideo.startPublishBtn.toolTip = Розпочати відеотрансляцію
bbb.video.publish.close.tooltip = Призупитини показ вашего відео
bbb.video.publish.close.label = Закрити
# Desktop Sharing
bbb.desktopPublish.title = Трансляція робочего столу
bbb.desktopPublish.fullscreen.tooltip = Транслювати весь екран
bbb.desktopPublish.fullscreen.label = Повноекранний режим
bbb.desktopPublish.region.tooltip = Транслювати область екрана
bbb.desktopPublish.region.label = Область
bbb.desktopPublish.stop.tooltip = Зупинити трансляцію екрана
bbb.desktopPublish.stop.label = Зупинити
bbb.desktopPublish.maximizeRestoreBtn.toolTip = Ви не можете розгорнути це вікно.
bbb.desktopPublish.closeBtn.toolTip = Зупинити трансляцію і закрити вікно
bbb.desktopPublish.minimizeBtn.toolTip = Згорнути це вікно.
bbb.desktopView.title = Трансляція робочего столу
bbb.desktopView.fitToWindow = Підлаштувати під розміри вікна
bbb.desktopView.actualSize = Оригінальний розмір
# ToolbarButton.mxml
bbb.toolbar.phone.toolTip = Ввімкнути мікрофон
bbb.toolbar.deskshare.toolTip = Транслювати робочий стіл
bbb.toolbar.video.toolTip = Ввімкнути веб-камеру
# Whiteboard
bbb.highlighter.toolbar.pencil = Маркер
bbb.highlighter.toolbar.ellipse = Коло
bbb.highlighter.toolbar.rectangle = Прямокутник
bbb.highlighter.toolbar.clear = Очистити сторінку
bbb.highlighter.toolbar.undo = Скасувати фігуру
bbb.highlighter.toolbar.color = Вибрати колір
bbb.highlighter.toolbar.thickness = Вибрати товщину ліній
bbb.highlighter.button.toolTipShow = Показати віртуальну дошку
bbb.highlighter.button.toolTipHide = Сховати віртуальну дошку

View File

@ -109,7 +109,7 @@ function startApplet(IP, roomNumber, fullScreen)
document.body.appendChild(iframe);
frames[frames.length - 1].document.write(
"<applet code=\"org.bigbluebutton.deskshare.client.DeskShareApplet.class\"" +
"id=\"DeskShareApplet\" width=\"0\" height=\"400\" archive=\"bbb-deskshare-applet-0.71.jar\">" +
"id=\"DeskShareApplet\" width=\"1\" height=\"400\" archive=\"bbb-deskshare-applet-0.71.jar\">" +
"<param name=\"ROOM\" value=\"" + roomNumber + "\"/>" +
"<param name=\"IP\" value=\"" + IP + "\"/>" +
"<param name=\"FULL_SCREEN\" value=\"" + fullScreen + "\"/>" +

View File

@ -20,6 +20,7 @@
<locale code="ro_RO" name="Romanian"/>
<locale code="ru_RU" name="Russian"/>
<locale code="tr_TR" name="Turkish"/>
<locale code="uk_UA" name="Ukrainian"/>
<locale code="vi_VN" name="Vietnamese"/>
<locale code="zh_CN" name="Chinese (Simplified)"/>
<locale code="zh_TW" name="Chinese (Traditional)"/>

View File

@ -38,6 +38,7 @@
# 2010-11-06 FFD Added logic to ensure red5 shuts down
# 2010-12-12 FFD Fixed bug #778
# 2010-12-12 FFD Added support for Intalio VM
# 2010-02-28 FFD Fixed #834
#set -x
@ -89,7 +90,7 @@ if [ -f /etc/lsb-release ]; then
PLATFORM=ubuntu-jetty-intalio
SERVLET_CONTAINER=cloud
SERVLET_LOGS=/var/www/cloud/jetty/logs
SERVLET_DIR=/var/www/cloud/webappsviacontext
SERVLET_DIR=/var/www/cloud/webapps
fi
fi
fi
@ -176,7 +177,7 @@ usage() {
echo " --setip <host> Set IP/hostname for BigBlueButton"
echo " --conference [konference|meetme|freeswitch]"
echo " Switch conference module"
echo " --saltset <salt> Change the security salt in bigbluebutton.properties"
echo " --setsalt <salt> Change the security salt in bigbluebutton.properties"
echo
echo "Monitoring:"
echo " --check <verbose> Check configuration files and processes for problems"
@ -513,14 +514,8 @@ done
# Version
#
if [ $VERSION ]; then
if [ "$(is_redhat)" ]; then
echo "$(yum list installed | grep bbb-conf)"
else
if [ "$(is_ubuntu)" ]; then
echo
dpkg -l | grep bbb
fi
fi
echo
dpkg -l | grep bbb
exit 0
fi
@ -899,7 +894,7 @@ check_configuration() {
# Make sure the salt for the API matches the server
#
SALT_PROPERTIES=$(cat ${SERVLET_DIR}/bigbluebutton/WEB-INF/classes/bigbluebutton.properties | tr -d '\r' | sed -n '/securitySalt/{s/.*=//;p}')
SALT_DEMO=$(cat ${SERVLET_DIR}/bigbluebutton/demo/bbb_api_conf.jsp | tr -d '\r' | sed -n '/salt =/{s/.* = "//;s/".*//g;p}')
SALT_DEMO=$(cat ${SERVLET_DIR}/bigbluebutton/demo/bbb_api_conf.jsp | tr -d '\r' | sed -n '/salt[ ]*=/{s/.*=[ ]*"//;s/".*//g;p}')
if [ "$SALT_PROPERTIES" != "$SALT_DEMO" ]; then
echo "# Salt mismatch: "