Skip to content

Commit c94e8f6

Browse files
author
dsward2
committed
This commit adds support for Icecast streaming with SSL/TLS encryption. Icecast is configured with two ports to stream LocalRadio audio, via http and https schemes.
The source audio connection uses http to stream to the Icecast server. Since the Icecast server and the source are both running on the same hosts, there was little benefit to encrypting that connection. Although the Icecast server now supports https, the user interface web server currently still supports only http. The plan is to add https support there in a future commit. The Bonjour hostname (e.g., joes-macintosh.local) is now used to identify the host in most cases. An experimental new tool was created - IcecastSourceClient - and a customized version libshout library to support AAC was also added. It was originally hoped that libshout would provide an easier way to encrypt the source connection, but I never got it to work due to various issues with the app sandbox and BoringSSL. The sandbox problems were mostly resolved by removing the MacPorts versions of OpenSSL's libssl and libcrypto which needed file access (for root certificates, etc.), and libcurl, libxml and libxslt, and instead using the standard Mac versions of those libraries in /usr/lib/, etc. Some code units were inspected and modified with otool and install_name_tool to use the Mac libraries. Ultimately, the previous "IcecastSource" tool turned out to work better than "IcecastSourceClient" with libshout, so the app is sticking with IcecastSource. The unused libshout source will remain in the project for reference purposes for now. A bug was fixed where the main thread was using a sleep command. A bug was fixed to avoid a crash during status updates. Some fflush() commands were added to stdout functions in AACEncoder, AudioMonitor2.
1 parent 42f78d9 commit c94e8f6

File tree

210 files changed

+50431
-389
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

210 files changed

+50431
-389
lines changed

