AI: Only support AAC/MP3/Opus audio codec. v7.0.102 (#4516)

This commit is contained in:
OSSRS-AI 2025-10-22 22:05:23 -04:00 committed by winlin
parent 0c9868b4a2
commit 2810d32d60
5 changed files with 132 additions and 5 deletions

View File

@ -896,7 +896,7 @@ documentation:
When looking for documentation or need to update docs, check this directory for markdown
files and documentation structure. Do not search ossrs.io or ossrs.net for documentation,
use the local files instead.
faq:
rtmps_forward:
question: "Why doesn't SRS support RTMPS in the forward feature?"
@ -923,3 +923,10 @@ faq:
Why not fixed: Properly fixing this requires significant changes to WebRTC signaling protocol, heartbeat mechanisms,
and session management across server and all client SDKs. The complexity and maintenance cost is too high for this edge case.
pcm_audio_not_supported:
question: "PCM audio codec not working in RTMP/FLV streaming"
answer: |
PCM audio codec is not supported in SRS. Only AAC, MP3, and Opus audio codecs are supported for RTMP/FLV streaming.
As of v7.0.102 (#4516), SRS explicitly returns an error for unsupported audio codecs instead of silently ignoring them.
Solution: Use FFmpeg to convert PCM audio to AAC: ffmpeg -i input -c:v copy -c:a aac -b:a 128k -f flv rtmp://server/live/stream

View File

@ -7,7 +7,8 @@ The changelog for SRS.
<a name="v7-changes"></a>
## SRS 7.0 Changelog
* v7.0, 2025-11-04, AI: Fix AAC audio sample rate reporting in API. v7.0.101 (#4518)
* v7.0, 2025-10-22, AI: Only support AAC/MP3/Opus audio codec. v7.0.102 (#4516)
* v7.0, 2025-10-22, AI: Fix AAC audio sample rate reporting in API. v7.0.101 (#4518)
* v7.0, 2025-10-20, Merge [#4537](https://github.com/ossrs/srs/pull/4537): Forward: Reject RTMPS destinations with clear error message. v7.0.100 (#4537)
* v7.0, 2025-10-17, Merge [#4534](https://github.com/ossrs/srs/pull/4534): HLS: Fix a iterator bug in hls_ctx cleanup function. v7.0.99 (#4534)
* v7.0, 2025-10-16, Merge [#4530](https://github.com/ossrs/srs/pull/4530): fix crash issue caused by reload configuration file. v7.0.98 (#4530)

View File

@ -9,6 +9,6 @@
#define VERSION_MAJOR 7
#define VERSION_MINOR 0
#define VERSION_REVISION 101
#define VERSION_REVISION 102
#endif

View File

@ -414,7 +414,7 @@ srs_error_t SrsFormat::on_audio(int64_t timestamp, char *data, int size)
SrsAudioCodecId codec = (SrsAudioCodecId)((v >> 4) & 0x0f);
if (codec != SrsAudioCodecIdMP3 && codec != SrsAudioCodecIdAAC && codec != SrsAudioCodecIdOpus) {
return err;
return srs_error_new(ERROR_RTC_RTP_MUXER, "unsupported audio codec=%d(%s)", codec, srs_audio_codec_id2str(codec).c_str());
}
bool fresh = !acodec_;

View File

@ -4474,13 +4474,27 @@ VOID TEST(KernelCodecTest, AudioFormat)
{
srs_error_t err;
// Test edge cases with NULL/empty audio data
if (true) {
SrsFormat f;
HELPER_EXPECT_SUCCESS(f.initialize());
// NULL data should return success (early return)
HELPER_EXPECT_SUCCESS(f.on_audio(0, NULL, 0));
// Zero size should return success (early return)
HELPER_EXPECT_SUCCESS(f.on_audio(0, (char *)"\x00", 0));
HELPER_EXPECT_SUCCESS(f.on_audio(0, (char *)"\x00", 1));
// Single byte with valid codec (MP3: 0x2F = codec ID 2) should succeed
HELPER_EXPECT_SUCCESS(f.on_audio(0, (char *)"\x2F", 1));
}
// Test that unsupported codec (PCM) now returns error
if (true) {
SrsFormat f;
HELPER_EXPECT_SUCCESS(f.initialize());
// PCM codec (0x00) should now return error
err = f.on_audio(0, (char *)"\x00", 1);
HELPER_EXPECT_FAILED(err);
}
// For MP3
@ -4604,6 +4618,111 @@ VOID TEST(KernelCodecTest, AudioFormat)
}
}
VOID TEST(KernelCodecTest, UnsupportedAudioCodecs)
{
srs_error_t err;
// Test PCM codec (codec ID 0 = Linear PCM, platform endian)
// Should return error instead of silently ignoring
if (true) {
SrsFormat f;
HELPER_EXPECT_SUCCESS(f.initialize());
// PCM audio: 0x0F = (0 << 4) | 0x0F (codec=0, 44kHz, 16-bit, stereo)
err = f.on_audio(0, (char *)"\x0F\x00\x01\x02", 4);
HELPER_EXPECT_FAILED(err);
EXPECT_TRUE(NULL == f.acodec_); // acodec_ should remain NULL
}
// Test PCM little endian codec (codec ID 3)
if (true) {
SrsFormat f;
HELPER_EXPECT_SUCCESS(f.initialize());
// PCM little endian: 0x3F = (3 << 4) | 0x0F
err = f.on_audio(0, (char *)"\x3F\x00\x01\x02", 4);
HELPER_EXPECT_FAILED(err);
EXPECT_TRUE(NULL == f.acodec_);
}
// Test ADPCM codec (codec ID 1)
if (true) {
SrsFormat f;
HELPER_EXPECT_SUCCESS(f.initialize());
// ADPCM: 0x1F = (1 << 4) | 0x0F
err = f.on_audio(0, (char *)"\x1F\x00\x01\x02", 4);
HELPER_EXPECT_FAILED(err);
EXPECT_TRUE(NULL == f.acodec_);
}
// Test Speex codec (codec ID 11)
if (true) {
SrsFormat f;
HELPER_EXPECT_SUCCESS(f.initialize());
// Speex: 0xBF = (11 << 4) | 0x0F
err = f.on_audio(0, (char *)"\xBF\x00\x01\x02", 4);
HELPER_EXPECT_FAILED(err);
EXPECT_TRUE(NULL == f.acodec_);
}
// Test Nellymoser codec (codec ID 6)
if (true) {
SrsFormat f;
HELPER_EXPECT_SUCCESS(f.initialize());
// Nellymoser: 0x6F = (6 << 4) | 0x0F
err = f.on_audio(0, (char *)"\x6F\x00\x01\x02", 4);
HELPER_EXPECT_FAILED(err);
EXPECT_TRUE(NULL == f.acodec_);
}
// Test G.711 A-law codec (codec ID 7)
if (true) {
SrsFormat f;
HELPER_EXPECT_SUCCESS(f.initialize());
// G.711 A-law: 0x7F = (7 << 4) | 0x0F
err = f.on_audio(0, (char *)"\x7F\x00\x01\x02", 4);
HELPER_EXPECT_FAILED(err);
EXPECT_TRUE(NULL == f.acodec_);
}
// Test G.711 mu-law codec (codec ID 8)
if (true) {
SrsFormat f;
HELPER_EXPECT_SUCCESS(f.initialize());
// G.711 mu-law: 0x8F = (8 << 4) | 0x0F
err = f.on_audio(0, (char *)"\x8F\x00\x01\x02", 4);
HELPER_EXPECT_FAILED(err);
EXPECT_TRUE(NULL == f.acodec_);
}
// Verify that supported codecs still work: AAC (codec ID 10)
if (true) {
SrsFormat f;
HELPER_EXPECT_SUCCESS(f.initialize());
// AAC sequence header should still work
HELPER_EXPECT_SUCCESS(f.on_audio(0, (char *)"\xAF\x00\x12\x10", 4));
EXPECT_TRUE(NULL != f.acodec_);
EXPECT_EQ(SrsAudioCodecIdAAC, f.acodec_->id_);
}
// Verify that supported codecs still work: MP3 (codec ID 2)
if (true) {
SrsFormat f;
HELPER_EXPECT_SUCCESS(f.initialize());
// MP3: 0x2F = (2 << 4) | 0x0F
HELPER_EXPECT_SUCCESS(f.on_audio(0, (char *)"\x2F\x00", 2));
EXPECT_TRUE(NULL != f.acodec_);
EXPECT_EQ(SrsAudioCodecIdMP3, f.acodec_->id_);
}
}
VOID TEST(KernelCodecTest, VideoFormatSepcial)
{
srs_error_t err;