static const char * rtmp_init_subtitles(media_pipe_t *mp, struct play_video_subtitle_list *list) { play_video_subtitle_t *pvs; char track[20]; int i = 0, s; const char *lang, *ret = NULL; int best_subtitle_score = 0; mp_add_track_off(mp->mp_prop_subtitle_tracks, "off"); LIST_FOREACH(pvs, list, pvs_link) { i++; if(pvs->pvs_language) { s = i18n_subtitle_score(pvs->pvs_language); if(s > best_subtitle_score) { ret = pvs->pvs_url; best_subtitle_score = s; } lang = isolang_iso2lang(pvs->pvs_language); } else { snprintf(track, sizeof(track), "Track #%d", i); lang = track; } mp_add_track(mp->mp_prop_subtitle_tracks, lang, pvs->pvs_url); }
static JSBool js_addSubtitle(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { js_sub_job_t *jsj = JS_GetPrivate(cx, obj); const char *url; const char *title; const char *language = NULL; const char *format = NULL; const char *source = NULL; int score = 0; if(!JS_ConvertArguments(cx, argc, argv, "ss/sssu", &url, &title, &language, &format, &source, &score)) return JS_FALSE; sub_scanner_t *ss = jsj->jsj_ss; hts_mutex_lock(&ss->ss_mutex); mp_add_track(ss->ss_proproot, title, url, format, NULL, language, source, NULL, jsj->jsj_score + score, jsj->jsj_autosel); hts_mutex_unlock(&ss->ss_mutex); return JS_TRUE; }
static event_t * get_packet_a(rtmp_t *r, uint8_t *data, int size, int64_t dts, media_pipe_t *mp) { uint8_t flags; uint8_t type = 0; enum AVCodecID id; if(r->r->m_read.flags & RTMP_READ_SEEKING) return NULL; if(size < 2) return NULL; flags = *data++; size--; switch(flags & 0xf0) { case 0xa0: id = AV_CODEC_ID_AAC; type = *data++; size--; break; case 0x20: id = AV_CODEC_ID_MP3; break; default: return NULL; } if(r->acodec == NULL) { media_codec_params_t mcp = {0}; int parse = 0; const char *fmt; switch(id) { case AV_CODEC_ID_AAC: if(type != 0 || size < 0) return NULL; mcp.extradata = data; mcp.extradata_size = size; fmt = "AAC"; break; case AV_CODEC_ID_MP3: parse = 1; fmt = "MP3"; break; default: abort(); } mp_add_track(mp->mp_prop_audio_tracks, NULL, "rtmp:1", fmt, fmt, NULL, NULL, NULL, 0, 1); prop_set_string(mp->mp_prop_audio_track_current, "rtmp:1"); r->acodec = media_codec_create(id, parse, NULL, NULL, &mcp, mp); return NULL; } media_codec_t *mc = r->acodec; dts *= 1000; if(dts <= r->seekpos_audio) return NULL; r->seekpos_audio = dts; if(mc->parser_ctx == NULL) return sendpkt(r, &mp->mp_audio, mc, dts, dts, data, size, 0, MB_AUDIO, 0, 0); while(size > 0) { int outlen; uint8_t *outbuf; int rlen = av_parser_parse2(mc->parser_ctx, mc->fmt_ctx, &outbuf, &outlen, data, size, dts, dts, AV_NOPTS_VALUE); if(outlen) { event_t *e = sendpkt(r, &mp->mp_audio, mc, mc->parser_ctx->dts, mc->parser_ctx->pts, outbuf, outlen, 0, MB_AUDIO, 0, 0); if(e != NULL) return e; } dts = AV_NOPTS_VALUE; data += rlen; size -= rlen; } return NULL; }
static event_t * get_packet_a(rtmp_t *r, uint8_t *data, size_t size, int64_t dts, media_pipe_t *mp) { uint8_t flags; uint8_t type = 0; enum CodecID id; if(r->r->m_read.flags & RTMP_READ_SEEKING) return NULL; if(size < 2) return NULL; flags = *data++; size--; switch(flags & 0xf0) { case 0xa0: id = CODEC_ID_AAC; type = *data++; size--; break; case 0x20: id = CODEC_ID_MP3; break; default: return NULL; } if(r->acodec == NULL) { AVCodecContext *ctx; int parse = 0; const char *fmt; switch(id) { case CODEC_ID_AAC: if(type != 0 || size < 0) return NULL; ctx = avcodec_alloc_context3(NULL); ctx->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(ctx->extradata, data, size); ctx->extradata_size = size; fmt = "AAC"; break; case CODEC_ID_MP3: ctx = avcodec_alloc_context3(NULL); parse = 1; fmt = "MP3"; break; default: abort(); } mp_add_track(mp->mp_prop_audio_tracks, NULL, "rtmp:1", fmt, fmt, NULL, NULL, NULL, 0); prop_set_string(mp->mp_prop_audio_track_current, "rtmp:1"); r->acodec = media_codec_create(id, parse, NULL, ctx, NULL, mp); return NULL; } media_codec_t *mc = r->acodec; dts *= 1000; if(dts < r->seekpos) return NULL; if(mc->parser_ctx == NULL) return sendpkt(r, &mp->mp_audio, mc, dts, dts, dts, data, size, 0, MB_AUDIO, 0); while(size > 0) { int outlen; uint8_t *outbuf; int rlen = av_parser_parse2(mc->parser_ctx, mc->codec_ctx, &outbuf, &outlen, data, size, dts, dts, AV_NOPTS_VALUE); if(outlen) { event_t *e = sendpkt(r, &mp->mp_audio, mc, mc->parser_ctx->dts, mc->parser_ctx->pts, mc->parser_ctx->dts, outbuf, outlen, 0, MB_AUDIO, 0); if(e != NULL) return e; } dts = AV_NOPTS_VALUE; data += rlen; size -= rlen; } return NULL; }