AACEncoder/AACEncoder.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@
223223
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
224224
GCC_WARN_UNUSED_FUNCTION = YES;
225225
GCC_WARN_UNUSED_VARIABLE = YES;
226-
MACOSX_DEPLOYMENT_TARGET = 10.13;
226+
MACOSX_DEPLOYMENT_TARGET = 10.11;
227227
MTL_ENABLE_DEBUG_INFO = YES;
228228
ONLY_ACTIVE_ARCH = YES;
229229
SDKROOT = macosx;
@@ -275,7 +275,7 @@
275275
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
276276
GCC_WARN_UNUSED_FUNCTION = YES;
277277
GCC_WARN_UNUSED_VARIABLE = YES;
278-
MACOSX_DEPLOYMENT_TARGET = 10.13;
278+
MACOSX_DEPLOYMENT_TARGET = 10.11;
279279
MTL_ENABLE_DEBUG_INFO = NO;
280280
SDKROOT = macosx;
281281
};
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Scheme
3+
LastUpgradeVersion = "1000"
4+
version = "1.3">
5+
<BuildAction
6+
parallelizeBuildables = "YES"
7+
buildImplicitDependencies = "YES">
8+
<BuildActionEntries>
9+
<BuildActionEntry
10+
buildForTesting = "YES"
11+
buildForRunning = "YES"
12+
buildForProfiling = "YES"
13+
buildForArchiving = "YES"
14+
buildForAnalyzing = "YES">
15+
<BuildableReference
16+
BuildableIdentifier = "primary"
17+
BlueprintIdentifier = "0E727340214892C800C5B5DE"
18+
BuildableName = "AACEncoder"
19+
BlueprintName = "AACEncoder"
20+
ReferencedContainer = "container:AACEncoder.xcodeproj">
21+
</BuildableReference>
22+
</BuildActionEntry>
23+
</BuildActionEntries>
24+
</BuildAction>
25+
<TestAction
26+
buildConfiguration = "Debug"
27+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29+
shouldUseLaunchSchemeArgsEnv = "YES">
30+
<Testables>
31+
</Testables>
32+
<MacroExpansion>
33+
<BuildableReference
34+
BuildableIdentifier = "primary"
35+
BlueprintIdentifier = "0E727340214892C800C5B5DE"
36+
BuildableName = "AACEncoder"
37+
BlueprintName = "AACEncoder"
38+
ReferencedContainer = "container:AACEncoder.xcodeproj">
39+
</BuildableReference>
40+
</MacroExpansion>
41+
<AdditionalOptions>
42+
</AdditionalOptions>
43+
</TestAction>
44+
<LaunchAction
45+
buildConfiguration = "Debug"
46+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
47+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
48+
launchStyle = "1"
49+
useCustomWorkingDirectory = "NO"
50+
ignoresPersistentStateOnLaunch = "NO"
51+
debugDocumentVersioning = "YES"
52+
debugServiceExtension = "internal"
53+
allowLocationSimulation = "YES">
54+
<BuildableProductRunnable
55+
runnableDebuggingMode = "0">
56+
<BuildableReference
57+
BuildableIdentifier = "primary"
58+
BlueprintIdentifier = "0E727340214892C800C5B5DE"
59+
BuildableName = "AACEncoder"
60+
BlueprintName = "AACEncoder"
61+
ReferencedContainer = "container:AACEncoder.xcodeproj">
62+
</BuildableReference>
63+
</BuildableProductRunnable>
64+
<AdditionalOptions>
65+
</AdditionalOptions>
66+
</LaunchAction>
67+
<ProfileAction
68+
buildConfiguration = "Release"
69+
shouldUseLaunchSchemeArgsEnv = "YES"
70+
savedToolIdentifier = ""
71+
useCustomWorkingDirectory = "NO"
72+
debugDocumentVersioning = "YES">
73+
<BuildableProductRunnable
74+
runnableDebuggingMode = "0">
75+
<BuildableReference
76+
BuildableIdentifier = "primary"
77+
BlueprintIdentifier = "0E727340214892C800C5B5DE"
78+
BuildableName = "AACEncoder"
79+
BlueprintName = "AACEncoder"
80+
ReferencedContainer = "container:AACEncoder.xcodeproj">
81+
</BuildableReference>
82+
</BuildableProductRunnable>
83+
</ProfileAction>
84+
<AnalyzeAction
85+
buildConfiguration = "Debug">
86+
</AnalyzeAction>
87+
<ArchiveAction
88+
buildConfiguration = "Release"
89+
revealArchiveInOrganizer = "YES">
90+
</ArchiveAction>
91+
</Scheme>

AACEncoder/AACEncoder/AACEncoder.cpp

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -937,9 +937,14 @@ void startAudioConverter()
937937
//audioConverterOutputDescription.mFormatID = kAudioFormatMPEG4AAC_HE_V2;
938938

939939
//audioConverterOutputDescription.mFormatFlags = kMPEG4Object_AAC_SBR;
940-
audioConverterOutputDescription.mFormatFlags = 0;
940+
//audioConverterOutputDescription.mFormatFlags = kMPEG4Object_AAC_LC;
941+
//audioConverterOutputDescription.mFormatFlags = 0;
941942

943+
//audioConverterOutputDescription.mFramesPerPacket = 1024;
942944
audioConverterOutputDescription.mFramesPerPacket = 2048; // for AAC-HE per https://lists.apple.com/archives/coreaudio-api/2011/Mar/msg00176.html
945+
//audioConverterOutputDescription.mFramesPerPacket = 1536; // per kAudioConverterPropertyMaximumOutputPacketSize
946+
//audioConverterOutputDescription.mFramesPerPacket = 3072; // per kAudioConverterPropertyMaximumOutputPacketSize
947+
//audioConverterOutputDescription.mFramesPerPacket = 0;
943948
}
944949

945950
logDescription(&audioConverterOutputDescription, "audioConverterOutputDescription");
@@ -994,7 +999,7 @@ void startAudioConverter()
994999
*/
9951000

9961001

997-
logAudioConverterProperties();
1002+
//logAudioConverterProperties(); // this is a good place to log audio converter properties
9981003
}
9991004

