|
|
@ -10,7 +10,6 @@ import java.net.InetSocketAddress;
|
|
|
|
import java.net.Socket;
|
|
|
|
import java.net.Socket;
|
|
|
|
import java.net.SocketAddress;
|
|
|
|
import java.net.SocketAddress;
|
|
|
|
import java.net.SocketException;
|
|
|
|
import java.net.SocketException;
|
|
|
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
|
|
|
|
|
|
import java.util.logging.Level;
|
|
|
|
import java.util.logging.Level;
|
|
|
|
import java.util.logging.Logger;
|
|
|
|
import java.util.logging.Logger;
|
|
|
|
import java.util.regex.Matcher;
|
|
|
|
import java.util.regex.Matcher;
|
|
|
@ -75,7 +74,11 @@ public class RtmpConnection implements RtmpPublisher {
|
|
|
|
private int videoWidth;
|
|
|
|
private int videoWidth;
|
|
|
|
private int videoHeight;
|
|
|
|
private int videoHeight;
|
|
|
|
private int videoFrameCount;
|
|
|
|
private int videoFrameCount;
|
|
|
|
private long lastTimeMillis;
|
|
|
|
private int videoDataLength;
|
|
|
|
|
|
|
|
private int audioFrameCount;
|
|
|
|
|
|
|
|
private int audioDataLength;
|
|
|
|
|
|
|
|
private long videoLastTimeMillis;
|
|
|
|
|
|
|
|
private long audioLastTimeMillis;
|
|
|
|
|
|
|
|
|
|
|
|
public RtmpConnection(RtmpPublisher.EventHandler handler) {
|
|
|
|
public RtmpConnection(RtmpPublisher.EventHandler handler) {
|
|
|
|
mHandler = handler;
|
|
|
|
mHandler = handler;
|
|
|
@ -370,6 +373,7 @@ public class RtmpConnection implements RtmpPublisher {
|
|
|
|
audio.getHeader().setAbsoluteTimestamp(dts);
|
|
|
|
audio.getHeader().setAbsoluteTimestamp(dts);
|
|
|
|
audio.getHeader().setMessageStreamId(currentStreamId);
|
|
|
|
audio.getHeader().setMessageStreamId(currentStreamId);
|
|
|
|
sendRtmpPacket(audio);
|
|
|
|
sendRtmpPacket(audio);
|
|
|
|
|
|
|
|
calcAudioBitrate(audio.getHeader().getPacketLength());
|
|
|
|
mHandler.onRtmpAudioStreaming("audio streaming");
|
|
|
|
mHandler.onRtmpAudioStreaming("audio streaming");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -390,14 +394,42 @@ public class RtmpConnection implements RtmpPublisher {
|
|
|
|
video.getHeader().setMessageStreamId(currentStreamId);
|
|
|
|
video.getHeader().setMessageStreamId(currentStreamId);
|
|
|
|
sendRtmpPacket(video);
|
|
|
|
sendRtmpPacket(video);
|
|
|
|
videoFrameCacheNumber.decrementAndGet();
|
|
|
|
videoFrameCacheNumber.decrementAndGet();
|
|
|
|
calcFps();
|
|
|
|
calcVideoFpsAndBitrate(video.getHeader().getPacketLength());
|
|
|
|
mHandler.onRtmpVideoStreaming("video streaming");
|
|
|
|
mHandler.onRtmpVideoStreaming("video streaming");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
private void calcVideoFpsAndBitrate(int length) {
|
|
|
|
* Transmit the specified RTMP packet
|
|
|
|
videoDataLength += length;
|
|
|
|
*/
|
|
|
|
if (videoFrameCount == 0) {
|
|
|
|
public void sendRtmpPacket(RtmpPacket rtmpPacket) {
|
|
|
|
videoLastTimeMillis = System.nanoTime() / 1000000;
|
|
|
|
|
|
|
|
videoFrameCount++;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if (++videoFrameCount >= 48) {
|
|
|
|
|
|
|
|
long diffTimeMillis = System.nanoTime() / 1000000 - videoLastTimeMillis;
|
|
|
|
|
|
|
|
mHandler.onRtmpOutputFps((double) videoFrameCount * 1000 / diffTimeMillis);
|
|
|
|
|
|
|
|
mHandler.onRtmpVideoBitrate((double) videoDataLength * 8 * 1000 / diffTimeMillis);
|
|
|
|
|
|
|
|
videoFrameCount = 0;
|
|
|
|
|
|
|
|
videoDataLength = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void calcAudioBitrate(int length) {
|
|
|
|
|
|
|
|
audioDataLength += length;
|
|
|
|
|
|
|
|
if (audioFrameCount == 0) {
|
|
|
|
|
|
|
|
audioLastTimeMillis = System.nanoTime() / 1000000;
|
|
|
|
|
|
|
|
audioFrameCount++;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if (++audioFrameCount >= 48) {
|
|
|
|
|
|
|
|
long diffTimeMillis = System.nanoTime() / 1000000 - audioLastTimeMillis;
|
|
|
|
|
|
|
|
mHandler.onRtmpAudioBitrate((double) audioDataLength * 8 * 1000 / diffTimeMillis);
|
|
|
|
|
|
|
|
audioFrameCount = 0;
|
|
|
|
|
|
|
|
audioDataLength = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void sendRtmpPacket(RtmpPacket rtmpPacket) {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
ChunkStreamInfo chunkStreamInfo = rtmpSessionInfo.getChunkStreamInfo(rtmpPacket.getHeader().getChunkStreamId());
|
|
|
|
ChunkStreamInfo chunkStreamInfo = rtmpSessionInfo.getChunkStreamInfo(rtmpPacket.getHeader().getChunkStreamId());
|
|
|
|
chunkStreamInfo.setPrevHeaderTx(rtmpPacket.getHeader());
|
|
|
|
chunkStreamInfo.setPrevHeaderTx(rtmpPacket.getHeader());
|
|
|
@ -422,19 +454,6 @@ public class RtmpConnection implements RtmpPublisher {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void calcFps() {
|
|
|
|
|
|
|
|
if (videoFrameCount == 0) {
|
|
|
|
|
|
|
|
lastTimeMillis = System.nanoTime() / 1000000;
|
|
|
|
|
|
|
|
videoFrameCount++;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if (++videoFrameCount >= 48) {
|
|
|
|
|
|
|
|
long diffTimeMillis = System.nanoTime() / 1000000 - lastTimeMillis;
|
|
|
|
|
|
|
|
mHandler.onRtmpOutputFps((double) videoFrameCount * 1000 / diffTimeMillis);
|
|
|
|
|
|
|
|
videoFrameCount = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void handleRxPacketLoop() throws IOException {
|
|
|
|
private void handleRxPacketLoop() throws IOException {
|
|
|
|
// Handle all queued received RTMP packets
|
|
|
|
// Handle all queued received RTMP packets
|
|
|
|
while (!Thread.interrupted()) {
|
|
|
|
while (!Thread.interrupted()) {
|
|
|
|