diff --git a/src/main/java/io/github/dsheirer/audio/broadcast/BroadcastConfiguration.java b/src/main/java/io/github/dsheirer/audio/broadcast/BroadcastConfiguration.java
index 8391c492..e6069897 100644
--- a/src/main/java/io/github/dsheirer/audio/broadcast/BroadcastConfiguration.java
+++ b/src/main/java/io/github/dsheirer/audio/broadcast/BroadcastConfiguration.java
@@ -25,6 +25,7 @@ import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import io.github.dsheirer.audio.broadcast.broadcastify.BroadcastifyCallConfiguration;
import io.github.dsheirer.audio.broadcast.rdioscanner.RdioScannerConfiguration;
+import io.github.dsheirer.audio.broadcast.thinline.ThinlineRadioConfiguration;
import io.github.dsheirer.audio.broadcast.openmhz.OpenMHzConfiguration;
import io.github.dsheirer.audio.broadcast.icecast.IcecastConfiguration;
import io.github.dsheirer.audio.broadcast.shoutcast.v1.ShoutcastV1Configuration;
@@ -49,6 +50,7 @@ import java.net.SocketAddress;
@JsonSubTypes({
@JsonSubTypes.Type(value = BroadcastifyCallConfiguration.class, name="broadcastifyCallConfiguration"),
@JsonSubTypes.Type(value = RdioScannerConfiguration.class, name="RdioScannerConfiguration"),
+ @JsonSubTypes.Type(value = ThinlineRadioConfiguration.class, name="ThinlineRadioConfiguration"),
@JsonSubTypes.Type(value = OpenMHzConfiguration.class, name="OpenMHzConfiguration"),
@JsonSubTypes.Type(value = IcecastConfiguration.class, name="icecastConfiguration"),
@JsonSubTypes.Type(value = ShoutcastV1Configuration.class, name="shoutcastV1Configuration"),
diff --git a/src/main/java/io/github/dsheirer/audio/broadcast/BroadcastFactory.java b/src/main/java/io/github/dsheirer/audio/broadcast/BroadcastFactory.java
index f513938d..43a2a8e0 100644
--- a/src/main/java/io/github/dsheirer/audio/broadcast/BroadcastFactory.java
+++ b/src/main/java/io/github/dsheirer/audio/broadcast/BroadcastFactory.java
@@ -24,6 +24,7 @@ import io.github.dsheirer.audio.broadcast.broadcastify.BroadcastifyCallConfigura
import io.github.dsheirer.audio.broadcast.broadcastify.BroadcastifyFeedConfiguration;
import io.github.dsheirer.audio.broadcast.rdioscanner.RdioScannerBroadcaster;
import io.github.dsheirer.audio.broadcast.rdioscanner.RdioScannerConfiguration;
+import io.github.dsheirer.audio.broadcast.thinline.ThinlineRadioConfiguration;
import io.github.dsheirer.audio.broadcast.rdioscanner.RdioScannerFeedConfiguration;
import io.github.dsheirer.audio.broadcast.openmhz.OpenMHzBroadcaster;
import io.github.dsheirer.audio.broadcast.openmhz.OpenMHzConfiguration;
@@ -68,6 +69,7 @@ public class BroadcastFactory
return new BroadcastifyCallBroadcaster((BroadcastifyCallConfiguration)configuration,
inputAudioFormat, mp3Setting, aliasModel);
case RDIOSCANNER_CALL:
+ case THINLINE_RADIO:
return new RdioScannerBroadcaster((RdioScannerConfiguration)configuration,
inputAudioFormat, mp3Setting, aliasModel);
case OPENMHZ:
@@ -113,6 +115,8 @@ public class BroadcastFactory
return new BroadcastifyCallConfiguration(format);
case RDIOSCANNER_CALL:
return new RdioScannerConfiguration(format);
+ case THINLINE_RADIO:
+ return new ThinlineRadioConfiguration(format);
case BROADCASTIFY:
return new BroadcastifyFeedConfiguration(format);
case OPENMHZ:
diff --git a/src/main/java/io/github/dsheirer/audio/broadcast/BroadcastServerType.java b/src/main/java/io/github/dsheirer/audio/broadcast/BroadcastServerType.java
index b33e88c8..07c09799 100644
--- a/src/main/java/io/github/dsheirer/audio/broadcast/BroadcastServerType.java
+++ b/src/main/java/io/github/dsheirer/audio/broadcast/BroadcastServerType.java
@@ -32,6 +32,7 @@ public enum BroadcastServerType
ICECAST_HTTP("Icecast 2 (v2.4+)", "images/icecast.png"),
RDIOSCANNER_CALL("Rdio Scanner", "images/rdioscanner.png"),
+ THINLINE_RADIO("Thinline Radio", "images/rdioscanner.png"),
OPENMHZ("OpenMHz", "images/openmhz.png"),
ICECAST_TCP("Icecast (v2.3)", "images/icecast.png"),
SHOUTCAST_V1("Shoutcast v1.x", "images/shoutcast.png"),
diff --git a/src/main/java/io/github/dsheirer/audio/broadcast/rdioscanner/RdioScannerBroadcaster.java b/src/main/java/io/github/dsheirer/audio/broadcast/rdioscanner/RdioScannerBroadcaster.java
index 468a42dd..2cb9ffdd 100644
--- a/src/main/java/io/github/dsheirer/audio/broadcast/rdioscanner/RdioScannerBroadcaster.java
+++ b/src/main/java/io/github/dsheirer/audio/broadcast/rdioscanner/RdioScannerBroadcaster.java
@@ -113,7 +113,8 @@ public class RdioScannerBroadcaster extends AbstractAudioBroadcaster
+ * ****************************************************************************
+ */
+
+package io.github.dsheirer.audio.broadcast.thinline;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import io.github.dsheirer.audio.broadcast.BroadcastConfiguration;
+import io.github.dsheirer.audio.broadcast.BroadcastFormat;
+import io.github.dsheirer.audio.broadcast.BroadcastServerType;
+import io.github.dsheirer.audio.broadcast.rdioscanner.RdioScannerConfiguration;
+
+/**
+ * Call upload configuration for Thinline Radio.
+ *
+ * Thinline Radio accepts the same completed-call upload used by Rdio Scanner, including the system id, API key,
+ * and /api/call-upload path.
+ */
+public class ThinlineRadioConfiguration extends RdioScannerConfiguration
+{
+ /**
+ * Constructor for Jackson
+ */
+ public ThinlineRadioConfiguration()
+ {
+ this(BroadcastFormat.MP3);
+ }
+
+ /**
+ * Public constructor.
+ * @param format to use for audio recording (MP3)
+ */
+ public ThinlineRadioConfiguration(BroadcastFormat format)
+ {
+ super(format);
+ }
+
+ @JacksonXmlProperty(isAttribute = true, localName = "type", namespace = "http://www.w3.org/2001/XMLSchema-instance")
+ @Override
+ public BroadcastServerType getBroadcastServerType()
+ {
+ return BroadcastServerType.THINLINE_RADIO;
+ }
+
+ @JsonIgnore
+ @Override
+ public String getServiceName()
+ {
+ return "Thinline Radio";
+ }
+
+ @Override
+ public BroadcastConfiguration copyOf()
+ {
+ ThinlineRadioConfiguration copy = new ThinlineRadioConfiguration();
+ copy.setSystemID(getSystemID());
+ return copy;
+ }
+}
diff --git a/src/main/java/io/github/dsheirer/gui/playlist/streaming/RdioScannerEditor.java b/src/main/java/io/github/dsheirer/gui/playlist/streaming/RdioScannerEditor.java
index 485b5ffe..03699700 100644
--- a/src/main/java/io/github/dsheirer/gui/playlist/streaming/RdioScannerEditor.java
+++ b/src/main/java/io/github/dsheirer/gui/playlist/streaming/RdioScannerEditor.java
@@ -119,6 +119,22 @@ public class RdioScannerEditor extends AbstractBroadcastEditor
+ * ****************************************************************************
+ */
+
+package io.github.dsheirer.gui.playlist.streaming;
+
+import io.github.dsheirer.audio.broadcast.BroadcastServerType;
+import io.github.dsheirer.playlist.PlaylistManager;
+
+/**
+ * Thinline Radio call upload configuration editor.
+ *
+ * The form and upload path match the Rdio Scanner editor.
+ */
+public class ThinlineRadioEditor extends RdioScannerEditor
+{
+ /**
+ * Constructs an instance
+ * @param playlistManager for accessing the broadcast model
+ */
+ public ThinlineRadioEditor(PlaylistManager playlistManager)
+ {
+ super(playlistManager);
+ }
+
+ @Override
+ public BroadcastServerType getBroadcastServerType()
+ {
+ return BroadcastServerType.THINLINE_RADIO;
+ }
+
+ @Override
+ protected String getHostLabel()
+ {
+ return "Thinline Radio URL";
+ }
+}