mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 08:37:25 -05:00
#30 - adds support for Shoutcast V1 streaming. Resolves issue where temporary MP3 recording files were not being flushed at the end, causing partial frames to be streamed resulting in repeated remote server connection resets.
Note: Shoutcast V1 streaming to a Shoutcast V2.5.x server seems to be problematic. The newer server tracks MP3 boundaries in order to insert advertising and this appears to have problems keeping sync with the MP3 stream. I spent significant time eliminating MP3 framing errors in my code. You can see these 'Bad frame' errors in the sc_serv.log and the shoutcast server will eventually reset the connection after a period of time or after a number of framing errors occur. I anticipate that streaming to a Shoutcast V2 server using the ultravox (ie V2.x) protocol may resolve this issue.
This commit is contained in:
@@ -19,7 +19,6 @@
|
||||
package audio.broadcast;
|
||||
|
||||
import alias.AliasModel;
|
||||
import audio.AudioPacket;
|
||||
import audio.broadcast.broadcastify.BroadcastifyConfiguration;
|
||||
import audio.broadcast.broadcastify.BroadcastifyConfigurationEditor;
|
||||
import audio.broadcast.icecast.IcecastHTTPAudioBroadcaster;
|
||||
@@ -30,6 +29,7 @@ import audio.broadcast.icecast.IcecastTCPConfiguration;
|
||||
import audio.broadcast.icecast.IcecastTCPConfigurationEditor;
|
||||
import audio.broadcast.shoutcast.v1.ShoutcastV1AudioBroadcaster;
|
||||
import audio.broadcast.shoutcast.v1.ShoutcastV1Configuration;
|
||||
import audio.broadcast.shoutcast.v1.ShoutcastV1ConfigurationEditor;
|
||||
import audio.broadcast.shoutcast.v2.ShoutcastV2AudioBroadcaster;
|
||||
import audio.broadcast.shoutcast.v2.ShoutcastV2Configuration;
|
||||
import audio.convert.IAudioConverter;
|
||||
@@ -46,8 +46,6 @@ import record.mp3.MP3Recorder;
|
||||
import settings.SettingsManager;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BroadcastFactory
|
||||
{
|
||||
@@ -55,20 +53,6 @@ public class BroadcastFactory
|
||||
|
||||
public static final int MP3_MONO_16_KHZ_BITRATE = 16;
|
||||
public static final boolean MP3_CONSTANT_BITRATE = false;
|
||||
private static MP3AudioConverter MP3_SILENT_FRAME_GENERATOR;
|
||||
|
||||
static
|
||||
{
|
||||
MP3_SILENT_FRAME_GENERATOR = new MP3AudioConverter(MP3Recorder.MP3_BIT_RATE, MP3Recorder.CONSTANT_BIT_RATE);
|
||||
|
||||
//We have to charge the converter pipeline with 1200 milliseconds to get 1 second of audio the first time
|
||||
float[] silence = new float[9600]; //1200 milliseconds at 8000 kHz
|
||||
AudioPacket silencePacket = new AudioPacket(silence, null);
|
||||
List<AudioPacket> silencePackets = new ArrayList<>();
|
||||
silencePackets.add(silencePacket);
|
||||
MP3_SILENT_FRAME_GENERATOR.convert(silencePackets);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates an audio streaming broadcaster for the configuration
|
||||
@@ -185,6 +169,9 @@ public class BroadcastFactory
|
||||
case ICECAST_HTTP:
|
||||
editor = new IcecastHTTPConfigurationEditor(broadcastModel, aliasModel, settingsManager);
|
||||
break;
|
||||
case SHOUTCAST_V1:
|
||||
editor = new ShoutcastV1ConfigurationEditor(broadcastModel, aliasModel, settingsManager);
|
||||
break;
|
||||
default:
|
||||
editor = new EmptyEditor<BroadcastConfiguration>();
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user