Farzaneh Soltanzadeh 2 weeks ago
committed by GitHub
parent
commit
5265920423
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
4 changed files with 100 additions and 0 deletions
  1. +8
    -0
      daemon/call_interfaces.c
  2. +85
    -0
      daemon/media_player.c
  3. +2
    -0
      include/call_interfaces.h
  4. +5
    -0
      include/media_player.h

+ 8
- 0
daemon/call_interfaces.c View File

@ -1957,6 +1957,12 @@ void call_ng_main_flags(const ng_parser_t *parser, str *key, parser_arg value, h
case CSH_LOOKUP("file"):
out->file = s;
break;
case CSH_LOOKUP("audio-raw-rtp-file"):
out->audio_raw_rtp_file = s;
break;
case CSH_LOOKUP("audio-raw-rtp-codec"):
out->audio_raw_rtp_codec = s;
break;
case CSH_LOOKUP("frequency"):
case CSH_LOOKUP("frequencies"):
call_ng_flags_freqs(parser, value, out);
@ -3934,6 +3940,8 @@ const char *call_play_media_ng(ng_command_ctx_t *ctx) {
.codec_set = flags.codec_set,
.file = flags.file,
.blob = flags.blob,
.audio_raw_rtp_file = flags.audio_raw_rtp_file,
.audio_raw_rtp_codec = flags.audio_raw_rtp_codec,
.db_id = flags.db_id,
);


+ 85
- 0
daemon/media_player.c View File

@ -1479,6 +1479,87 @@ static mp_cached_code __media_player_add_file(struct media_player *mp,
return MPC_OK;
}
struct rtp_payload_data{
int pt; // RTP payload type
const char ffmpeg_codec_name[6]; // Codec name (case-sensitive)
enum AVMediaType codec_type;// Media type
enum AVCodecID codec_id; // FFmpeg codec ID
int sample_rate; // Sample rate
int channels; // Default channels
};
const struct rtp_payload_data rtp_payload_types[] = {
{0, "mulaw", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_PCM_MULAW, 8000, 1},
{8, "alaw", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_PCM_ALAW, 8000, 1},
{9, "g722", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_ADPCM_G722, 8000, 1},
{18, "g729", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_G729, 8000, 1},
{-1, "", AVMEDIA_TYPE_UNKNOWN, AV_CODEC_ID_NONE, -1, -1}
};
// Helper function to find codec configuration
static const struct rtp_payload_data *find_rtp_payload_data(const str *codec_str) {
// Check static payload types
for (int i = 0; rtp_payload_types[i].pt != -1; i++) {
if (str_cmp(codec_str, rtp_payload_types[i].ffmpeg_codec_name) == 0) {
return &rtp_payload_types[i];
}
}
ilog(LOG_ERR, "Unsupported codec: '" STR_FORMAT "'", STR_FMT(codec_str));
return NULL;
}
static bool __media_player_open_audio_raw_rtp_file(struct media_player *mp, media_player_opts_t opts) {
// Validate codec
if (!opts.audio_raw_rtp_codec.len) {
ilog(LOG_ERR, "Raw RTP playback requires codec specification");
return false;
}
// Find codec configuration
const struct rtp_payload_data *payload_data = find_rtp_payload_data(&opts.audio_raw_rtp_codec);
if (!payload_data || payload_data->codec_id == AV_CODEC_ID_NONE) {
ilog(LOG_ERR, "Codec '" STR_FORMAT "' is not supported by FFmpeg", STR_FMT(&opts.audio_raw_rtp_codec));
return false;
}
// Convert file path
char file_path[PATH_MAX];
snprintf(file_path, sizeof(file_path), STR_FORMAT, STR_FMT(&opts.audio_raw_rtp_file));
AVInputFormat *iformat = av_find_input_format(opts.audio_raw_rtp_codec.s);
if (!iformat) {
ilog(LOG_ERR, "Failed to find input format:'" STR_FORMAT "'", STR_FMT(&opts.audio_raw_rtp_codec));
return false;
}
int ret = avformat_open_input(&mp->coder.fmtctx, file_path, iformat , NULL);
if (ret < 0) {
ilog(LOG_ERR, "Raw RTP playback failing in avformat_open_input");
return false;
}
if (!mp->coder.fmtctx->streams || !mp->coder.fmtctx->streams[0]) {
ilog(LOG_ERR, "No streams found in input file");
return false;
}
mp->coder.fmtctx->streams[0]->time_base = (AVRational){1, payload_data->sample_rate > 0 ? payload_data->sample_rate : 8000}; // Default for 8kHz audio;
mp->coder.fmtctx->streams[0]->codecpar->sample_rate = payload_data->sample_rate;
return true;
}
static bool media_player_play_audio_raw_rtp_file(struct media_player *mp, media_player_opts_t opts) {
const rtp_payload_type *dst_pt = media_player_play_init(mp);
if (!dst_pt)
return false;
if (!__media_player_open_audio_raw_rtp_file(mp, opts))
return false;
mp->coder.audio_raw_rtp_mode = true;
return media_player_play_start(mp, dst_pt, opts.codec_set);
}
// call->master_lock held in W
static bool media_player_play_file(struct media_player *mp, media_player_opts_t opts) {
const rtp_payload_type *dst_pt = media_player_play_init(mp);
@ -1685,6 +1766,10 @@ const char * call_play_media_for_ml(struct call_monologue *ml,
if (!media_player_play_db(ml->player, opts))
return "Failed to start media playback from database";
}
else if (opts.audio_raw_rtp_file.len ) {
if (!media_player_play_audio_raw_rtp_file(ml->player, opts))
return "Failed to start audio raw RTP file playback";
}
else
return "No media file specified";
return NULL;


+ 2
- 0
include/call_interfaces.h View File

@ -165,6 +165,8 @@ struct sdp_ng_flags {
str moh_file;
str blob;
str moh_blob;
str audio_raw_rtp_file;
str audio_raw_rtp_codec;
long long db_id;
long long moh_db_id;
long long duration;


+ 5
- 0
include/media_player.h View File

@ -26,6 +26,10 @@ typedef struct {
unsigned int block_egress:1,
moh:1;
str file, blob;
str audio_raw_rtp_file; // Path to audio raw RTP file
str audio_raw_rtp_codec; // Codec for audio raw RTP (e.g., "PCMU")
long long db_id;
} media_player_opts_t;
@ -58,6 +62,7 @@ struct media_player_coder {
str blob;
str read_pos;
struct codec_handler *handler;
unsigned int audio_raw_rtp_mode;
};
struct media_player {


Loading…
Cancel
Save