AI: Only support AAC/MP3/Opus audio codec. v7.0.102 (#4516)
This commit is contained in:
parent
0c9868b4a2
commit
2810d32d60
|
|
@ -923,3 +923,10 @@ faq:
|
||||||
Why not fixed: Properly fixing this requires significant changes to WebRTC signaling protocol, heartbeat mechanisms,
|
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.
|
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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@ The changelog for SRS.
|
||||||
<a name="v7-changes"></a>
|
<a name="v7-changes"></a>
|
||||||
|
|
||||||
## SRS 7.0 Changelog
|
## 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-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-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)
|
* 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)
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,6 @@
|
||||||
|
|
||||||
#define VERSION_MAJOR 7
|
#define VERSION_MAJOR 7
|
||||||
#define VERSION_MINOR 0
|
#define VERSION_MINOR 0
|
||||||
#define VERSION_REVISION 101
|
#define VERSION_REVISION 102
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -414,7 +414,7 @@ srs_error_t SrsFormat::on_audio(int64_t timestamp, char *data, int size)
|
||||||
SrsAudioCodecId codec = (SrsAudioCodecId)((v >> 4) & 0x0f);
|
SrsAudioCodecId codec = (SrsAudioCodecId)((v >> 4) & 0x0f);
|
||||||
|
|
||||||
if (codec != SrsAudioCodecIdMP3 && codec != SrsAudioCodecIdAAC && codec != SrsAudioCodecIdOpus) {
|
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_;
|
bool fresh = !acodec_;
|
||||||
|
|
|
||||||
|
|
@ -4474,13 +4474,27 @@ VOID TEST(KernelCodecTest, AudioFormat)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
srs_error_t err;
|
||||||
|
|
||||||
|
// Test edge cases with NULL/empty audio data
|
||||||
if (true) {
|
if (true) {
|
||||||
SrsFormat f;
|
SrsFormat f;
|
||||||
HELPER_EXPECT_SUCCESS(f.initialize());
|
HELPER_EXPECT_SUCCESS(f.initialize());
|
||||||
|
|
||||||
|
// NULL data should return success (early return)
|
||||||
HELPER_EXPECT_SUCCESS(f.on_audio(0, NULL, 0));
|
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", 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
|
// 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)
|
VOID TEST(KernelCodecTest, VideoFormatSepcial)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
srs_error_t err;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user