1
1
/*
2
2
* *****************************************************************************
3
- * Copyright (C) 2014-2022 Dennis Sheirer
3
+ * Copyright (C) 2014-2024 Dennis Sheirer
4
4
*
5
5
* This program is free software: you can redistribute it and/or modify
6
6
* it under the terms of the GNU General Public License as published by
20
20
21
21
import io .github .dsheirer .alias .AliasModel ;
22
22
import io .github .dsheirer .audio .broadcast .BroadcastState ;
23
+ import io .github .dsheirer .audio .broadcast .broadcastify .BroadcastifyFeedConfiguration ;
23
24
import io .github .dsheirer .audio .broadcast .icecast .codec .IcecastCodecFactory ;
24
25
import io .github .dsheirer .audio .convert .InputAudioFormat ;
25
26
import io .github .dsheirer .audio .convert .MP3AudioConverter ;
39
40
import org .apache .mina .core .service .IoHandlerAdapter ;
40
41
import org .apache .mina .core .session .IoSession ;
41
42
import org .apache .mina .filter .codec .ProtocolCodecFilter ;
43
+ import org .apache .mina .filter .logging .LogLevel ;
44
+ import org .apache .mina .filter .logging .LoggingFilter ;
42
45
import org .apache .mina .transport .socket .nio .NioSocketConnector ;
43
46
import org .slf4j .Logger ;
44
47
import org .slf4j .LoggerFactory ;
@@ -56,6 +59,7 @@ public class IcecastTCPAudioBroadcaster extends IcecastAudioBroadcaster
56
59
private IoSession mStreamingSession = null ;
57
60
58
61
private long mLastConnectionAttempt = 0 ;
62
+ private boolean mVerboseLogging = false ;
59
63
private AtomicBoolean mConnecting = new AtomicBoolean ();
60
64
61
65
/**
@@ -73,6 +77,11 @@ public IcecastTCPAudioBroadcaster(IcecastTCPConfiguration configuration, InputAu
73
77
MP3Setting mp3Setting , AliasModel aliasModel )
74
78
{
75
79
super (configuration , inputAudioFormat , mp3Setting , aliasModel );
80
+
81
+ if (configuration instanceof BroadcastifyFeedConfiguration broadcastify )
82
+ {
83
+ mVerboseLogging = broadcastify .isVerboseLogging ();
84
+ }
76
85
}
77
86
78
87
/**
@@ -132,9 +141,12 @@ private boolean connect()
132
141
mSocketConnector = new NioSocketConnector ();
133
142
mSocketConnector .getSessionConfig ().setWriteTimeout (WRITE_TIMEOUT_SECONDS );
134
143
135
- // LoggingFilter loggingFilter = new LoggingFilter(IcecastTCPAudioBroadcaster.class);
136
- // loggingFilter.setMessageSentLogLevel(LogLevel.NONE);
137
- // mSocketConnector.getFilterChain().addLast("logger", loggingFilter);
144
+ if (mVerboseLogging )
145
+ {
146
+ LoggingFilter loggingFilter = new LoggingFilter (IcecastTCPAudioBroadcaster .class );
147
+ loggingFilter .setMessageSentLogLevel (LogLevel .NONE );
148
+ mSocketConnector .getFilterChain ().addLast ("logger" , loggingFilter );
149
+ }
138
150
139
151
mSocketConnector .getFilterChain ().addLast ("codec" ,
140
152
new ProtocolCodecFilter (new IcecastCodecFactory ()));
@@ -148,6 +160,10 @@ private boolean connect()
148
160
@ Override
149
161
public void run ()
150
162
{
163
+ if (mVerboseLogging )
164
+ {
165
+ mLog .info ("Attempting connection ..." );
166
+ }
151
167
setBroadcastState (BroadcastState .CONNECTING );
152
168
153
169
try
@@ -156,32 +172,65 @@ public void run()
156
172
.connect (new InetSocketAddress (getBroadcastConfiguration ().getHost (),
157
173
getBroadcastConfiguration ().getPort ()));
158
174
175
+ if (mVerboseLogging )
176
+ {
177
+ mLog .info ("Socket created - asynchronous connect requested - entering wait period" );
178
+ }
179
+
159
180
boolean connected = future .await (CONNECTION_ATTEMPT_TIMEOUT_MILLISECONDS , TimeUnit .MILLISECONDS );
160
181
161
182
if (connected )
162
183
{
184
+ if (mVerboseLogging )
185
+ {
186
+ mLog .info ("Connected." );
187
+ }
188
+
163
189
mStreamingSession = future .getSession ();
164
190
mConnecting .set (false );
165
191
return ;
166
192
}
193
+ else
194
+ {
195
+ if (mVerboseLogging )
196
+ {
197
+ mLog .info ("Not Connected. Connection attempt timeout [" + CONNECTION_ATTEMPT_TIMEOUT_MILLISECONDS + "ms] exceeded" );
198
+ }
199
+ }
167
200
}
168
201
catch (RuntimeIoException rioe )
169
202
{
170
203
if (rioe .getCause () instanceof SocketException )
171
204
{
205
+ if (mVerboseLogging )
206
+ {
207
+ mLog .info ("Socket error. This usually indicates sdrtrunk can't reach the server " +
208
+ "address over the current network connection. Setting state to " +
209
+ "NETWORK UNAVAILABLE" , rioe );
210
+ }
172
211
setBroadcastState (BroadcastState .NETWORK_UNAVAILABLE );
173
212
mConnecting .set (false );
174
213
return ;
175
214
}
176
215
}
177
216
catch (UnresolvedAddressException uae )
178
217
{
218
+ if (mVerboseLogging )
219
+ {
220
+ mLog .info ("Unresolved Address error. This means the domain name services can't resolve " +
221
+ "the server URL to an IP address. Setting state to NETWORK UNAVAILABLE" , uae );
222
+ }
223
+
179
224
setBroadcastState (BroadcastState .NETWORK_UNAVAILABLE );
180
225
mConnecting .set (false );
181
226
return ;
182
227
}
183
228
catch (Exception e )
184
229
{
230
+ if (mVerboseLogging )
231
+ {
232
+ mLog .info ("Unknown error. An error occurred while attempting to connect to the server." , e );
233
+ }
185
234
mLog .error ("Error" , e );
186
235
//Disregard ... we'll disconnect and try again
187
236
}
@@ -190,6 +239,11 @@ public void run()
190
239
mLog .error ("Throwable error caught" , t );
191
240
}
192
241
242
+ if (mVerboseLogging )
243
+ {
244
+ mLog .info ("Starting disconnect sequence since an error occurred while trying to connect." );
245
+ }
246
+
193
247
disconnect ();
194
248
mConnecting .set (false );
195
249
}
@@ -209,6 +263,11 @@ public void disconnect()
209
263
{
210
264
if (connected () && mStreamingSession != null )
211
265
{
266
+ if (mVerboseLogging )
267
+ {
268
+ mLog .info ("Routine disconnect requested from a connected state with a non-null streaming session" );
269
+ }
270
+
212
271
mStreamingSession .closeNow ();
213
272
}
214
273
else
@@ -217,6 +276,12 @@ public void disconnect()
217
276
//want to preserve the error state that got us here, so the user can see it.
218
277
if (!getBroadcastState ().isErrorState ())
219
278
{
279
+ if (mVerboseLogging )
280
+ {
281
+ mLog .info ("Disconnect requested - previous non-error state was [" + getBroadcastState () +
282
+ "] - changing state to DISCONNECTED" );
283
+ }
284
+
220
285
setBroadcastState (BroadcastState .DISCONNECTED );
221
286
}
222
287
@@ -282,12 +347,23 @@ public void sessionOpened(IoSession session) throws Exception
282
347
mInlineActive = false ;
283
348
}
284
349
350
+ if (mVerboseLogging )
351
+ {
352
+ mLog .info ("Session opened. Sending: " + sb );
353
+ }
354
+
355
+
285
356
session .write (sb .toString ());
286
357
}
287
358
288
359
@ Override
289
360
public void sessionClosed (IoSession session ) throws Exception
290
361
{
362
+ if (mVerboseLogging )
363
+ {
364
+ mLog .info ("Session closed. Setting connecting flag to false." );
365
+ }
366
+
291
367
mLastConnectionAttempt = System .currentTimeMillis ();
292
368
293
369
//If there is already an error state, don't override it. Otherwise, set state to disconnected
@@ -311,15 +387,23 @@ public void exceptionCaught(IoSession session, Throwable cause) throws Exception
311
387
mLog .error ("[" + getStreamName () + "] Broadcast error" , cause );
312
388
}
313
389
390
+ if (mVerboseLogging )
391
+ {
392
+ mLog .info ("Session error caught." , cause );
393
+ }
394
+
314
395
disconnect ();
315
396
}
316
397
317
398
@ Override
318
399
public void messageReceived (IoSession session , Object object ) throws Exception
319
400
{
320
- if (object instanceof String )
401
+ if (object instanceof String message )
321
402
{
322
- String message = (String ) object ;
403
+ if (mVerboseLogging )
404
+ {
405
+ mLog .info ("Message Received [" + message + "]" );
406
+ }
323
407
324
408
if (message != null && !message .trim ().isEmpty ())
325
409
{
0 commit comments