SRS5: MP3: Convert RTMP(MP3) to WebRTC(OPUS). v5.0.118 (#296) (#3340)

PICK 37867533cd
pull/3348/head
winlin 2 years ago
parent f82f265ece
commit 6875876349

@ -695,15 +695,16 @@ fi
# ffmpeg-fit, for WebRTC to transcode AAC with Opus.
#####################################################################################
if [[ $SRS_FFMPEG_FIT == YES ]]; then
FFMPEG_OPTIONS=""
if [[ $SRS_CROSS_BUILD == YES ]]; then
FFMPEG_CONFIGURE=./configure
FFMPEG_CONFIGURE="./configure"
else
FFMPEG_CONFIGURE="env PKG_CONFIG_PATH=${SRS_DEPENDS_LIBS}/opus/lib/pkgconfig ./configure"
fi
# Disable all features, note that there are still some options need to be disabled.
FFMPEG_OPTIONS="--disable-everything"
# Disable all asm for FFmpeg, to compatible with ARM CPU.
FFMPEG_OPTIONS="--disable-asm --disable-x86asm --disable-inline-asm"
FFMPEG_OPTIONS="$FFMPEG_OPTIONS --disable-asm --disable-x86asm --disable-inline-asm"
# Only build static libraries if no shared FFmpeg.
if [[ $SRS_SHARED_FFMPEG == YES ]]; then
FFMPEG_OPTIONS="$FFMPEG_OPTIONS --enable-shared"
@ -725,6 +726,17 @@ if [[ $SRS_FFMPEG_FIT == YES ]]; then
else
FFMPEG_OPTIONS="$FFMPEG_OPTIONS --enable-decoder=libopus --enable-encoder=libopus --enable-libopus"
fi
# Disable features of ffmpeg.
FFMPEG_OPTIONS="$FFMPEG_OPTIONS --disable-avdevice --disable-avformat --disable-swscale --disable-postproc --disable-avfilter --disable-network"
FFMPEG_OPTIONS="$FFMPEG_OPTIONS --disable-dwt --disable-error-resilience --disable-lsp --disable-lzo --disable-faan --disable-pixelutils"
FFMPEG_OPTIONS="$FFMPEG_OPTIONS --disable-hwaccels --disable-devices --disable-audiotoolbox --disable-videotoolbox --disable-cuvid"
FFMPEG_OPTIONS="$FFMPEG_OPTIONS --disable-d3d11va --disable-dxva2 --disable-ffnvcodec --disable-nvdec --disable-nvenc --disable-v4l2-m2m --disable-vaapi"
FFMPEG_OPTIONS="$FFMPEG_OPTIONS --disable-vdpau --disable-appkit --disable-coreimage --disable-avfoundation --disable-securetransport --disable-iconv"
FFMPEG_OPTIONS="$FFMPEG_OPTIONS --disable-lzma --disable-sdl2"
# Enable FFmpeg native AAC encoder and decoder.
FFMPEG_OPTIONS="$FFMPEG_OPTIONS --enable-decoder=aac --enable-decoder=aac_fixed --enable-decoder=aac_latm --enable-encoder=aac"
# Enable FFmpeg native MP3 decoder, which depends on dct.
FFMPEG_OPTIONS="$FFMPEG_OPTIONS --enable-decoder=mp3 --enable-dct"
if [[ -f ${SRS_OBJS}/${SRS_PLATFORM}/3rdpatry/ffmpeg/lib/libavcodec.a ]]; then
rm -rf ${SRS_OBJS}/ffmpeg && cp -rf ${SRS_OBJS}/${SRS_PLATFORM}/3rdpatry/ffmpeg ${SRS_OBJS}/ &&
@ -736,18 +748,9 @@ if [[ $SRS_FFMPEG_FIT == YES ]]; then
cp -rf ${SRS_WORKDIR}/3rdparty/ffmpeg-4-fit ${SRS_OBJS}/${SRS_PLATFORM}/ &&
(
cd ${SRS_OBJS}/${SRS_PLATFORM}/ffmpeg-4-fit &&
$FFMPEG_CONFIGURE \
--prefix=${SRS_DEPENDS_LIBS}/${SRS_PLATFORM}/3rdpatry/ffmpeg --pkg-config=pkg-config \
--pkg-config-flags="--static" --extra-libs="-lpthread" --extra-libs="-lm" \
--disable-everything ${FFMPEG_OPTIONS} \
--disable-programs --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages \
--disable-avdevice --disable-avformat --disable-swscale --disable-postproc --disable-avfilter --disable-network \
--disable-dct --disable-dwt --disable-error-resilience --disable-lsp --disable-lzo --disable-faan --disable-pixelutils \
--disable-hwaccels --disable-devices --disable-audiotoolbox --disable-videotoolbox --disable-cuvid \
--disable-d3d11va --disable-dxva2 --disable-ffnvcodec --disable-nvdec --disable-nvenc --disable-v4l2-m2m --disable-vaapi \
--disable-vdpau --disable-appkit --disable-coreimage --disable-avfoundation --disable-securetransport --disable-iconv \
--disable-lzma --disable-sdl2 --enable-decoder=aac --enable-decoder=aac_fixed --enable-decoder=aac_latm \
--enable-encoder=aac
$FFMPEG_CONFIGURE --prefix=${SRS_DEPENDS_LIBS}/${SRS_PLATFORM}/3rdpatry/ffmpeg \
--pkg-config=pkg-config --pkg-config-flags='--static' --extra-libs='-lpthread' --extra-libs='-lm' \
${FFMPEG_OPTIONS}
) &&
# See https://www.laoyuyu.me/2019/05/23/android/clang_compile_ffmpeg/
if [[ $SRS_CROSS_BUILD == YES ]]; then

@ -0,0 +1,32 @@
listen 1935;
max_connections 1000;
daemon off;
srs_log_tank console;
http_server {
enabled on;
listen 8080;
dir ./objs/nginx/html;
}
rtc_server {
enabled on;
listen 8000; # UDP port
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#config-candidate
candidate $CANDIDATE;
}
vhost __defaultVhost__ {
http_remux {
enabled on;
mount [vhost]/[app]/[stream].flv;
}
hls {
enabled on;
hls_acodec mp3;
}
rtc {
enabled on;
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtmp-to-rtc
rtmp_to_rtc on;
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtc-to-rtmp
rtc_to_rtmp on;
}
}

@ -21,6 +21,7 @@ The changelog for SRS.
## SRS 5.0 Changelog
* v5.0, 2022-12-26, For [#296](https://github.com/ossrs/srs/issues/296): MP3: Convert RTMP(MP3) to WebRTC(OPUS). v5.0.118
* v5.0, 2022-12-25, For [#296](https://github.com/ossrs/srs/issues/296): MP3: Support dump stream information. v5.0.117
* v5.0, 2022-12-25, For [#296](https://github.com/ossrs/srs/issues/296): MP3: Support mp3 for RTMP/HLS/HTTP-FLV/HTTP-TS/HLS etc. v5.0.116
* v5.0, 2022-12-24, Fix [#3328](https://github.com/ossrs/srs/issues/3328): Docker: Avoiding duplicated copy files. v5.0.115

@ -14,6 +14,8 @@ static const AVCodec* srs_find_decoder_by_id(SrsAudioCodecId id)
{
if (id == SrsAudioCodecIdAAC) {
return avcodec_find_decoder_by_name("aac");
} else if (id == SrsAudioCodecIdMP3) {
return avcodec_find_decoder_by_name("mp3");
} else if (id == SrsAudioCodecIdOpus) {
const AVCodec* codec = avcodec_find_decoder_by_name("libopus");
if (!codec) {

@ -717,6 +717,7 @@ SrsRtcFromRtmpBridge::SrsRtcFromRtmpBridge(SrsRtcSource* source)
source_ = source;
format = new SrsRtmpFormat();
codec_ = new SrsAudioTranscoder();
latest_codec_ = SrsAudioCodecIdForbidden;
rtmp_to_rtc = false;
keep_bframe = false;
merge_nalus = false;
@ -766,12 +767,6 @@ srs_error_t SrsRtcFromRtmpBridge::initialize(SrsRequest* r)
// Setup the SPS/PPS parsing strategy.
format->try_annexb_first = _srs_config->try_annexb_first(r->vhost);
int bitrate = 48000; // The output bitrate in bps.
if ((err = codec_->initialize(SrsAudioCodecIdAAC, SrsAudioCodecIdOpus, kAudioChannel, kAudioSamplerate,
bitrate)) != srs_success) {
return srs_error_wrap(err, "init codec");
}
}
keep_bframe = _srs_config->get_rtc_keep_bframe(req->vhost);
@ -831,6 +826,11 @@ srs_error_t SrsRtcFromRtmpBridge::on_audio(SrsSharedPtrMessage* msg)
return srs_error_wrap(err, "format consume audio");
}
// Try to init codec when startup or codec changed.
if (format->acodec && (err = init_codec(format->acodec->id)) != srs_success) {
return srs_error_wrap(err, "init codec");
}
// Ignore if no format->acodec, it means the codec is not parsed, or unknown codec.
// @issue https://github.com/ossrs/srs/issues/1506#issuecomment-562079474
if (!format->acodec) {
@ -843,14 +843,18 @@ srs_error_t SrsRtcFromRtmpBridge::on_audio(SrsSharedPtrMessage* msg)
return err;
}
// ignore sequence header
srs_assert(format->audio);
if (format->acodec->id == SrsAudioCodecIdMP3) {
return transcode(format->audio);
}
// When drop aac audio packet, never transcode.
if (acodec != SrsAudioCodecIdAAC) {
return err;
}
// ignore sequence header
srs_assert(format->audio);
char* adts_audio = NULL;
int nn_adts_audio = 0;
// TODO: FIXME: Reserve 7 bytes header when create shared message.
@ -875,6 +879,35 @@ srs_error_t SrsRtcFromRtmpBridge::on_audio(SrsSharedPtrMessage* msg)
return err;
}
srs_error_t SrsRtcFromRtmpBridge::init_codec(SrsAudioCodecId codec)
{
srs_error_t err = srs_success;
// Ignore if not changed.
if (latest_codec_ == codec) return err;
// Create a new codec.
srs_freep(codec_);
codec_ = new SrsAudioTranscoder();
// Initialize the codec according to the codec in stream.
int bitrate = 48000; // The output bitrate in bps.
if ((err = codec_->initialize(codec, SrsAudioCodecIdOpus, kAudioChannel, kAudioSamplerate, bitrate)) != srs_success) {
return srs_error_wrap(err, "init codec=%d", codec);
}
// Update the latest codec in stream.
if (latest_codec_ == SrsAudioCodecIdForbidden) {
srs_trace("RTMP2RTC: Init audio codec to %d(%s)", codec, srs_audio_codec_id2str(codec).c_str());
} else {
srs_trace("RTMP2RTC: Switch audio codec %d(%s) to %d(%s)", latest_codec_, srs_audio_codec_id2str(latest_codec_).c_str(),
codec, srs_audio_codec_id2str(codec).c_str());
}
latest_codec_ = codec;
return err;
}
srs_error_t SrsRtcFromRtmpBridge::transcode(SrsAudioFrame* audio)
{
srs_error_t err = srs_success;

@ -254,6 +254,7 @@ private:
SrsMetaCache* meta;
private:
bool rtmp_to_rtc;
SrsAudioCodecId latest_codec_;
SrsAudioTranscoder* codec_;
bool keep_bframe;
bool merge_nalus;
@ -272,6 +273,7 @@ public:
virtual void on_unpublish();
virtual srs_error_t on_audio(SrsSharedPtrMessage* msg);
private:
srs_error_t init_codec(SrsAudioCodecId codec);
srs_error_t transcode(SrsAudioFrame* audio);
srs_error_t package_opus(SrsAudioFrame* audio, SrsRtpPacket* pkt);
public:

@ -9,6 +9,6 @@
#define VERSION_MAJOR 5
#define VERSION_MINOR 0
#define VERSION_REVISION 117
#define VERSION_REVISION 118
#endif

Loading…
Cancel
Save