winlin

for #319, refine the config structure.

@@ -268,81 +268,86 @@ vhost removed.srs.com { @@ -268,81 +268,86 @@ vhost removed.srs.com {
268 # @see scope.vhost.srs.com 268 # @see scope.vhost.srs.com
269 enabled off; 269 enabled off;
270 } 270 }
271 -# the vhost for antisuck.  
272 -vhost refer.anti_suck.com {  
273 - # refer hotlink-denial.  
274 - refer {  
275 - # whether enable the refer hotlink-denial.  
276 - # default: off.  
277 - enabled on;  
278 - # the common refer for play and publish.  
279 - # if the page url of client not in the refer, access denied.  
280 - # if not specified this field, allow all.  
281 - # default: not specified.  
282 - all github.com github.io;  
283 - # refer for publish clients specified.  
284 - # the common refer is not overrided by this.  
285 - # if not specified this field, allow all.  
286 - # default: not specified.  
287 - publish github.com github.io;  
288 - # refer for play clients specified.  
289 - # the common refer is not overrided by this.  
290 - # if not specified this field, allow all.  
291 - # default: not specified.  
292 - play github.com github.io; 271 +
  272 +# vhost for stream cluster for RTMP/FLV
  273 +vhost cluster.srs.com {
  274 + # stream RTMP/FLV cluster config.
  275 + cluster {
  276 + # the mode of vhost, local or remote.
  277 + # local: vhost is origin vhost, which provides stream source.
  278 + # remote: vhost is edge vhost, which pull/push to origin.
  279 + # default: local
  280 + mode remote;
  281 + # for edge(remote mode), user must specifies the origin server
  282 + # format as: <server_name|ip>[:port]
  283 + # @remark user can specifies multiple origin for error backup, by space,
  284 + # for example, 192.168.1.100:1935 192.168.1.101:1935 192.168.1.102:1935
  285 + origin 127.0.0.1:1935 localhost:1935;
  286 +
  287 + # for edge, whether open the token traverse mode,
  288 + # if token traverse on, all connections of edge will forward to origin to check(auth),
  289 + # it's very important for the edge to do the token auth.
  290 + # the better way is use http callback to do the token auth by the edge,
  291 + # but if user prefer origin check(auth), the token_traverse if better solution.
  292 + # default: off
  293 + token_traverse off;
  294 +
  295 + # the vhost to transform for edge,
  296 + # to fetch from the specified vhost at origin,
  297 + # if not specified, use the current vhost of edge in origin, the variable [vhost].
  298 + # default: [vhost]
  299 + vhost same.edge.srs.com;
  300 +
  301 + # when upnode(forward to, edge push to, edge pull from) is srs,
  302 + # it's strongly recommend to open the debug_srs_upnode,
  303 + # when connect to upnode, it will take the debug info,
  304 + # for example, the id, source id, pid.
  305 + # please see: https://github.com/simple-rtmp-server/srs/wiki/v1_CN_SrsLog
  306 + # default: on
  307 + debug_srs_upnode on;
293 } 308 }
294 } 309 }
295 310
296 -# vhost for bandwidth check  
297 -# generally, the bandcheck vhost must be: bandcheck.srs.com,  
298 -# or need to modify the vhost of client.  
299 -vhost bandcheck.srs.com {  
300 - enabled on;  
301 - chunk_size 65000;  
302 - # bandwidth check config.  
303 - bandcheck {  
304 - # whether support bandwidth check,  
305 - # default: off.  
306 - enabled on;  
307 - # the key for server to valid,  
308 - # if invalid key, server disconnect and abort the bandwidth check.  
309 - key "35c9b402c12a7246868752e2878f7e0e";  
310 - # the interval in seconds for bandwidth check,  
311 - # server donot allow new test request.  
312 - # default: 30  
313 - interval 30;  
314 - # the max available check bandwidth in kbps.  
315 - # to avoid attack of bandwidth check.  
316 - # default: 1000  
317 - limit_kbps 4000; 311 +# vhost for edge, edge and origin is the same vhost
  312 +vhost same.edge.srs.com {
  313 + # @see cluster.srs.com
  314 + cluster {
  315 + mode remote;
  316 + origin 127.0.0.1:1935 localhost:1935;
  317 + token_traverse off;
318 } 318 }
319 } 319 }
320 320
321 -# the publish specified configs  
322 -vhost publish.srs.com {  
323 - # the config for FMLE/Flash publisher, which push RTMP to SRS.  
324 - publish {  
325 - # about MR, read https://github.com/simple-rtmp-server/srs/issues/241  
326 - # when enabled the mr, SRS will read as large as possible.  
327 - # default: off  
328 - mr off;  
329 - # the latency in ms for MR(merged-read),  
330 - # the performance+ when latency+, and memory+,  
331 - # memory(buffer) = latency * kbps / 8  
332 - # for example, latency=500ms, kbps=3000kbps, each publish connection will consume  
333 - # memory = 500 * 3000 / 8 = 187500B = 183KB  
334 - # when there are 2500 publisher, the total memory of SRS atleast:  
335 - # 183KB * 2500 = 446MB  
336 - # the value recomment is [300, 2000]  
337 - # default: 350  
338 - mr_latency 350; 321 +# vhost for edge, edge transform vhost to fetch from another vhost.
  322 +vhost transform.edge.srs.com {
  323 + # @see cluster.srs.com
  324 + cluster {
  325 + mode remote;
  326 + origin 127.0.0.1:1935;
  327 + vhost same.edge.srs.com;
  328 + }
  329 +}
339 330
340 - # the 1st packet timeout in ms for encoder.  
341 - # default: 20000  
342 - firstpkt_timeout 20000;  
343 - # the normal packet timeout in ms for encoder.  
344 - # default: 5000  
345 - normal_timeout 7000; 331 +# the vhost for srs debug info, whether send args in connect(tcUrl).
  332 +vhost debug.srs.com {
  333 + # @see cluster.srs.com
  334 + cluster {
  335 + debug_srs_upnode on;
  336 + }
  337 +}
  338 +
  339 +# the vhost which forward publish streams.
  340 +vhost same.vhost.forward.srs.com {
  341 + # forward stream to other servers.
  342 + forward {
  343 + # whether enable the forward.
  344 + # default: off
  345 + enabled on;
  346 + # forward all publish stream to the specified server.
  347 + # this used to split/forward the current stream for cluster active-standby,
  348 + # active-active for cdn to build high available fault tolerance system.
  349 + # format: {ip}:{port} {ip_N}:{port_N}
  350 + destination 127.0.0.1:1936 127.0.0.1:1937;
346 } 351 }
347 } 352 }
348 353
@@ -505,136 +510,81 @@ vhost stream.control.com { @@ -505,136 +510,81 @@ vhost stream.control.com {
505 } 510 }
506 } 511 }
507 512
508 -# the vhost which forward publish streams.  
509 -vhost same.vhost.forward.srs.com {  
510 - # forward stream to other servers.  
511 - forward {  
512 - # whether enable the forward.  
513 - # default: off  
514 - enabled on;  
515 - # forward all publish stream to the specified server.  
516 - # this used to split/forward the current stream for cluster active-standby,  
517 - # active-active for cdn to build high available fault tolerance system.  
518 - # format: {ip}:{port} {ip_N}:{port_N}  
519 - destination 127.0.0.1:1936 127.0.0.1:1937;  
520 - }  
521 -}  
522 -  
523 -# vhost for stream cluster for RTMP/FLV  
524 -vhost cluster.srs.com {  
525 - # stream RTMP/FLV cluster config.  
526 - cluster {  
527 - # the mode of vhost, local or remote.  
528 - # local: vhost is origin vhost, which provides stream source.  
529 - # remote: vhost is edge vhost, which pull/push to origin.  
530 - # default: local  
531 - mode remote;  
532 - # for edge(remote mode), user must specifies the origin server  
533 - # format as: <server_name|ip>[:port]  
534 - # @remark user can specifies multiple origin for error backup, by space,  
535 - # for example, 192.168.1.100:1935 192.168.1.101:1935 192.168.1.102:1935  
536 - origin 127.0.0.1:1935 localhost:1935;  
537 -  
538 - # for edge, whether open the token traverse mode,  
539 - # if token traverse on, all connections of edge will forward to origin to check(auth),  
540 - # it's very important for the edge to do the token auth.  
541 - # the better way is use http callback to do the token auth by the edge,  
542 - # but if user prefer origin check(auth), the token_traverse if better solution. 513 +# the publish specified configs
  514 +vhost publish.srs.com {
  515 + # the config for FMLE/Flash publisher, which push RTMP to SRS.
  516 + publish {
  517 + # about MR, read https://github.com/simple-rtmp-server/srs/issues/241
  518 + # when enabled the mr, SRS will read as large as possible.
543 # default: off 519 # default: off
544 - token_traverse off;  
545 -  
546 - # the vhost to transform for edge,  
547 - # to fetch from the specified vhost at origin,  
548 - # if not specified, use the current vhost of edge in origin, the variable [vhost].  
549 - # default: [vhost]  
550 - vhost same.edge.srs.com;  
551 -  
552 - # when upnode(forward to, edge push to, edge pull from) is srs,  
553 - # it's strongly recommend to open the debug_srs_upnode,  
554 - # when connect to upnode, it will take the debug info,  
555 - # for example, the id, source id, pid.  
556 - # please see: https://github.com/simple-rtmp-server/srs/wiki/v1_CN_SrsLog  
557 - # default: on  
558 - debug_srs_upnode on;  
559 - }  
560 -} 520 + mr off;
  521 + # the latency in ms for MR(merged-read),
  522 + # the performance+ when latency+, and memory+,
  523 + # memory(buffer) = latency * kbps / 8
  524 + # for example, latency=500ms, kbps=3000kbps, each publish connection will consume
  525 + # memory = 500 * 3000 / 8 = 187500B = 183KB
  526 + # when there are 2500 publisher, the total memory of SRS atleast:
  527 + # 183KB * 2500 = 446MB
  528 + # the value recomment is [300, 2000]
  529 + # default: 350
  530 + mr_latency 350;
561 531
562 -# vhost for edge, edge and origin is the same vhost  
563 -vhost same.edge.srs.com {  
564 - # @see cluster.srs.com  
565 - cluster {  
566 - mode remote;  
567 - origin 127.0.0.1:1935 localhost:1935;  
568 - token_traverse off; 532 + # the 1st packet timeout in ms for encoder.
  533 + # default: 20000
  534 + firstpkt_timeout 20000;
  535 + # the normal packet timeout in ms for encoder.
  536 + # default: 5000
  537 + normal_timeout 7000;
569 } 538 }
570 } 539 }
571 540
572 -# vhost for edge, edge transform vhost to fetch from another vhost.  
573 -vhost transform.edge.srs.com {  
574 - # @see cluster.srs.com  
575 - cluster {  
576 - mode remote;  
577 - origin 127.0.0.1:1935;  
578 - vhost same.edge.srs.com; 541 +# the vhost for antisuck.
  542 +vhost refer.anti_suck.com {
  543 + # refer hotlink-denial.
  544 + refer {
  545 + # whether enable the refer hotlink-denial.
  546 + # default: off.
  547 + enabled on;
  548 + # the common refer for play and publish.
  549 + # if the page url of client not in the refer, access denied.
  550 + # if not specified this field, allow all.
  551 + # default: not specified.
  552 + all github.com github.io;
  553 + # refer for publish clients specified.
  554 + # the common refer is not overrided by this.
  555 + # if not specified this field, allow all.
  556 + # default: not specified.
  557 + publish github.com github.io;
  558 + # refer for play clients specified.
  559 + # the common refer is not overrided by this.
  560 + # if not specified this field, allow all.
  561 + # default: not specified.
  562 + play github.com github.io;
579 } 563 }
580 } 564 }
581 565
582 -# the vhost for srs debug info, whether send args in connect(tcUrl).  
583 -vhost debug.srs.com {  
584 - # @see cluster.srs.com  
585 - cluster {  
586 - debug_srs_upnode on;  
587 - }  
588 -}  
589 -  
590 -  
591 -  
592 -  
593 -  
594 -  
595 -  
596 -  
597 -  
598 -  
599 -  
600 -  
601 -  
602 -  
603 -  
604 -  
605 -  
606 -  
607 -  
608 -  
609 -  
610 -  
611 -  
612 -  
613 -  
614 -  
615 -  
616 -  
617 -  
618 -# the vhost for exec, fork process when publish stream.  
619 -vhost exec.srs.com {  
620 - # the exec used to fork process when got some event.  
621 - exec {  
622 - # whether enable the exec. 566 +# vhost for bandwidth check
  567 +# generally, the bandcheck vhost must be: bandcheck.srs.com,
  568 +# or need to modify the vhost of client.
  569 +vhost bandcheck.srs.com {
  570 + enabled on;
  571 + chunk_size 65000;
  572 + # bandwidth check config.
  573 + bandcheck {
  574 + # whether support bandwidth check,
623 # default: off. 575 # default: off.
624 - enabled off;  
625 - # when publish stream, exec the process with variables:  
626 - # [vhost] the input stream vhost.  
627 - # [port] the intput stream port.  
628 - # [app] the input stream app.  
629 - # [stream] the input stream name.  
630 - # [engine] the tanscode engine name.  
631 - # other variables for exec only:  
632 - # [url] the rtmp url which trigger the publish.  
633 - # [tcUrl] the client request tcUrl.  
634 - # [swfUrl] the client request swfUrl.  
635 - # [pageUrl] the client request pageUrl.  
636 - # @remark empty to ignore this exec.  
637 - publish ./objs/ffmpeg/bin/ffmpeg -f flv -i [url] -c copy -y ./[stream].flv; 576 + enabled on;
  577 + # the key for server to valid,
  578 + # if invalid key, server disconnect and abort the bandwidth check.
  579 + key "35c9b402c12a7246868752e2878f7e0e";
  580 + # the interval in seconds for bandwidth check,
  581 + # server donot allow new test request.
  582 + # default: 30
  583 + interval 30;
  584 + # the max available check bandwidth in kbps.
  585 + # to avoid attack of bandwidth check.
  586 + # default: 1000
  587 + limit_kbps 4000;
638 } 588 }
639 } 589 }
640 590
@@ -667,173 +617,6 @@ vhost security.srs.com { @@ -667,173 +617,6 @@ vhost security.srs.com {
667 } 617 }
668 } 618 }
669 619
670 -# vhost for dvr  
671 -vhost dvr.srs.com {  
672 - # dvr RTMP stream to file,  
673 - # start to record to file when encoder publish,  
674 - # reap flv according by specified dvr_plan.  
675 - dvr {  
676 - # whether enabled dvr features  
677 - # default: off  
678 - enabled on;  
679 - # the dvr plan. canbe:  
680 - # session reap flv when session end(unpublish).  
681 - # segment reap flv when flv duration exceed the specified dvr_duration.  
682 - # append always append to flv file, never reap it.  
683 - # default: session  
684 - dvr_plan session;  
685 - # the dvr output path.  
686 - # we supports some variables to generate the filename.  
687 - # [vhost], the vhost of stream.  
688 - # [app], the app of stream.  
689 - # [stream], the stream name of stream.  
690 - # [2006], replace this const to current year.  
691 - # [01], replace this const to current month.  
692 - # [02], replace this const to current date.  
693 - # [15], replace this const to current hour.  
694 - # [04], repleace this const to current minute.  
695 - # [05], repleace this const to current second.  
696 - # [999], repleace this const to current millisecond.  
697 - # [timestamp],replace this const to current UNIX timestamp in ms.  
698 - # @remark we use golang time format "2006-01-02 15:04:05.999" as "[2006]-[01]-[02]_[15].[04].[05]_[999]"  
699 - # for example, for url rtmp://ossrs.net/live/livestream and time 2015-01-03 10:57:30.776  
700 - # 1. No variables, the rule of SRS1.0(auto add [stream].[timestamp].flv as filename):  
701 - # dvr_path ./objs/nginx/html;  
702 - # =>  
703 - # dvr_path ./objs/nginx/html/live/livestream.1420254068776.flv;  
704 - # 2. Use stream and date as dir name, time as filename:  
705 - # dvr_path /data/[vhost]/[app]/[stream]/[2006]/[01]/[02]/[15].[04].[05].[999].flv;  
706 - # =>  
707 - # dvr_path /data/ossrs.net/live/livestream/2015/01/03/10.57.30.776.flv;  
708 - # 3. Use stream and year/month as dir name, date and time as filename:  
709 - # dvr_path /data/[vhost]/[app]/[stream]/[2006]/[01]/[02]-[15].[04].[05].[999].flv;  
710 - # =>  
711 - # dvr_path /data/ossrs.net/live/livestream/2015/01/03-10.57.30.776.flv;  
712 - # 4. Use vhost/app and year/month as dir name, stream/date/time as filename:  
713 - # dvr_path /data/[vhost]/[app]/[2006]/[01]/[stream]-[02]-[15].[04].[05].[999].flv;  
714 - # =>  
715 - # dvr_path /data/ossrs.net/live/2015/01/livestream-03-10.57.30.776.flv;  
716 - # @see https://github.com/simple-rtmp-server/srs/wiki/v2_CN_DVR#custom-path  
717 - # @see https://github.com/simple-rtmp-server/srs/wiki/v2_EN_DVR#custom-path  
718 - # segment,session apply it.  
719 - # default: ./objs/nginx/html/[app]/[stream].[timestamp].flv  
720 - dvr_path ./objs/nginx/html/[app]/[stream].[timestamp].flv;  
721 - # the duration for dvr file, reap if exeed, in seconds.  
722 - # segment apply it.  
723 - # session,append ignore.  
724 - # default: 30  
725 - dvr_duration 30;  
726 - # whether wait keyframe to reap segment,  
727 - # if off, reap segment when duration exceed the dvr_duration,  
728 - # if on, reap segment when duration exceed and got keyframe.  
729 - # segment apply it.  
730 - # session,append ignore.  
731 - # default: on  
732 - dvr_wait_keyframe on;  
733 - # about the stream monotonically increasing:  
734 - # 1. video timestamp is monotonically increasing,  
735 - # 2. audio timestamp is monotonically increasing,  
736 - # 3. video and audio timestamp is interleaved monotonically increasing.  
737 - # it's specified by RTMP specification, @see 3. Byte Order, Alignment, and Time Format  
738 - # however, some encoder cannot provides this feature, please set this to off to ignore time jitter.  
739 - # the time jitter algorithm:  
740 - # 1. full, to ensure stream start at zero, and ensure stream monotonically increasing.  
741 - # 2. zero, only ensure sttream start at zero, ignore timestamp jitter.  
742 - # 3. off, disable the time jitter algorithm, like atc.  
743 - # apply for all dvr plan.  
744 - # default: full  
745 - time_jitter full;  
746 -  
747 - # on_dvr, never config in here, should config in http_hooks.  
748 - # for the dvr http callback, @see http_hooks.on_dvr of vhost hooks.callback.srs.com  
749 - # @read https://github.com/simple-rtmp-server/srs/wiki/v2_CN_DVR#http-callback  
750 - # @read https://github.com/simple-rtmp-server/srs/wiki/v2_EN_DVR#http-callback  
751 - }  
752 -}  
753 -  
754 -# vhost for ingest  
755 -vhost ingest.srs.com {  
756 - # ingest file/stream/device then push to SRS over RTMP.  
757 - # the name/id used to identify the ingest, must be unique in global.  
758 - # ingest id is used in reload or http api management.  
759 - ingest livestream {  
760 - # whether enabled ingest features  
761 - # default: off  
762 - enabled on;  
763 - # input file/stream/device  
764 - # @remark only support one input.  
765 - input {  
766 - # the type of input.  
767 - # can be file/stream/device, that is,  
768 - # file: ingest file specifies by url.  
769 - # stream: ingest stream specifeis by url.  
770 - # device: not support yet.  
771 - # default: file  
772 - type file;  
773 - # the url of file/stream.  
774 - url ./doc/source.200kbps.768x320.flv;  
775 - }  
776 - # the ffmpeg  
777 - ffmpeg ./objs/ffmpeg/bin/ffmpeg;  
778 - # the transcode engine, @see all.transcode.srs.com  
779 - # @remark, the output is specified following.  
780 - engine {  
781 - # @see enabled of transcode engine.  
782 - # if disabled or vcodec/acodec not specified, use copy.  
783 - # default: off.  
784 - enabled off;  
785 - # output stream. variables:  
786 - # [vhost] current vhost which start the ingest.  
787 - # [port] system RTMP stream port.  
788 - output rtmp://127.0.0.1:[port]/live?vhost=[vhost]/livestream;  
789 - }  
790 - }  
791 -}  
792 -  
793 -# the vhost for intest with transcode engine.  
794 -vhost transcode.ingest.srs.com {  
795 - ingest livestream {  
796 - enabled on;  
797 - input {  
798 - type file;  
799 - url ./doc/source.200kbps.768x320.flv;  
800 - }  
801 - ffmpeg ./objs/ffmpeg/bin/ffmpeg;  
802 - engine {  
803 - enabled off;  
804 - iformat flv;  
805 - vfilter {  
806 - i ./doc/ffmpeg-logo.png;  
807 - filter_complex 'overlay=10:10';  
808 - }  
809 - vcodec libx264;  
810 - vbitrate 1500;  
811 - vfps 25;  
812 - vwidth 768;  
813 - vheight 320;  
814 - vthreads 12;  
815 - vprofile main;  
816 - vpreset medium;  
817 - vparams {  
818 - t 100;  
819 - coder 1;  
820 - b_strategy 2;  
821 - bf 3;  
822 - refs 10;  
823 - }  
824 - acodec libfdk_aac;  
825 - abitrate 70;  
826 - asample_rate 44100;  
827 - achannels 2;  
828 - aparams {  
829 - profile:a aac_low;  
830 - }  
831 - oformat flv;  
832 - output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream];  
833 - }  
834 - }  
835 -}  
836 -  
837 # vhost for http static and flv vod stream for each vhost. 620 # vhost for http static and flv vod stream for each vhost.
838 vhost http.static.srs.com { 621 vhost http.static.srs.com {
839 # http static vhost specified config 622 # http static vhost specified config
@@ -916,19 +699,179 @@ vhost http.remux.srs.com { @@ -916,19 +699,179 @@ vhost http.remux.srs.com {
916 } 699 }
917 } 700 }
918 701
919 -# the vhost with hls specified.  
920 -vhost with-hls.srs.com {  
921 - hls {  
922 - # whether the hls is enabled.  
923 - # if off, donot write hls(ts and m3u8) when publish.  
924 - # default: off 702 +# the http hook callback vhost, srs will invoke the hooks for specified events.
  703 +vhost hooks.callback.srs.com {
  704 + http_hooks {
  705 + # whether the http hooks enalbe.
  706 + # default off.
925 enabled on; 707 enabled on;
926 - # the hls fragment in seconds, the duration of a piece of ts.  
927 - # default: 10  
928 - hls_fragment 10;  
929 - # the hls m3u8 target duration ratio,  
930 - # EXT-X-TARGETDURATION = hls_td_ratio * hls_fragment // init  
931 - # EXT-X-TARGETDURATION = max(ts_duration, EXT-X-TARGETDURATION) // for each ts 708 + # when client connect to vhost/app, call the hook,
  709 + # the request in the POST data string is a object encode by json:
  710 + # {
  711 + # "action": "on_connect",
  712 + # "client_id": 1985,
  713 + # "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",
  714 + # "tcUrl": "rtmp://video.test.com/live?key=d2fa801d08e3f90ed1e1670e6e52651a",
  715 + # "pageUrl": "http://www.test.com/live.html"
  716 + # }
  717 + # if valid, the hook must return HTTP code 200(Stauts OK) and response
  718 + # an int value specifies the error code(0 corresponding to success):
  719 + # 0
  720 + # support multiple api hooks, format:
  721 + # on_connect http://xxx/api0 http://xxx/api1 http://xxx/apiN
  722 + on_connect http://127.0.0.1:8085/api/v1/clients http://localhost:8085/api/v1/clients;
  723 + # when client close/disconnect to vhost/app/stream, call the hook,
  724 + # the request in the POST data string is a object encode by json:
  725 + # {
  726 + # "action": "on_close",
  727 + # "client_id": 1985,
  728 + # "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",
  729 + # "send_bytes": 10240, "recv_bytes": 10240
  730 + # }
  731 + # if valid, the hook must return HTTP code 200(Stauts OK) and response
  732 + # an int value specifies the error code(0 corresponding to success):
  733 + # 0
  734 + # support multiple api hooks, format:
  735 + # on_close http://xxx/api0 http://xxx/api1 http://xxx/apiN
  736 + on_close http://127.0.0.1:8085/api/v1/clients http://localhost:8085/api/v1/clients;
  737 + # when client(encoder) publish to vhost/app/stream, call the hook,
  738 + # the request in the POST data string is a object encode by json:
  739 + # {
  740 + # "action": "on_publish",
  741 + # "client_id": 1985,
  742 + # "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",
  743 + # "stream": "livestream"
  744 + # }
  745 + # if valid, the hook must return HTTP code 200(Stauts OK) and response
  746 + # an int value specifies the error code(0 corresponding to success):
  747 + # 0
  748 + # support multiple api hooks, format:
  749 + # on_publish http://xxx/api0 http://xxx/api1 http://xxx/apiN
  750 + on_publish http://127.0.0.1:8085/api/v1/streams http://localhost:8085/api/v1/streams;
  751 + # when client(encoder) stop publish to vhost/app/stream, call the hook,
  752 + # the request in the POST data string is a object encode by json:
  753 + # {
  754 + # "action": "on_unpublish",
  755 + # "client_id": 1985,
  756 + # "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",
  757 + # "stream": "livestream"
  758 + # }
  759 + # if valid, the hook must return HTTP code 200(Stauts OK) and response
  760 + # an int value specifies the error code(0 corresponding to success):
  761 + # 0
  762 + # support multiple api hooks, format:
  763 + # on_unpublish http://xxx/api0 http://xxx/api1 http://xxx/apiN
  764 + on_unpublish http://127.0.0.1:8085/api/v1/streams http://localhost:8085/api/v1/streams;
  765 + # when client start to play vhost/app/stream, call the hook,
  766 + # the request in the POST data string is a object encode by json:
  767 + # {
  768 + # "action": "on_play",
  769 + # "client_id": 1985,
  770 + # "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",
  771 + # "stream": "livestream",
  772 + # "pageUrl": "http://www.test.com/live.html"
  773 + # }
  774 + # if valid, the hook must return HTTP code 200(Stauts OK) and response
  775 + # an int value specifies the error code(0 corresponding to success):
  776 + # 0
  777 + # support multiple api hooks, format:
  778 + # on_play http://xxx/api0 http://xxx/api1 http://xxx/apiN
  779 + on_play http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions;
  780 + # when client stop to play vhost/app/stream, call the hook,
  781 + # the request in the POST data string is a object encode by json:
  782 + # {
  783 + # "action": "on_stop",
  784 + # "client_id": 1985,
  785 + # "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",
  786 + # "stream": "livestream"
  787 + # }
  788 + # if valid, the hook must return HTTP code 200(Stauts OK) and response
  789 + # an int value specifies the error code(0 corresponding to success):
  790 + # 0
  791 + # support multiple api hooks, format:
  792 + # on_stop http://xxx/api0 http://xxx/api1 http://xxx/apiN
  793 + on_stop http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions;
  794 + # when srs reap a dvr file, call the hook,
  795 + # the request in the POST data string is a object encode by json:
  796 + # {
  797 + # "action": "on_dvr",
  798 + # "client_id": 1985,
  799 + # "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",
  800 + # "stream": "livestream",
  801 + # "cwd": "/usr/local/srs",
  802 + # "file": "./objs/nginx/html/live/livestream.1420254068776.flv"
  803 + # }
  804 + # if valid, the hook must return HTTP code 200(Stauts OK) and response
  805 + # an int value specifies the error code(0 corresponding to success):
  806 + # 0
  807 + on_dvr http://127.0.0.1:8085/api/v1/dvrs http://localhost:8085/api/v1/dvrs;
  808 + # when srs reap a ts file of hls, call the hook,
  809 + # the request in the POST data string is a object encode by json:
  810 + # {
  811 + # "action": "on_hls",
  812 + # "client_id": 1985,
  813 + # "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",
  814 + # "stream": "livestream",
  815 + # "duration": 9.36, // in seconds
  816 + # "cwd": "/usr/local/srs",
  817 + # "file": "./objs/nginx/html/live/livestream/2015-04-23/01/476584165.ts",
  818 + # "url": "live/livestream/2015-04-23/01/476584165.ts",
  819 + # "m3u8": "./objs/nginx/html/live/livestream/live.m3u8",
  820 + # "m3u8_url": "live/livestream/live.m3u8",
  821 + # "seq_no": 100
  822 + # }
  823 + # if valid, the hook must return HTTP code 200(Stauts OK) and response
  824 + # an int value specifies the error code(0 corresponding to success):
  825 + # 0
  826 + on_hls http://127.0.0.1:8085/api/v1/hls http://localhost:8085/api/v1/hls;
  827 + # when srs reap a ts file of hls, call this hook,
  828 + # used to push file to cdn network, by get the ts file from cdn network.
  829 + # so we use HTTP GET and use the variable following:
  830 + # [app], replace with the app.
  831 + # [stream], replace with the stream.
  832 + # [ts_url], replace with the ts url.
  833 + # ignore any return data of server.
  834 + # @remark random select a url to report, not report all.
  835 + on_hls_notify http://127.0.0.1:8085/api/v1/hls/[app]/[stream][ts_url];
  836 + }
  837 +}
  838 +
  839 +# the vhost for exec, fork process when publish stream.
  840 +vhost exec.srs.com {
  841 + # the exec used to fork process when got some event.
  842 + exec {
  843 + # whether enable the exec.
  844 + # default: off.
  845 + enabled off;
  846 + # when publish stream, exec the process with variables:
  847 + # [vhost] the input stream vhost.
  848 + # [port] the intput stream port.
  849 + # [app] the input stream app.
  850 + # [stream] the input stream name.
  851 + # [engine] the tanscode engine name.
  852 + # other variables for exec only:
  853 + # [url] the rtmp url which trigger the publish.
  854 + # [tcUrl] the client request tcUrl.
  855 + # [swfUrl] the client request swfUrl.
  856 + # [pageUrl] the client request pageUrl.
  857 + # @remark empty to ignore this exec.
  858 + publish ./objs/ffmpeg/bin/ffmpeg -f flv -i [url] -c copy -y ./[stream].flv;
  859 + }
  860 +}
  861 +
  862 +# the vhost with hls specified.
  863 +vhost with-hls.srs.com {
  864 + hls {
  865 + # whether the hls is enabled.
  866 + # if off, donot write hls(ts and m3u8) when publish.
  867 + # default: off
  868 + enabled on;
  869 + # the hls fragment in seconds, the duration of a piece of ts.
  870 + # default: 10
  871 + hls_fragment 10;
  872 + # the hls m3u8 target duration ratio,
  873 + # EXT-X-TARGETDURATION = hls_td_ratio * hls_fragment // init
  874 + # EXT-X-TARGETDURATION = max(ts_duration, EXT-X-TARGETDURATION) // for each ts
932 # @see https://github.com/simple-rtmp-server/srs/issues/304#issuecomment-74000081 875 # @see https://github.com/simple-rtmp-server/srs/issues/304#issuecomment-74000081
933 # default: 1.5 876 # default: 1.5
934 hls_td_ratio 1.5; 877 hls_td_ratio 1.5;
@@ -1085,140 +1028,170 @@ vhost hds.srs.com { @@ -1085,140 +1028,170 @@ vhost hds.srs.com {
1085 } 1028 }
1086 } 1029 }
1087 1030
1088 -# the http hook callback vhost, srs will invoke the hooks for specified events.  
1089 -vhost hooks.callback.srs.com {  
1090 - http_hooks {  
1091 - # whether the http hooks enalbe.  
1092 - # default off. 1031 +# vhost for dvr
  1032 +vhost dvr.srs.com {
  1033 + # dvr RTMP stream to file,
  1034 + # start to record to file when encoder publish,
  1035 + # reap flv according by specified dvr_plan.
  1036 + dvr {
  1037 + # whether enabled dvr features
  1038 + # default: off
1093 enabled on; 1039 enabled on;
1094 - # when client connect to vhost/app, call the hook,  
1095 - # the request in the POST data string is a object encode by json:  
1096 - # {  
1097 - # "action": "on_connect",  
1098 - # "client_id": 1985,  
1099 - # "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",  
1100 - # "tcUrl": "rtmp://video.test.com/live?key=d2fa801d08e3f90ed1e1670e6e52651a",  
1101 - # "pageUrl": "http://www.test.com/live.html"  
1102 - # }  
1103 - # if valid, the hook must return HTTP code 200(Stauts OK) and response  
1104 - # an int value specifies the error code(0 corresponding to success):  
1105 - # 0  
1106 - # support multiple api hooks, format:  
1107 - # on_connect http://xxx/api0 http://xxx/api1 http://xxx/apiN  
1108 - on_connect http://127.0.0.1:8085/api/v1/clients http://localhost:8085/api/v1/clients;  
1109 - # when client close/disconnect to vhost/app/stream, call the hook,  
1110 - # the request in the POST data string is a object encode by json:  
1111 - # {  
1112 - # "action": "on_close",  
1113 - # "client_id": 1985,  
1114 - # "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",  
1115 - # "send_bytes": 10240, "recv_bytes": 10240  
1116 - # }  
1117 - # if valid, the hook must return HTTP code 200(Stauts OK) and response  
1118 - # an int value specifies the error code(0 corresponding to success):  
1119 - # 0  
1120 - # support multiple api hooks, format:  
1121 - # on_close http://xxx/api0 http://xxx/api1 http://xxx/apiN  
1122 - on_close http://127.0.0.1:8085/api/v1/clients http://localhost:8085/api/v1/clients;  
1123 - # when client(encoder) publish to vhost/app/stream, call the hook,  
1124 - # the request in the POST data string is a object encode by json:  
1125 - # {  
1126 - # "action": "on_publish",  
1127 - # "client_id": 1985,  
1128 - # "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",  
1129 - # "stream": "livestream"  
1130 - # }  
1131 - # if valid, the hook must return HTTP code 200(Stauts OK) and response  
1132 - # an int value specifies the error code(0 corresponding to success):  
1133 - # 0  
1134 - # support multiple api hooks, format:  
1135 - # on_publish http://xxx/api0 http://xxx/api1 http://xxx/apiN  
1136 - on_publish http://127.0.0.1:8085/api/v1/streams http://localhost:8085/api/v1/streams;  
1137 - # when client(encoder) stop publish to vhost/app/stream, call the hook,  
1138 - # the request in the POST data string is a object encode by json:  
1139 - # {  
1140 - # "action": "on_unpublish",  
1141 - # "client_id": 1985,  
1142 - # "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",  
1143 - # "stream": "livestream"  
1144 - # }  
1145 - # if valid, the hook must return HTTP code 200(Stauts OK) and response  
1146 - # an int value specifies the error code(0 corresponding to success):  
1147 - # 0  
1148 - # support multiple api hooks, format:  
1149 - # on_unpublish http://xxx/api0 http://xxx/api1 http://xxx/apiN  
1150 - on_unpublish http://127.0.0.1:8085/api/v1/streams http://localhost:8085/api/v1/streams;  
1151 - # when client start to play vhost/app/stream, call the hook,  
1152 - # the request in the POST data string is a object encode by json:  
1153 - # {  
1154 - # "action": "on_play",  
1155 - # "client_id": 1985,  
1156 - # "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",  
1157 - # "stream": "livestream",  
1158 - # "pageUrl": "http://www.test.com/live.html"  
1159 - # }  
1160 - # if valid, the hook must return HTTP code 200(Stauts OK) and response  
1161 - # an int value specifies the error code(0 corresponding to success):  
1162 - # 0  
1163 - # support multiple api hooks, format:  
1164 - # on_play http://xxx/api0 http://xxx/api1 http://xxx/apiN  
1165 - on_play http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions;  
1166 - # when client stop to play vhost/app/stream, call the hook,  
1167 - # the request in the POST data string is a object encode by json:  
1168 - # {  
1169 - # "action": "on_stop",  
1170 - # "client_id": 1985,  
1171 - # "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",  
1172 - # "stream": "livestream"  
1173 - # }  
1174 - # if valid, the hook must return HTTP code 200(Stauts OK) and response  
1175 - # an int value specifies the error code(0 corresponding to success):  
1176 - # 0  
1177 - # support multiple api hooks, format:  
1178 - # on_stop http://xxx/api0 http://xxx/api1 http://xxx/apiN  
1179 - on_stop http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions;  
1180 - # when srs reap a dvr file, call the hook,  
1181 - # the request in the POST data string is a object encode by json:  
1182 - # {  
1183 - # "action": "on_dvr",  
1184 - # "client_id": 1985,  
1185 - # "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",  
1186 - # "stream": "livestream",  
1187 - # "cwd": "/usr/local/srs",  
1188 - # "file": "./objs/nginx/html/live/livestream.1420254068776.flv"  
1189 - # }  
1190 - # if valid, the hook must return HTTP code 200(Stauts OK) and response  
1191 - # an int value specifies the error code(0 corresponding to success):  
1192 - # 0  
1193 - on_dvr http://127.0.0.1:8085/api/v1/dvrs http://localhost:8085/api/v1/dvrs;  
1194 - # when srs reap a ts file of hls, call the hook,  
1195 - # the request in the POST data string is a object encode by json:  
1196 - # {  
1197 - # "action": "on_hls",  
1198 - # "client_id": 1985,  
1199 - # "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",  
1200 - # "stream": "livestream",  
1201 - # "duration": 9.36, // in seconds  
1202 - # "cwd": "/usr/local/srs",  
1203 - # "file": "./objs/nginx/html/live/livestream/2015-04-23/01/476584165.ts",  
1204 - # "url": "live/livestream/2015-04-23/01/476584165.ts",  
1205 - # "m3u8": "./objs/nginx/html/live/livestream/live.m3u8",  
1206 - # "m3u8_url": "live/livestream/live.m3u8",  
1207 - # "seq_no": 100  
1208 - # }  
1209 - # if valid, the hook must return HTTP code 200(Stauts OK) and response  
1210 - # an int value specifies the error code(0 corresponding to success):  
1211 - # 0  
1212 - on_hls http://127.0.0.1:8085/api/v1/hls http://localhost:8085/api/v1/hls;  
1213 - # when srs reap a ts file of hls, call this hook,  
1214 - # used to push file to cdn network, by get the ts file from cdn network.  
1215 - # so we use HTTP GET and use the variable following:  
1216 - # [app], replace with the app.  
1217 - # [stream], replace with the stream.  
1218 - # [ts_url], replace with the ts url.  
1219 - # ignore any return data of server.  
1220 - # @remark random select a url to report, not report all.  
1221 - on_hls_notify http://127.0.0.1:8085/api/v1/hls/[app]/[stream][ts_url]; 1040 + # the dvr plan. canbe:
  1041 + # session reap flv when session end(unpublish).
  1042 + # segment reap flv when flv duration exceed the specified dvr_duration.
  1043 + # append always append to flv file, never reap it.
  1044 + # default: session
  1045 + dvr_plan session;
  1046 + # the dvr output path.
  1047 + # we supports some variables to generate the filename.
  1048 + # [vhost], the vhost of stream.
  1049 + # [app], the app of stream.
  1050 + # [stream], the stream name of stream.
  1051 + # [2006], replace this const to current year.
  1052 + # [01], replace this const to current month.
  1053 + # [02], replace this const to current date.
  1054 + # [15], replace this const to current hour.
  1055 + # [04], repleace this const to current minute.
  1056 + # [05], repleace this const to current second.
  1057 + # [999], repleace this const to current millisecond.
  1058 + # [timestamp],replace this const to current UNIX timestamp in ms.
  1059 + # @remark we use golang time format "2006-01-02 15:04:05.999" as "[2006]-[01]-[02]_[15].[04].[05]_[999]"
  1060 + # for example, for url rtmp://ossrs.net/live/livestream and time 2015-01-03 10:57:30.776
  1061 + # 1. No variables, the rule of SRS1.0(auto add [stream].[timestamp].flv as filename):
  1062 + # dvr_path ./objs/nginx/html;
  1063 + # =>
  1064 + # dvr_path ./objs/nginx/html/live/livestream.1420254068776.flv;
  1065 + # 2. Use stream and date as dir name, time as filename:
  1066 + # dvr_path /data/[vhost]/[app]/[stream]/[2006]/[01]/[02]/[15].[04].[05].[999].flv;
  1067 + # =>
  1068 + # dvr_path /data/ossrs.net/live/livestream/2015/01/03/10.57.30.776.flv;
  1069 + # 3. Use stream and year/month as dir name, date and time as filename:
  1070 + # dvr_path /data/[vhost]/[app]/[stream]/[2006]/[01]/[02]-[15].[04].[05].[999].flv;
  1071 + # =>
  1072 + # dvr_path /data/ossrs.net/live/livestream/2015/01/03-10.57.30.776.flv;
  1073 + # 4. Use vhost/app and year/month as dir name, stream/date/time as filename:
  1074 + # dvr_path /data/[vhost]/[app]/[2006]/[01]/[stream]-[02]-[15].[04].[05].[999].flv;
  1075 + # =>
  1076 + # dvr_path /data/ossrs.net/live/2015/01/livestream-03-10.57.30.776.flv;
  1077 + # @see https://github.com/simple-rtmp-server/srs/wiki/v2_CN_DVR#custom-path
  1078 + # @see https://github.com/simple-rtmp-server/srs/wiki/v2_EN_DVR#custom-path
  1079 + # segment,session apply it.
  1080 + # default: ./objs/nginx/html/[app]/[stream].[timestamp].flv
  1081 + dvr_path ./objs/nginx/html/[app]/[stream].[timestamp].flv;
  1082 + # the duration for dvr file, reap if exeed, in seconds.
  1083 + # segment apply it.
  1084 + # session,append ignore.
  1085 + # default: 30
  1086 + dvr_duration 30;
  1087 + # whether wait keyframe to reap segment,
  1088 + # if off, reap segment when duration exceed the dvr_duration,
  1089 + # if on, reap segment when duration exceed and got keyframe.
  1090 + # segment apply it.
  1091 + # session,append ignore.
  1092 + # default: on
  1093 + dvr_wait_keyframe on;
  1094 + # about the stream monotonically increasing:
  1095 + # 1. video timestamp is monotonically increasing,
  1096 + # 2. audio timestamp is monotonically increasing,
  1097 + # 3. video and audio timestamp is interleaved monotonically increasing.
  1098 + # it's specified by RTMP specification, @see 3. Byte Order, Alignment, and Time Format
  1099 + # however, some encoder cannot provides this feature, please set this to off to ignore time jitter.
  1100 + # the time jitter algorithm:
  1101 + # 1. full, to ensure stream start at zero, and ensure stream monotonically increasing.
  1102 + # 2. zero, only ensure sttream start at zero, ignore timestamp jitter.
  1103 + # 3. off, disable the time jitter algorithm, like atc.
  1104 + # apply for all dvr plan.
  1105 + # default: full
  1106 + time_jitter full;
  1107 +
  1108 + # on_dvr, never config in here, should config in http_hooks.
  1109 + # for the dvr http callback, @see http_hooks.on_dvr of vhost hooks.callback.srs.com
  1110 + # @read https://github.com/simple-rtmp-server/srs/wiki/v2_CN_DVR#http-callback
  1111 + # @read https://github.com/simple-rtmp-server/srs/wiki/v2_EN_DVR#http-callback
  1112 + }
  1113 +}
  1114 +
  1115 +# vhost for ingest
  1116 +vhost ingest.srs.com {
  1117 + # ingest file/stream/device then push to SRS over RTMP.
  1118 + # the name/id used to identify the ingest, must be unique in global.
  1119 + # ingest id is used in reload or http api management.
  1120 + ingest livestream {
  1121 + # whether enabled ingest features
  1122 + # default: off
  1123 + enabled on;
  1124 + # input file/stream/device
  1125 + # @remark only support one input.
  1126 + input {
  1127 + # the type of input.
  1128 + # can be file/stream/device, that is,
  1129 + # file: ingest file specifies by url.
  1130 + # stream: ingest stream specifeis by url.
  1131 + # device: not support yet.
  1132 + # default: file
  1133 + type file;
  1134 + # the url of file/stream.
  1135 + url ./doc/source.200kbps.768x320.flv;
  1136 + }
  1137 + # the ffmpeg
  1138 + ffmpeg ./objs/ffmpeg/bin/ffmpeg;
  1139 + # the transcode engine, @see all.transcode.srs.com
  1140 + # @remark, the output is specified following.
  1141 + engine {
  1142 + # @see enabled of transcode engine.
  1143 + # if disabled or vcodec/acodec not specified, use copy.
  1144 + # default: off.
  1145 + enabled off;
  1146 + # output stream. variables:
  1147 + # [vhost] current vhost which start the ingest.
  1148 + # [port] system RTMP stream port.
  1149 + output rtmp://127.0.0.1:[port]/live?vhost=[vhost]/livestream;
  1150 + }
  1151 + }
  1152 +}
  1153 +
  1154 +# the vhost for intest with transcode engine.
  1155 +vhost transcode.ingest.srs.com {
  1156 + ingest livestream {
  1157 + enabled on;
  1158 + input {
  1159 + type file;
  1160 + url ./doc/source.200kbps.768x320.flv;
  1161 + }
  1162 + ffmpeg ./objs/ffmpeg/bin/ffmpeg;
  1163 + engine {
  1164 + enabled off;
  1165 + iformat flv;
  1166 + vfilter {
  1167 + i ./doc/ffmpeg-logo.png;
  1168 + filter_complex 'overlay=10:10';
  1169 + }
  1170 + vcodec libx264;
  1171 + vbitrate 1500;
  1172 + vfps 25;
  1173 + vwidth 768;
  1174 + vheight 320;
  1175 + vthreads 12;
  1176 + vprofile main;
  1177 + vpreset medium;
  1178 + vparams {
  1179 + t 100;
  1180 + coder 1;
  1181 + b_strategy 2;
  1182 + bf 3;
  1183 + refs 10;
  1184 + }
  1185 + acodec libfdk_aac;
  1186 + abitrate 70;
  1187 + asample_rate 44100;
  1188 + achannels 2;
  1189 + aparams {
  1190 + profile:a aac_low;
  1191 + }
  1192 + oformat flv;
  1193 + output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream];
  1194 + }
1222 } 1195 }
1223 } 1196 }
1224 1197
@@ -51,7 +51,6 @@ vhost vhost.srs.com { @@ -51,7 +51,6 @@ vhost vhost.srs.com {
51 tcp_nodelay on; 51 tcp_nodelay on;
52 min_latency on; 52 min_latency on;
53 53
54 - # TODO  
55 cluster { 54 cluster {
56 mode remote; 55 mode remote;
57 origin 127.0.0.1:1935 localhost:1935; 56 origin 127.0.0.1:1935 localhost:1935;
@@ -137,6 +136,11 @@ vhost vhost.srs.com { @@ -137,6 +136,11 @@ vhost vhost.srs.com {
137 on_hls_notify http://127.0.0.1:8085/api/v1/hls/[app]/[stream][ts_url]; 136 on_hls_notify http://127.0.0.1:8085/api/v1/hls/[app]/[stream][ts_url];
138 } 137 }
139 138
  139 + exec {
  140 + enabled off;
  141 + publish ./objs/ffmpeg/bin/ffmpeg -f flv -i [url] -c copy -y ./[stream].flv;
  142 + }
  143 +
140 hls { 144 hls {
141 enabled off; 145 enabled off;
142 hls_fragment 10; 146 hls_fragment 10;
@@ -166,11 +170,6 @@ vhost vhost.srs.com { @@ -166,11 +170,6 @@ vhost vhost.srs.com {
166 hds_path ./objs/nginx/html; 170 hds_path ./objs/nginx/html;
167 } 171 }
168 172
169 - exec {  
170 - enabled off;  
171 - publish ./objs/ffmpeg/bin/ffmpeg -f flv -i [url] -c copy -y ./[stream].flv;  
172 - }  
173 -  
174 dvr { 173 dvr {
175 enabled off; 174 enabled off;
176 dvr_plan session; 175 dvr_plan session;