10001005
//==================================================================================
@@ -1122,24 +1127,19 @@ void convertBuffer(void * inputBufferPtr, unsigned int dataLength)
11221127
&audioConverterOutputBufferList, // AudioBufferList *outOutputData
11231128
&outputPacketDescriptions // AudioStreamPacketDescription *outPacketDescription
11241129
);
1125-
1130+
11261131
//fprintf(stderr, "AACEncoder convertBuffer AudioConverterFillComplexBuffer result = %d, outputDataPacketSize = %d\n", convertResult, outputDataPacketSize);
11271132

11281133
if ((convertResult == noErr) || (convertResult == 'zero'))
11291134
{
11301135
if (outputDataPacketSize > 0) // number of packets converted
11311136
{
11321137
// produce encoded audio to stdout
1133-
1134-
SInt64 mStartOffset = outputPacketDescriptions.mStartOffset;
1135-
UInt32 mVariableFramesInPacket = outputPacketDescriptions.mVariableFramesInPacket;
1136-
UInt32 mDataByteSize = outputPacketDescriptions.mDataByteSize;
1137-
#pragma unused(mStartOffset, mVariableFramesInPacket, mDataByteSize)
1138-
1138+
11391139
int32_t convertedDataLength = audioConverterOutputBufferList.mBuffers[0].mDataByteSize;
11401140
void * convertedDataPtr = audioConverterOutputBufferList.mBuffers[0].mData;
11411141

1142-
//fprintf(stderr, "AACEncoder convertBuffer AudioConverterFillComplexBuffer mStartOffset = %lld, mVariableFramesInPacket = %d, mDataByteSize = %d, convertedDataLength = %d\n", mStartOffset, mVariableFramesInPacket, mDataByteSize, convertedDataLength);
1142+
//fprintf(stderr, "AACEncoder convertBuffer AudioConverterFillComplexBuffer mStartOffset = %lld, mVariableFramesInPacket = %d, mDataByteSize = %d\n", mStartOffset, mVariableFramesInPacket, mDataByteSize);
11431143

11441144
// format ADTS header per https://wiki.multimedia.cx/index.php/ADTS
11451145
// ADTS header decoder: http://www.p23.nl/projects/aac-header/
@@ -1152,17 +1152,6 @@ void convertBuffer(void * inputBufferPtr, unsigned int dataLength)
11521152
UInt32 chanCfg = 2; // channels
11531153
UInt32 fullLength = adtsHeaderLength + convertedDataLength;
11541154

1155-
/*
1156-
// adapted from https://github.com/JQJoe/AACEncodeAndDecode
1157-
adtsHeader[0] = (UInt8)0xFF; // syncword
1158-
adtsHeader[1] = (UInt8)0xF9; // syncword, mpeg version, layer, CRC protection absent
1159-
adtsHeader[2] = (UInt8)(((profile-1)<<6) + (freqIdx<<2) + (chanCfg>>2)); // profile, sampling frequency index, private bit, channel configuration
1160-
adtsHeader[3] = (UInt8)(((chanCfg&3)<<6) + (fullLength>>11)); // channel configuration, originality, home, copyrighted, copyright id, frame length
1161-
adtsHeader[4] = (UInt8)((fullLength&0x7FF) >> 3); // frame length
1162-
adtsHeader[5] = (UInt8)(((fullLength&7)<<5) + 0x1F); // frame length, buffer fullness
1163-
adtsHeader[6] = (UInt8)0xFC; // buffer fullness, number of aac frames minus one
1164-
*/
1165-
11661155
// adapted from http://lists.live555.com/pipermail/live-devel/2009-August/011113.html
11671156
/* Sync point over a full byte */
11681157
adtsHeader[0] = 0xFF;
@@ -1224,6 +1213,8 @@ void convertBuffer(void * inputBufferPtr, unsigned int dataLength)
12241213

12251214
fwrite(adtsPacketPtr, packetLength, 1, stdout); // write ADTS packet
12261215

1216+
fflush(stdout);
1217+
12271218
if (outputPacketCount == 0)
12281219
{
12291220
// log the first ADTS header
@@ -1318,7 +1309,7 @@ void * runAudioConverterOnThread(void * ptr)
13181309
int32_t bytesConsumedCount = bytesAvailableCount;
13191310

13201311
int32_t maxBytesCount = (inputChannels * sizeof(SInt16) * 1024); // 1024 samples = 2048 for one channel, 4096 for two channels
1321-
1312+
13221313
if (bytesConsumedCount > maxBytesCount)
13231314
{
13241315
bytesConsumedCount = maxBytesCount; // kAudioConverterPropertyMaximumInputBufferSize = 4100
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Scheme
3+
LastUpgradeVersion = "0930"
4+
version = "1.3">
5+
<BuildAction
6+
parallelizeBuildables = "YES"
7+
buildImplicitDependencies = "YES">
8+
<BuildActionEntries>
9+
<BuildActionEntry
10+
buildForTesting = "YES"
11+
buildForRunning = "YES"
12+
buildForProfiling = "YES"
13+
buildForArchiving = "YES"
14+
buildForAnalyzing = "YES">
15+
<BuildableReference
16+
BuildableIdentifier = "primary"
17+
BlueprintIdentifier = "0EB51DED212D3E2F0059D84C"
18+
BuildableName = "AudioMonitor2"
19+
BlueprintName = "AudioMonitor2"
20+
ReferencedContainer = "container:AudioMonitor.xcodeproj">
21+
</BuildableReference>
22+
</BuildActionEntry>
23+
</BuildActionEntries>
24+
</BuildAction>
25+
<TestAction
26+
buildConfiguration = "Debug"
27+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29+
shouldUseLaunchSchemeArgsEnv = "YES">
30+
<Testables>
31+
</Testables>
32+
<MacroExpansion>
33+
<BuildableReference
34+
BuildableIdentifier = "primary"
35+
BlueprintIdentifier = "0EB51DED212D3E2F0059D84C"
36+
BuildableName = "AudioMonitor2"
37+
BlueprintName = "AudioMonitor2"
38+
ReferencedContainer = "container:AudioMonitor.xcodeproj">
39+
</BuildableReference>
40+
</MacroExpansion>
41+
<AdditionalOptions>
42+
</AdditionalOptions>
43+
</TestAction>
44+
<LaunchAction
45+
buildConfiguration = "Debug"
46+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
47+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
48+
launchStyle = "1"
49+
useCustomWorkingDirectory = "NO"
50+
ignoresPersistentStateOnLaunch = "NO"
51+
debugDocumentVersioning = "YES"
52+
debugServiceExtension = "internal"
53+
allowLocationSimulation = "YES">
54+
<BuildableProductRunnable
55+
runnableDebuggingMode = "0">
56+
<BuildableReference
57+
BuildableIdentifier = "primary"
58+
BlueprintIdentifier = "0EB51DED212D3E2F0059D84C"
59+
BuildableName = "AudioMonitor2"
60+
BlueprintName = "AudioMonitor2"
61+
ReferencedContainer = "container:AudioMonitor.xcodeproj">
62+
</BuildableReference>
63+
</BuildableProductRunnable>
64+
<AdditionalOptions>
65+
</AdditionalOptions>
66+
</LaunchAction>
67+
<ProfileAction
68+
buildConfiguration = "Release"
69+
shouldUseLaunchSchemeArgsEnv = "YES"
70+
savedToolIdentifier = ""
71+
useCustomWorkingDirectory = "NO"
72+
debugDocumentVersioning = "YES">
73+
<BuildableProductRunnable
74+
runnableDebuggingMode = "0">
75+
<BuildableReference
76+
BuildableIdentifier = "primary"
77+
BlueprintIdentifier = "0EB51DED212D3E2F0059D84C"
78+
BuildableName = "AudioMonitor2"
79+
BlueprintName = "AudioMonitor2"
80+
ReferencedContainer = "container:AudioMonitor.xcodeproj">
81+
</BuildableReference>
82+
</BuildableProductRunnable>
83+
</ProfileAction>
84+
<AnalyzeAction
85+
buildConfiguration = "Debug">
86+
</AnalyzeAction>
87+
<ArchiveAction
88+
buildConfiguration = "Release"
89+
revealArchiveInOrganizer = "YES">
90+
</ArchiveAction>
91+
</Scheme>

AudioMonitor/AudioMonitor/AudioMonitor.mm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,8 @@ - (void)convertBuffer:(void *)inputBufferPtr length:(UInt32)dataLength
509509

510510
fwrite(convertedDataPtr, convertedDataLength, 1, stdout); // write resampled audio to stdout, can be piped to sox, etc.
511511

512+
fflush(stdout);
513+
512514
bool produceBytesResult = TPCircularBufferProduceBytes(&audioConverterCircularBuffer, convertedDataPtr, convertedDataLength);
513515

514516
if (produceBytesResult == false)

AudioMonitor/AudioMonitor/AudioMonitor2.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,7 @@ void * runInputBufferOnThread(void * ptr)
797797
}
798798
else
799799
{
800-
fprintf(stderr, "AudioMonitor2 runInputBufferOnThread error - bytesAvailableCount %d misaligned for packet size\n", bytesAvailableCount);
800+
//fprintf(stderr, "AudioMonitor2 runInputBufferOnThread error - bytesAvailableCount %d misaligned for packet size\n", bytesAvailableCount);
801801
}
802802
}
803803

@@ -1141,6 +1141,8 @@ void convertBuffer(void * inputBufferPtr, unsigned int dataLength)
11411141
}
11421142

11431143
fwrite(convertedDataPtr, convertedDataLength, 1, stdout); // write resampled audio to stdout, can be piped to sox, etc.
1144+
1145+
fflush(stdout);
11441146

11451147
/*
11461148
if (packetOutputIndex == 0)

IcecastSource/IcecastSource.xcodeproj/project.pbxproj

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3058,7 +3058,7 @@
30583058
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
30593059
GCC_WARN_UNUSED_FUNCTION = YES;
30603060
GCC_WARN_UNUSED_VARIABLE = YES;
3061-
MACOSX_DEPLOYMENT_TARGET = 10.13;
3061+
MACOSX_DEPLOYMENT_TARGET = 10.11;
30623062
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
30633063
MTL_FAST_MATH = YES;
30643064
ONLY_ACTIVE_ARCH = YES;
@@ -3111,7 +3111,7 @@
31113111
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
31123112
GCC_WARN_UNUSED_FUNCTION = YES;
31133113
GCC_WARN_UNUSED_VARIABLE = YES;
3114-
MACOSX_DEPLOYMENT_TARGET = 10.13;
3114+
MACOSX_DEPLOYMENT_TARGET = 10.11;
31153115
MTL_ENABLE_DEBUG_INFO = NO;
31163116
MTL_FAST_MATH = YES;
31173117
SDKROOT = macosx;
@@ -3122,7 +3122,6 @@
31223122
isa = XCBuildConfiguration;
31233123
buildSettings = {
31243124
CODE_SIGN_ENTITLEMENTS = IcecastSource.entitlements;
3125-
CODE_SIGN_IDENTITY = "Developer ID Application";
31263125
CODE_SIGN_STYLE = Manual;
31273126
DEVELOPMENT_TEAM = MMFBWVS455;
31283127
HEADER_SEARCH_PATHS = (
@@ -3139,7 +3138,6 @@
31393138
isa = XCBuildConfiguration;
31403139
buildSettings = {
31413140
CODE_SIGN_ENTITLEMENTS = IcecastSource.entitlements;
3142-
CODE_SIGN_IDENTITY = "Developer ID Application";
31433141
CODE_SIGN_STYLE = Manual;
31443142
DEVELOPMENT_TEAM = MMFBWVS455;
31453143
HEADER_SEARCH_PATHS = (

0 commit comments

Comments
 (0)