http streaming with nginx module
Pete1103
nginx-forum at forum.nginx.org
Tue Jan 29 05:37:59 UTC 2019
Hello all,
I tried to make a third-party module in nginx in order to support the ts
stream in shared_memory. However, in my nginx handler function, it will
output a FILE_SIZE ts steam in once. I want to enable "Transfer Encoding:
chunked" in this function, so it can continuously send data to a client over
a single HTTP connection that remains open indefinitely. Does the function "
ngx_http_output_filter(r, &out)" can achieve this goal? or I should use
another function to make it?
nginx version: 1.15.7
here is my nginx handler code:
static ngx_int_t ngx_http_ts_handler(ngx_http_request_t *r){
ngx_int_t rc;
ngx_buf_t *b;
ngx_chain_t out;
char uri[50] = {0};
static char ngx_ts_data[FILE_SIZE] = {0};
if (!(r->method & (NGX_HTTP_GET | NGX_HTTP_PUT ))) {
return NGX_HTTP_NOT_ALLOWED;
}
rc = ngx_http_discard_request_body(r);
if (rc != NGX_OK) return rc;
/* Set the Content-Type header. "text/html" */
r->headers_out.content_type.len = sizeof(TS_TYPE) - 1;
r->headers_out.content_type.data = (u_char *) TS_TYPE;
/* Allocate a new buffer for sending out the reply. */
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
/* Insertion in the buffer chain. */
out.buf = b;
out.next = NULL;
memcpy(&uri, r-> uri_start , r-> uri_end-(r-> uri_start));
/*make http header*/
if (!strncmp(uri, "/VideoInput/", 12)){
int shm_fd;
uint32_t *pos_hdr;
int pos;
int cur_loc;
char *fifo_start;
int remain = 0;
shm_fd = open_output_shm(SHM_NAME);
g_shm_ptr = (char *)mmap(NULL, SHM_SIZE, PROT_READ | PROT_WRITE,
MAP_SHARED, shm_fd, 0);
close(shm_fd);
pos_hdr = (uint32_t *)g_shm_ptr;
//chn = (int)(*pos_hdr & CHN_MASK);
pos = (int)(*pos_hdr & POS_MASK);
if (pos > (PACKET_SIZE * 100)) {
cur_loc = pos - (PACKET_SIZE * 100);
} else cur_loc = 0;
fifo_start = (char *)(pos_hdr + 1);
if (fifo_start[cur_loc] != 0x47) {
//json_object_set_new(jret, "TS", json_string("non-sync"));
memset(ngx_ts_data, 0, strlen(ngx_ts_data));
memcpy(ngx_ts_data,"TS non-sync", 11);
b->pos = (u_char *)ngx_ts_data;
b->last = (u_char *)ngx_ts_data + strlen(ngx_ts_data);
}else{
if( pos > FILE_SIZE ){
b->pos = (u_char *)(g_shm_ptr + 4);
b->last = (u_char *)(g_shm_ptr + 4) + FILE_SIZE;
}else{
remain = FILE_SIZE - pos;
memset(ngx_ts_data, 0, sizeof(ngx_ts_data)-1);
memcpy(ngx_ts_data, g_shm_ptr + (SHM_SIZE - remain),
remain);
memcpy(&ngx_ts_data[remain], g_shm_ptr + 4, pos);
b->pos = (u_char *)ngx_ts_data;
b->last = (u_char *)ngx_ts_data + sizeof(ngx_ts_data)-1;
}
}
}else{
//json_object_set_new(jret, "TS", json_string("Nothing"));
memset(ngx_ts_data, 0, strlen(ngx_ts_data));
memcpy(ngx_ts_data,"No",2);
b->pos = (u_char *)ngx_ts_data;
b->last = (u_char *)ngx_ts_data + strlen(ngx_ts_data);
}
b->memory = 1; /* content is in read-only memory */
/* there will be no more buffers in the request */
b->last_buf = 1;
/* Sending the headers for the reply. */
r->headers_out.status = NGX_HTTP_OK; /* 200 status code */
rc = ngx_http_send_header(r); /* Send the headers */
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
return rc;
}
/* Send the body, and return the status code of the output filter chain.
*/
return ngx_http_output_filter(r, &out);
}
Any help would be appreciated,
Pete
Posted at Nginx Forum: https://forum.nginx.org/read.php?2,282849,282849#msg-282849
More information about the nginx
mailing list