Skip to content

Commit 75149fd

Browse files
committed
dynamic audio ports
1 parent bfcf0fe commit 75149fd

3 files changed

Lines changed: 50 additions & 12 deletions

File tree

src/main/java/com/github/serezhka/jap2server/internal/AudioControlServer.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,16 @@ public class AudioControlServer implements Runnable {
1919

2020
private static final Logger log = LoggerFactory.getLogger(AudioControlServer.class);
2121

22+
private final Object monitor;
23+
24+
private int port;
25+
26+
public AudioControlServer(Object monitor) {
27+
this.monitor = monitor;
28+
}
29+
2230
@Override
2331
public void run() {
24-
var port = 4999;
2532
var bootstrap = new Bootstrap();
2633
var workerGroup = eventLoopGroup();
2734
var audioControlHandler = new AudioControlHandler();
@@ -30,15 +37,23 @@ public void run() {
3037
bootstrap
3138
.group(workerGroup)
3239
.channel(datagramChannelClass())
33-
.localAddress(new InetSocketAddress(port))
40+
.localAddress(new InetSocketAddress(0)) // bind random port
3441
.handler(new ChannelInitializer<DatagramChannel>() {
3542
@Override
3643
public void initChannel(final DatagramChannel ch) {
3744
ch.pipeline().addLast(audioControlHandler);
3845
}
3946
});
47+
4048
var channelFuture = bootstrap.bind().sync();
41-
log.info("Audio control server listening on port: {}", port);
49+
50+
log.info("Audio control server listening on port: {}",
51+
port = ((InetSocketAddress) channelFuture.channel().localAddress()).getPort());
52+
53+
synchronized (monitor) {
54+
monitor.notify();
55+
}
56+
4257
channelFuture.channel().closeFuture().sync();
4358
} catch (InterruptedException e) {
4459
log.info("Audio control server interrupted");
@@ -48,6 +63,10 @@ public void initChannel(final DatagramChannel ch) {
4863
}
4964
}
5065

66+
public int getPort() {
67+
return port;
68+
}
69+
5170
private EventLoopGroup eventLoopGroup() {
5271
return Epoll.isAvailable() ? new EpollEventLoopGroup() : new NioEventLoopGroup();
5372
}

src/main/java/com/github/serezhka/jap2server/internal/AudioReceiver.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import com.github.serezhka.jap2server.internal.handler.audio.AudioHandler;
44
import io.netty.bootstrap.Bootstrap;
55
import io.netty.channel.ChannelInitializer;
6-
import io.netty.channel.ChannelOption;
76
import io.netty.channel.EventLoopGroup;
87
import io.netty.channel.epoll.Epoll;
98
import io.netty.channel.epoll.EpollDatagramChannel;
@@ -21,31 +20,40 @@ public class AudioReceiver implements Runnable {
2120
private static final Logger log = LoggerFactory.getLogger(AudioReceiver.class);
2221

2322
private final AudioHandler audioHandler;
23+
private final Object monitor;
2424

25-
public AudioReceiver(AudioHandler audioHandler) {
25+
private int port;
26+
27+
public AudioReceiver(AudioHandler audioHandler, Object monitor) {
2628
this.audioHandler = audioHandler;
29+
this.monitor = monitor;
2730
}
2831

2932
@Override
3033
public void run() {
31-
var port = 4998;
3234
var bootstrap = new Bootstrap();
3335
var workerGroup = eventLoopGroup();
3436

3537
try {
3638
bootstrap
3739
.group(workerGroup)
3840
.channel(datagramChannelClass())
39-
.localAddress(new InetSocketAddress(port))
40-
.option(ChannelOption.SO_KEEPALIVE, true)
41+
.localAddress(new InetSocketAddress(0)) // bind random port
4142
.handler(new ChannelInitializer<DatagramChannel>() {
4243
@Override
4344
public void initChannel(final DatagramChannel ch) {
4445
ch.pipeline().addLast(audioHandler);
4546
}
4647
});
4748
var channelFuture = bootstrap.bind().sync();
48-
log.info("Audio receiver listening on port: {}", port);
49+
50+
log.info("Audio receiver listening on port: {}",
51+
port = ((InetSocketAddress) channelFuture.channel().localAddress()).getPort());
52+
53+
synchronized (monitor) {
54+
monitor.notify();
55+
}
56+
4957
channelFuture.channel().closeFuture().sync();
5058
} catch (InterruptedException e) {
5159
log.info("Audio receiver interrupted");
@@ -55,6 +63,10 @@ public void initChannel(final DatagramChannel ch) {
5563
}
5664
}
5765

66+
public int getPort() {
67+
return port;
68+
}
69+
5870
private EventLoopGroup eventLoopGroup() {
5971
return Epoll.isAvailable() ? new EpollEventLoopGroup() : new NioEventLoopGroup();
6072
}

src/main/java/com/github/serezhka/jap2server/internal/handler/control/RTSPHandler.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,24 @@ protected boolean handleRequest(ChannelHandlerContext ctx, Session session, Full
5757
}
5858

5959
var audioHandler = new AudioHandler(session.getAirPlay(), airplayDataConsumer);
60-
var audioReceiver = new AudioReceiver(audioHandler);
60+
var audioReceiver = new AudioReceiver(audioHandler, this);
6161
var audioReceiverThread = new Thread(audioReceiver);
6262
session.setAudioReceiverThread(audioReceiverThread);
6363
audioReceiverThread.start();
64+
synchronized (this) {
65+
wait();
66+
}
6467

65-
var audioControlServer = new AudioControlServer();
68+
var audioControlServer = new AudioControlServer(this);
6669
var audioControlServerThread = new Thread(audioControlServer);
6770
session.setAudioControlServerThread(audioControlServerThread);
6871
audioControlServerThread.start();
72+
synchronized (this) {
73+
wait();
74+
}
6975

70-
session.getAirPlay().rtspSetupAudio(new ByteBufOutputStream(response.content()), 4998, 4999);
76+
session.getAirPlay().rtspSetupAudio(new ByteBufOutputStream(response.content()),
77+
audioReceiver.getPort(), audioControlServer.getPort());
7178
break;
7279

7380
case VIDEO:

0 commit comments

Comments
 (0)