Merge branch 'master' of github.com:bigbluebutton/bigbluebutton
This commit is contained in:
commit
43046a7338
@ -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.");
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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.
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 = Сховати віртуальну дошку
|
||||
|
@ -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 + "\"/>" +
|
||||
|
@ -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)"/>
|
||||
|
@ -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: "
|
||||
|
Loading…
Reference in New Issue
Block a user