mirror of
https://github.com/zotanmew/nginx-rtmp-module.git
synced 2024-05-18 17:21:08 +02:00
implemented record append feature
This commit is contained in:
parent
349259329d
commit
0b6a84b0b8
|
@ -432,6 +432,9 @@ ngx_rtmp_record_node_open(ngx_rtmp_session_t *s,
|
|||
ngx_err_t err;
|
||||
ngx_str_t path;
|
||||
ngx_int_t mode, create_mode;
|
||||
u_char buf[8], *p;
|
||||
off_t file_size;
|
||||
uint32_t tag_size, mlen, timestamp;
|
||||
|
||||
rracf = rctx->conf;
|
||||
|
||||
|
@ -449,7 +452,7 @@ ngx_rtmp_record_node_open(ngx_rtmp_session_t *s,
|
|||
|
||||
ngx_rtmp_record_make_path(s, rctx, &path);
|
||||
|
||||
mode = rracf->append ? NGX_FILE_APPEND : NGX_FILE_WRONLY;
|
||||
mode = rracf->append ? NGX_FILE_RDWR : NGX_FILE_WRONLY;
|
||||
create_mode = rracf->append ? NGX_FILE_CREATE_OR_OPEN : NGX_FILE_TRUNCATE;
|
||||
|
||||
ngx_memzero(&rctx->file, sizeof(rctx->file));
|
||||
|
@ -457,6 +460,7 @@ ngx_rtmp_record_node_open(ngx_rtmp_session_t *s,
|
|||
rctx->file.log = s->connection->log;
|
||||
rctx->file.fd = ngx_open_file(path.data, mode, create_mode,
|
||||
NGX_FILE_DEFAULT_ACCESS);
|
||||
ngx_str_set(&rctx->file.name, "recorded");
|
||||
|
||||
if (rctx->file.fd == NGX_INVALID_FILE) {
|
||||
err = ngx_errno;
|
||||
|
@ -489,17 +493,71 @@ ngx_rtmp_record_node_open(ngx_rtmp_session_t *s,
|
|||
}
|
||||
|
||||
if (rracf->append) {
|
||||
/* need non-zero offset to skip header */
|
||||
rctx->file.offset = lseek(rctx->file.fd, 0, SEEK_END);
|
||||
if (rctx->file.offset == (off_t) -1) {
|
||||
|
||||
file_size = 0;
|
||||
timestamp = 0;
|
||||
|
||||
file_size = lseek(rctx->file.fd, 0, SEEK_END);
|
||||
if (file_size == (off_t) -1) {
|
||||
ngx_log_error(NGX_LOG_CRIT, s->connection->log, ngx_errno,
|
||||
"record: %V seek failed", &rracf->id);
|
||||
lseek(rctx->file.fd, 0, SEEK_SET);
|
||||
rctx->file.offset = 0;
|
||||
} else {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||
"record: append offset=%O", rctx->file.offset);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (file_size < 4) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (ngx_read_file(&rctx->file, buf, 4, file_size - 4) != 4) {
|
||||
ngx_log_error(NGX_LOG_CRIT, s->connection->log, ngx_errno,
|
||||
"record: %V tag size read failed", &rracf->id);
|
||||
goto done;
|
||||
}
|
||||
|
||||
p = (u_char *) &tag_size;
|
||||
p[0] = buf[3];
|
||||
p[1] = buf[2];
|
||||
p[2] = buf[1];
|
||||
p[3] = buf[0];
|
||||
|
||||
if (tag_size == 0 || tag_size + 4 > file_size) {
|
||||
file_size = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (ngx_read_file(&rctx->file, buf, 8, file_size - tag_size - 4) != 8)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_CRIT, s->connection->log, ngx_errno,
|
||||
"record: %V tag read failed", &rracf->id);
|
||||
goto done;
|
||||
}
|
||||
|
||||
p = (u_char *) &mlen;
|
||||
p[0] = buf[3];
|
||||
p[1] = buf[2];
|
||||
p[2] = buf[1];
|
||||
p[3] = 0;
|
||||
|
||||
if (tag_size != mlen + 11) {
|
||||
ngx_log_error(NGX_LOG_CRIT, s->connection->log, ngx_errno,
|
||||
"record: %V tag size mismatch: "
|
||||
"tag_size=%uD, mlen=%uD", &rracf->id, tag_size, mlen);
|
||||
goto done;
|
||||
}
|
||||
|
||||
p = (u_char *) ×tamp;
|
||||
p[3] = buf[7];
|
||||
p[0] = buf[6];
|
||||
p[1] = buf[5];
|
||||
p[2] = buf[4];
|
||||
|
||||
done:
|
||||
rctx->file.offset = file_size;
|
||||
rctx->time_shift = timestamp;
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||
"record: append offset=%O, time=%uD, tag_size=%uD",
|
||||
file_size, timestamp, tag_size);
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
|
@ -975,29 +1033,17 @@ ngx_rtmp_record_node_av(ngx_rtmp_session_t *s, ngx_rtmp_record_rec_ctx_t *rctx,
|
|||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (rctx->file.offset == 0) {
|
||||
if (!rracf->append) {
|
||||
rctx->epoch = h->timestamp;
|
||||
}
|
||||
if (!rctx->initialized) {
|
||||
|
||||
if (ngx_rtmp_record_write_header(&rctx->file) != NGX_OK) {
|
||||
rctx->initialized = 1;
|
||||
rctx->epoch = h->timestamp + rctx->time_shift;
|
||||
|
||||
if (rctx->file.offset == 0 &&
|
||||
ngx_rtmp_record_write_header(&rctx->file) != NGX_OK)
|
||||
{
|
||||
ngx_rtmp_record_node_close(s, rctx);
|
||||
return NGX_OK;
|
||||
}
|
||||
#if 0
|
||||
/* metadata */
|
||||
if (codec_ctx->meta) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||
"record: writing metadata");
|
||||
ch.type = NGX_RTMP_MSG_AMF_META;
|
||||
ch.mlen = ngx_rtmp_record_get_chain_mlen(codec_ctx->meta);
|
||||
if (ngx_rtmp_record_write_frame(s, &ch, codec_ctx->meta)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
codec_ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module);
|
||||
|
|
|
@ -40,10 +40,11 @@ typedef struct {
|
|||
ngx_rtmp_record_app_conf_t *conf;
|
||||
ngx_file_t file;
|
||||
ngx_uint_t nframes;
|
||||
uint32_t epoch;
|
||||
uint32_t epoch, time_shift;
|
||||
ngx_time_t last;
|
||||
time_t timestamp;
|
||||
unsigned failed:1;
|
||||
unsigned initialized:1;
|
||||
unsigned aac_header_sent:1;
|
||||
unsigned avc_header_sent:1;
|
||||
unsigned video_key_sent:1;
|
||||
|
|
Loading…
Reference in a new issue