static ngx_int_t ngx_rtmp_live_pause(ngx_rtmp_session_t *s, ngx_rtmp_pause_t *v) { ngx_rtmp_live_ctx_t *ctx; ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_live_module); if (ctx == NULL || ctx->stream == NULL || ctx->hls) { goto next; } ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "live: pause=%i timestamp=%f", (ngx_int_t) v->pause, v->position); if (v->pause) { if (ngx_rtmp_send_status(s, "NetStream.Pause.Notify", "status", "Paused live") != NGX_OK) { return NGX_ERROR; } ctx->paused = 1; ngx_rtmp_live_stop(s); } else { if (ngx_rtmp_send_status(s, "NetStream.Unpause.Notify", "status", "Unpaused live") != NGX_OK) { return NGX_ERROR; } ctx->paused = 0; ngx_rtmp_live_start(s); } next: return next_pause(s, v); }
static ngx_int_t ngx_rtmp_flv_start(ngx_rtmp_session_t *s, ngx_file_t *f) { ngx_rtmp_flv_ctx_t *ctx; ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_flv_module); if (ctx == NULL) { return NGX_OK; } ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "flv: start"); ctx->offset = -1; ctx->msg_mask = 0; return NGX_OK; }
static ngx_int_t ngx_rtmp_live_stream_eof(ngx_rtmp_session_t *s, ngx_rtmp_stream_eof_t *v) { ngx_rtmp_live_ctx_t *ctx; ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_live_module); if (ctx == NULL || ctx->stream == NULL || !ctx->publishing || ctx->hls) { goto next; } ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "live: stream_eof"); ngx_rtmp_live_stop(s); next: return next_stream_eof(s, v); }
static ngx_int_t ngx_rtmp_codec_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, ngx_chain_t *in) { ngx_rtmp_core_srv_conf_t *cscf; ngx_rtmp_codec_ctx_t *ctx; ngx_chain_t **header; uint8_t fmt; ngx_uint_t idx; u_char *p; static ngx_uint_t sample_rates[] = { 5512, 11025, 22050, 44100 }; static ngx_uint_t aac_sample_rates[] = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350, 0, 0, 0 }; if (h->type != NGX_RTMP_MSG_AUDIO && h->type != NGX_RTMP_MSG_VIDEO) { return NGX_OK; } ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module); if (ctx == NULL) { ctx = ngx_pcalloc(s->connection->pool, sizeof(ngx_rtmp_codec_ctx_t)); ngx_rtmp_set_ctx(s, ctx, ngx_rtmp_codec_module); } /* save codec */ if (in->buf->last - in->buf->pos < 1) { return NGX_OK; } fmt = in->buf->pos[0]; if (h->type == NGX_RTMP_MSG_AUDIO) { ctx->audio_codec_id = (fmt & 0xf0) >> 4; ctx->audio_channels = (fmt & 0x01) + 1; ctx->sample_size = (fmt & 0x02) ? 2 : 1; if (ctx->aac_sample_rate == 0) { ctx->sample_rate = sample_rates[(fmt & 0x0c) >> 2]; }
static ngx_int_t ngx_rtmp_play_do_init(ngx_rtmp_session_t *s) { ngx_rtmp_play_ctx_t *ctx; ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_play_module); if (ctx == NULL) { return NGX_ERROR; } if (ctx->fmt && ctx->fmt->init && ctx->fmt->init(s, &ctx->file) != NGX_OK) { return NGX_ERROR; } return NGX_OK; }
static char * ngx_rtmp_exec_prepare_arg(ngx_rtmp_session_t *s, ngx_str_t *arg) { ngx_rtmp_core_app_conf_t *cacf; ngx_rtmp_exec_ctx_t *ctx; u_char *p, *pp; ngx_str_t result; cacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_core_module); ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_exec_module); /* substitute $app/${app} & $name/${name} */ ngx_str_set(&result, ""); pp = arg->data; for ( ;; ) { p = (u_char *)ngx_strchr(pp, '$'); ngx_rtmp_exec_append(&result, pp, p ? p - pp : 0); if (p == NULL) { return (char *)result.data; } pp = p + 1; if (p != arg->data && p[-1] == '\\') { goto dollar; } if (!ngx_strncmp(p + 1, "app", sizeof("app") - 1) || !ngx_strncmp(p + 1, "{app}", sizeof("{app}") - 1)) { ngx_rtmp_exec_append(&result, cacf->name.data, cacf->name.len); pp += (p[1] == '{' ? sizeof("{app}") - 1 : sizeof("app") - 1); continue; } if (!ngx_strncmp(p + 1, "name", sizeof("name") - 1) || !ngx_strncmp(p + 1, "{name}", sizeof("{name}") - 1)) { ngx_rtmp_exec_append(&result, ctx->name, 0); pp += (p[1] == '{' ? sizeof("{name}") - 1 : sizeof("name") - 1); continue; } dollar: ngx_rtmp_exec_append(&result, (u_char *)"$", 1); } }
static ngx_int_t ngx_rtmp_relay_play(ngx_rtmp_session_t *s, ngx_rtmp_play_t *v) { ngx_rtmp_relay_app_conf_t *racf; ngx_rtmp_relay_target_t *target; ngx_str_t name; size_t n; ngx_rtmp_relay_ctx_t *ctx; ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_relay_module); if (ctx && ctx->relay) { goto next; } racf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_relay_module); if (racf == NULL || racf->pulls.nelts == 0) { goto next; } name.len = ngx_strlen(v->name); name.data = v->name; target = racf->pulls.elts; for (n = 0; n < racf->pulls.nelts; ++n, ++target) { if (target->name.len == 0 || (name.len == target->name.len && !ngx_memcmp(name.data, target->name.data, name.len))) { if (ngx_rtmp_relay_pull(s, &name, target) != NGX_OK) { ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, "relay: pull failed name='%V' app='%V' " "playpath='%V' url='%V'", &name, &target->app, &target->play_path, &target->url.url); } break; } } next: return next_play(s, v); }
static ngx_rtmp_log_ctx_t * ngx_rtmp_log_set_names(ngx_rtmp_session_t *s, u_char *name, u_char *args) { ngx_rtmp_log_ctx_t *ctx; ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_log_module); if (ctx == NULL) { ctx = ngx_pcalloc(s->connection->pool, sizeof(ngx_rtmp_log_ctx_t)); if (ctx == NULL) { return NULL; } ngx_rtmp_set_ctx(s, ctx, ngx_rtmp_log_module); } ngx_memcpy(ctx->name, name, NGX_RTMP_MAX_NAME); ngx_memcpy(ctx->args, args, NGX_RTMP_MAX_ARGS); return ctx; }
static ngx_int_t ngx_live_relay_inner_pull_close(ngx_rtmp_session_t *s) { ngx_live_relay_ctx_t *ctx; ctx = ngx_rtmp_get_module_ctx(s, ngx_live_relay_module); if (ctx == NULL) { goto next; } if (ctx->tag != &ngx_live_relay_inner_module) { goto next; } // inner relay close s->live_stream->pslot = -1; next: return next_pull_close(s); }
static void ngx_rtmp_play_cleanup_local_file(ngx_rtmp_session_t *s) { ngx_rtmp_play_ctx_t *ctx; u_char *path; ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_play_module); if (ctx == NULL || ctx->file_id == 0) { return; } path = ngx_rtmp_play_get_local_file_path(s); ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "play: deleting local file '%s'", path); ctx->file_id = 0; ngx_delete_file(path); }
static ngx_rtmp_record_rec_ctx_t * ngx_rtmp_record_get_node_ctx(ngx_rtmp_session_t *s, ngx_uint_t n) { ngx_rtmp_record_ctx_t *ctx; ngx_rtmp_record_rec_ctx_t *rctx; if (ngx_rtmp_record_init(s) != NGX_OK) { return NULL; } ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_record_module); if (n >= ctx->rec.nelts) { return NULL; } rctx = ctx->rec.elts; return &rctx[n]; }
static ngx_rtmp_record_node_ctx_t * ngx_rtmp_record_get_node_ctx(ngx_rtmp_session_t *s, ngx_uint_t n) { ngx_rtmp_record_ctx_t *ctx; ngx_rtmp_record_node_ctx_t *nodes; if (ngx_rtmp_record_init(s) != NGX_OK) { return NULL; } ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_record_module); if (n >= ctx->nodes.nelts) { return NULL; } nodes = ctx->nodes.elts; return &nodes[n]; }
/* This funcion returns pointer to a static buffer */ static void ngx_rtmp_record_make_path(ngx_rtmp_session_t *s, ngx_rtmp_record_rec_ctx_t *rctx, ngx_str_t *path) { ngx_rtmp_record_ctx_t *ctx; ngx_rtmp_record_app_conf_t *rracf; u_char *p, *l; static u_char buf[NGX_TIME_T_LEN + 1]; static u_char pbuf[NGX_MAX_PATH + 1]; ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_record_module); rracf = rctx->conf; /* create file path */ p = pbuf; l = pbuf + sizeof(pbuf) - 1; p = ngx_cpymem(p, rracf->path.data, ngx_min(rracf->path.len, (size_t)(l - p - 1))); *p++ = '/'; p = (u_char *)ngx_escape_uri(p, ctx->name, ngx_min(ngx_strlen(ctx->name), (size_t)(l - p)), NGX_ESCAPE_URI_COMPONENT); /* append timestamp */ if (rracf->unique) { p = ngx_cpymem(p, buf, ngx_min(ngx_sprintf(buf, "-%T", rctx->timestamp) - buf, l - p)); } p = ngx_cpymem(p, rracf->suffix.data, ngx_min(rracf->suffix.len, (size_t)(l - p))); *p = 0; path->data = pbuf; path->len = p - pbuf; ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "record: %V path: '%V'", &rracf->id, path); }
static ngx_int_t ngx_rtmp_codec_disconnect(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, ngx_chain_t *in) { ngx_rtmp_codec_ctx_t *ctx; ngx_rtmp_core_srv_conf_t *cscf; ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module); if (ctx == NULL) { return NGX_OK; } cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module); if (ctx->avc_header) { ngx_rtmp_free_shared_chain(cscf, ctx->avc_header); ctx->avc_header = NULL; } if (ctx->aac_header) { ngx_rtmp_free_shared_chain(cscf, ctx->aac_header); ctx->aac_header = NULL; } if (ctx->avc_pheader) { ngx_rtmp_free_shared_chain(cscf, ctx->avc_pheader); ctx->avc_pheader = NULL; } if (ctx->aac_pheader) { ngx_rtmp_free_shared_chain(cscf, ctx->aac_pheader); ctx->aac_pheader = NULL; } if (ctx->meta) { ngx_rtmp_free_shared_chain(cscf, ctx->meta); ctx->meta = NULL; } return NGX_OK; }
static ngx_int_t ngx_rtmp_flv_seek(ngx_rtmp_session_t *s, ngx_file_t *f, ngx_uint_t timestamp) { ngx_rtmp_flv_ctx_t *ctx; ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_flv_module); if (ctx == NULL) { return NGX_OK; } ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "flv: seek timestamp=%ui", timestamp); ctx->start_timestamp = timestamp; ctx->epoch = ngx_current_msec; ctx->offset = -1; ctx->msg_mask = 0; return NGX_OK; }
static ngx_int_t ngx_rtmp_flv_init(ngx_rtmp_session_t *s, ngx_file_t *f) { ngx_rtmp_flv_ctx_t *ctx; ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_flv_module); if (ctx == NULL) { ctx = ngx_palloc(s->connection->pool, sizeof(ngx_rtmp_flv_ctx_t)); if (ctx == NULL) { return NGX_ERROR; } ngx_rtmp_set_ctx(s, ctx, ngx_rtmp_flv_module); } ngx_memzero(ctx, sizeof(*ctx)); return NGX_OK; }
/* This funcion returns pointer to a static buffer */ static u_char * ngx_rtmp_record_make_path(ngx_rtmp_session_t *s, ngx_rtmp_record_node_ctx_t *rctx) { ngx_rtmp_record_ctx_t *ctx; u_char *p, *l; ngx_rtmp_record_node_t *rc; static u_char buf[NGX_TIME_T_LEN + 1]; static u_char path[NGX_MAX_PATH + 1]; ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_record_module); rc = rctx->conf; /* create file path */ p = path; l = path + sizeof(path) - 1; p = ngx_cpymem(p, rc->path.data, ngx_min(rc->path.len, (size_t)(l - p - 1))); *p++ = '/'; p = (u_char *)ngx_escape_uri(p, ctx->name, ngx_min(ngx_strlen(ctx->name), (size_t)(l - p)), NGX_ESCAPE_URI_COMPONENT); /* append timestamp */ if (rc->unique) { p = ngx_cpymem(p, buf, ngx_min(ngx_sprintf(buf, "-%T", rctx->timestamp) - buf, l - p)); } p = ngx_cpymem(p, rc->suffix.data, ngx_min(rc->suffix.len, (size_t)(l - p))); *p = 0; ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "record: %V path: '%s'", &rc->id, path); return path; }
static ngx_int_t ngx_rtmp_notify_delete_stream(ngx_rtmp_session_t *s, ngx_rtmp_delete_stream_t *v) { ngx_rtmp_notify_ctx_t *ctx; ngx_rtmp_notify_app_conf_t *nacf; if (s->auto_pushed) { goto next; } ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_notify_module); if (ctx == NULL) { goto next; } nacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_notify_module); if (nacf == NULL) { goto next; } if (nacf->publish_done_url && (ctx->flags & NGX_RTMP_NOTIFY_PUBLISHING)) { ngx_rtmp_notify_done(s, "publish_done", nacf->publish_done_url); } if (nacf->play_done_url && (ctx->flags & NGX_RTMP_NOTIFY_PLAYING)) { ngx_rtmp_notify_done(s, "play_done", nacf->play_done_url); } if (nacf->done_url && ctx->flags) { ngx_rtmp_notify_done(s, "done", nacf->done_url); } ctx->flags = 0; next: return next_delete_stream(s, v); }
static ngx_int_t ngx_rtmp_exec_publish(ngx_rtmp_session_t *s, ngx_rtmp_publish_t *v) { ngx_rtmp_exec_app_conf_t *eacf; ngx_rtmp_exec_conf_t *ec; ngx_rtmp_exec_ctx_t *ctx; size_t n; eacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_exec_module); if (eacf == NULL || eacf->execs.nelts == 0) { goto next; } if (s->auto_pushed) { goto next; } ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_exec_module); if (ctx == NULL) { ctx = ngx_pcalloc(s->connection->pool, sizeof(ngx_rtmp_exec_ctx_t)); if (ctx == NULL) { return NGX_ERROR; } ngx_rtmp_set_ctx(s, ctx, ngx_rtmp_exec_module); ctx->execs = ngx_pcalloc(s->connection->pool, eacf->execs.nelts * sizeof(ngx_rtmp_exec_t)); } ngx_memcpy(ctx->name, v->name, NGX_RTMP_MAX_NAME); ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "exec: run %uz command(s)", eacf->execs.nelts); ec = eacf->execs.elts; for (n = 0; n < eacf->execs.nelts; ++n, ++ec) { ngx_rtmp_exec_run(s, n); } next: return next_publish(s, v); }
static void ngx_live_relay_inner_handler(ngx_event_t *ev) { ngx_rtmp_session_t *s; ngx_live_relay_app_conf_t *lracf; ngx_live_relay_ctx_t *ctx; ngx_live_relay_t relay; s = ev->data; ctx = ngx_rtmp_get_module_ctx(s, ngx_live_relay_module); if (!ctx->failed_delay && ev->timedout) { // connect timeout ngx_log_error(NGX_LOG_ERR, s->log, NGX_ETIMEDOUT, "inner relay, relay timeout"); s->finalize_reason = NGX_LIVE_RELAY_TIMEOUT; ngx_rtmp_finalize_session(s); return; } // relay pull, no player or relay push no publisher if ((s->publishing && s->live_stream->play_ctx == NULL) || (!s->publishing && s->live_stream->publish_ctx == NULL)) { return; } lracf = ngx_rtmp_get_module_app_conf(s, ngx_live_relay_module); ngx_add_timer(&ctx->reconnect, lracf->relay_reconnect); if (ngx_live_relay_inner_create_relay(s, &relay, s->live_stream->pslot) != NGX_OK) { return; } ngx_live_relay_create(s, &relay); }
static ngx_rtmp_gop_frame_t * ngx_rtmp_gop_cache_alloc_frame(ngx_rtmp_session_t *s) { ngx_rtmp_gop_cache_ctx_t *ctx; ngx_rtmp_gop_frame_t *frame; ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_gop_cache_module); if (ctx == NULL) { return NULL; } if (ctx->free_frame) { frame = ctx->free_frame; ctx->free_frame = frame->next; return frame; } frame = ngx_pcalloc(ctx->pool, sizeof(ngx_rtmp_gop_frame_t)); return frame; }
static ngx_int_t ngx_rtmp_record_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h, ngx_chain_t *in) { ngx_rtmp_record_ctx_t *ctx; ngx_rtmp_record_rec_ctx_t *rctx; ngx_uint_t n; ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_record_module); if (ctx == NULL) { return NGX_OK; } rctx = ctx->rec.elts; for (n = 0; n < ctx->rec.nelts; ++n, ++rctx) { ngx_rtmp_record_node_av(s, rctx, h, in); } return NGX_OK; }
static ngx_int_t ngx_rtmp_play_pause(ngx_rtmp_session_t *s, ngx_rtmp_pause_t *v) { ngx_rtmp_play_ctx_t *ctx; ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_play_module); if (ctx == NULL || ctx->file.fd == NGX_INVALID_FILE) { goto next; } ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "play: pause=%i timestamp=%f", (ngx_int_t) v->pause, v->position); if (v->pause) { if (ngx_rtmp_send_status(s, "NetStream.Pause.Notify", "status", "Paused video on demand") != NGX_OK) { return NGX_ERROR; } ngx_rtmp_play_do_stop(s); } else { if (ngx_rtmp_send_status(s, "NetStream.Unpause.Notify", "status", "Unpaused video on demand") != NGX_OK) { return NGX_ERROR; } ngx_rtmp_play_do_start(s); /*TODO: v->position? */ } next: return next_pause(s, v); }
static ngx_int_t ngx_rtmp_dash_close_stream(ngx_rtmp_session_t *s, ngx_rtmp_close_stream_t *v) { ngx_rtmp_dash_ctx_t *ctx; ngx_rtmp_dash_app_conf_t *dacf; dacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_dash_module); ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_dash_module); if (dacf == NULL || !dacf->dash || ctx == NULL) { goto next; } ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "dash: delete stream"); ngx_rtmp_dash_close_fragments(s); next: return next_close_stream(s, v); }
static ngx_int_t ngx_rtmp_dash_open_fragments(ngx_rtmp_session_t *s) { ngx_rtmp_dash_ctx_t *ctx; ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "dash: open fragments"); ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_dash_module); if (ctx->opened) { return NGX_OK; } ngx_rtmp_dash_open_fragment(s, &ctx->video, ctx->id, 'v'); ngx_rtmp_dash_open_fragment(s, &ctx->audio, ctx->id, 'a'); ctx->opened = 1; return NGX_OK; }
static void ngx_rtmp_netcall_close(ngx_connection_t *cc) { ngx_rtmp_netcall_session_t *cs, **css; ngx_pool_t *pool; ngx_rtmp_session_t *s; ngx_rtmp_netcall_ctx_t *ctx; cs = cc->data; if (cc->destroyed) { return; } cc->destroyed = 1; if (!cs->detached) { s = cs->session; ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_netcall_module); for(css = &ctx->cs; *css; css = &((*css)->next)) { if (*css == cs) { *css = cs->next; break; } } if (cs->handle && cs->handle(s, cs->arg, cs->in) != NGX_OK) { ngx_rtmp_finalize_session(s); } } pool = cc->pool; ngx_close_connection(cc); ngx_destroy_pool(pool); }
static void ngx_rtmp_play_copy_local_file(ngx_rtmp_session_t *s, u_char *name) { ngx_rtmp_play_app_conf_t *pacf; ngx_rtmp_play_ctx_t *ctx; u_char *path, *p; static u_char dpath[NGX_MAX_PATH + 1]; pacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_play_module); if (pacf == NULL) { return; } ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_play_module); if (ctx == NULL || ctx->file_id == 0) { return; } path = ngx_rtmp_play_get_local_file_path(s); p = ngx_snprintf(dpath, NGX_MAX_PATH, "%V/%s%V", &pacf->local_path, name + ctx->pfx_size, &ctx->sfx); *p = 0; ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "play: copy local file '%s' to '%s'", path, dpath); if (ngx_rename_file(path, dpath) == 0) { ctx->file_id = 0; return; } ngx_log_error(NGX_LOG_ERR, s->connection->log, ngx_errno, "play: error copying local file '%s' to '%s'", path, dpath); ngx_rtmp_play_cleanup_local_file(s); }
static ngx_int_t ngx_rtmp_record_open(ngx_rtmp_session_t *s) { ngx_rtmp_record_ctx_t *ctx; ngx_err_t err; u_char *path; ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_record_module); if (ctx == NULL || ctx->file.fd != NGX_INVALID_FILE) { return NGX_ERROR; } ctx->timestamp = ngx_cached_time->sec; path = ngx_rtmp_record_make_path(s); ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "record: path '%s'", path); /* open file */ ctx->nframes = 0; ngx_memzero(&ctx->file, sizeof(ctx->file)); ctx->file.offset = 0; ctx->file.log = s->connection->log; ctx->file.fd = ngx_open_file(path, NGX_FILE_WRONLY, NGX_FILE_TRUNCATE, NGX_FILE_DEFAULT_ACCESS); ctx->last = *ngx_cached_time; if (ctx->file.fd == NGX_INVALID_FILE) { err = ngx_errno; if (err != NGX_ENOENT) { ngx_log_error(NGX_LOG_CRIT, s->connection->log, err, "record: failed to open file '%s'", path); } return NGX_OK; } ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "record: opened '%s'", path); return NGX_OK; }
static ngx_int_t ngx_rtmp_play_pause(ngx_rtmp_session_t *s, ngx_rtmp_pause_t *v) { ngx_rtmp_play_ctx_t *ctx; ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_play_module); if (ctx == NULL || ctx->file.fd == NGX_INVALID_FILE) { goto next; } ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "play: pause=%i timestamp=%i", (ngx_int_t) v->pause, (ngx_int_t) v->position); if (v->pause) { ngx_rtmp_play_stop(s); } else { ngx_rtmp_play_start(s, v->position); } next: return next_pause(s, v); }
static u_char * ngx_rtmp_log_var_command_getdata(ngx_rtmp_session_t *s, u_char *buf, ngx_rtmp_log_op_t *op) { ngx_rtmp_log_ctx_t *ctx; ngx_str_t *cmd; ngx_uint_t n; static ngx_str_t commands[] = { ngx_string("NONE"), ngx_string("PLAY"), ngx_string("PUBLISH"), ngx_string("PLAY+PUBLISH") }; ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_log_module); n = ctx ? (ctx->play + ctx->publish * 2) : 0; cmd = &commands[n]; return ngx_cpymem(buf, cmd->data, cmd->len); }