├── README.md ├── app ├── EventHandler.php ├── RtmpEndpoint.php └── loader.php └── library └── CRtmpLivestream ├── IRtmpEventHandler.php ├── Laravel.php ├── RtmpConstants.php ├── RtmpHandler.php └── RtmpSettings.php /README.md: -------------------------------------------------------------------------------- 1 | # Livestream 2 | A php backend for nginx rtmp module. 3 | 4 | # Notice 5 | This project is currently being rewritten from scratch to be used as a library. 6 | [if you are looking for a the old version, please click here](https://github.com/CallumCarmicheal/Livestream/tree/487cf9b876d7a4e9087ab30246a9dd87fd1a50fe) 7 | 8 | # Example configuration 9 | ``` 10 | rtmp { 11 | server { 12 | # Rtmp Listen Port 13 | listen 1935; 14 | 15 | # Application, this defines the specific streaming settings for each type 16 | # This means you can have a branch that will save and record live streams and 17 | # a branch for single one off live streams for low latency etc. 18 | # 19 | # In obs this is the url like: rtmp://ip_or_url/live 20 | # rtmp://localhost/live 21 | # 22 | application live { 23 | # Allow anyone to publish/watch a stream (this can be used to 24 | # limit the viewers to a subnet, ip. If you plan on doing this 25 | # in code it might be more beneficial to set this option instead 26 | # as it will increase performance and decrease load). 27 | 28 | # Allow anyone to publish a stream 29 | allow publish all; 30 | 31 | # Allow anyone to play / watch a stream 32 | allow play all; 33 | 34 | # Enable Live streaming 35 | live on; 36 | 37 | # https://github.com/arut/nginx-rtmp-module/wiki/Directives#meta 38 | meta copy; 39 | 40 | # We want to attach our events, if you don't want to subscribe to an event just 41 | # comment it out with a hash-tag (#). 42 | on_publish http://localhost/app/RtmpEndpoint.php; 43 | on_publish_done http://localhost/app/RtmpEndpoint.php; 44 | on_done http://localhost/app/RtmpEndpoint.php; 45 | on_play http://localhost/app/RtmpEndpoint.php; 46 | on_play_done http://localhost/app/RtmpEndpoint.php; 47 | on_update http://localhost/app/RtmpEndpoint.php; 48 | 49 | # Send the on_update event every 10 seconds, this as of right now 50 | # might be the only way to cut a stream midway as i am currently 51 | # looking into it. 52 | notify_update_timeout 10s; 53 | 54 | # Send all information as a get request 55 | notify_method get; 56 | 57 | # 58 | # See more advanced options at https://github.com/arut/nginx-rtmp-module/wiki/Directives 59 | # 60 | } 61 | } 62 | } 63 | ``` 64 | 65 | # Setup and Development 66 | ... 67 | 68 | # Security 69 | ... 70 | -------------------------------------------------------------------------------- /app/EventHandler.php: -------------------------------------------------------------------------------- 1 | eventHandler = new EventHandler(); 14 | $rtmpHandler = new \CRtmpLivestream\RtmpHandler($rtmpSettings); 15 | 16 | 17 | if ($rtmpHandler->IsAllowedHost()) 18 | /** Process Request */ 19 | $rtmpHandler->Process(); 20 | 21 | echo "THIS IS NOT A RTMP REQUEST?"; -------------------------------------------------------------------------------- /app/loader.php: -------------------------------------------------------------------------------- 1 | 50) 20 | return; 21 | 22 | // require all php files 23 | $scan = glob("$dir/*"); 24 | foreach ($scan as $path) { 25 | if (preg_match('/\.php$/', $path)) { 26 | // echo "Included $path
"; 27 | require_once $path; 28 | } else if (is_dir($path)) { 29 | _require_all($path, $depth+1); 30 | } 31 | } 32 | } 33 | 34 | _require_all(__DIR__. "/../library"); -------------------------------------------------------------------------------- /library/CRtmpLivestream/IRtmpEventHandler.php: -------------------------------------------------------------------------------- 1 | handler = $h; } 14 | 15 | /** 16 | * Event is invoked when the on_connect event has been fired by RTMP 17 | * This is fired when the client first connects (viewer) 18 | * 19 | * @see https://github.com/arut/nginx-rtmp-module/wiki/Directives#on_connect 20 | * 21 | * @param $addr string Client IP address 22 | * @param $app string Application name 23 | * @param $flashVer string Client flash version 24 | * @param $swfUrl string Client swf url 25 | * @param $tcUrl string 26 | * @param $pageUrl string Client page url 27 | * @return bool States if event is accepted 28 | */ 29 | public function onConnect($addr, $app, $flashVer, $swfUrl, $tcUrl, $pageUrl) { 30 | return true; 31 | } 32 | 33 | /** 34 | * Event is invoked when a viewer starts to watch a stream 35 | * 36 | * 37 | * @see https://github.com/arut/nginx-rtmp-module/wiki/Directives#on_play 38 | * 39 | * @param $addr string Client IP address 40 | * @param $clientid string Nginx client id (displayed in log and stat) 41 | * @param $app string Application name 42 | * @param $flashVer string Client flash version 43 | * @param $swfUrl string Client swf url 44 | * @param $tcUrl string 45 | * @param $pageUrl string Client page url 46 | * @param $name string Stream name 47 | * @return bool States if event is accepted 48 | */ 49 | public function onPlay($addr, $clientid, $app, $flashVer, $swfUrl, $tcUrl, $pageUrl, $name) { 50 | return true; 51 | } 52 | 53 | 54 | public function onPlayDone() { 55 | return true; 56 | } 57 | 58 | /** 59 | * Terminated ? from onUpdate ? 60 | * 61 | * @param $addr string Client IP address 62 | * @param $clientid string Nginx client id (displayed in log and stat) 63 | * @param $app string Application name 64 | * @param $flashVer string Client flash version 65 | * @param $swfUrl string Client swf url 66 | * @param $tcUrl string 67 | * @param $pageUrl string Client page url 68 | * @param $name string Stream name 69 | * @return bool States if event is accepted 70 | */ 71 | public function onDone($addr, $clientid, $app, $flashVer, $swfUrl, $tcUrl, $pageUrl, $name) { 72 | return true; 73 | } 74 | 75 | /** 76 | * User has started streaming 77 | * 78 | * @param $addr 79 | * @param $clientid 80 | * @param $app 81 | * @param $flashVer 82 | * @param $swfUrl 83 | * @param $tcUrl 84 | * @param $pageUrl 85 | * @param $name 86 | * @param $type 87 | * @return bool 88 | */ 89 | public function onPublish($addr, $clientid, $app, $flashVer, $swfUrl, $tcUrl, $pageUrl, $name, $type) { 90 | return true; 91 | } 92 | 93 | /** 94 | * Just like publish but every x seconds defined as notify_update_timeout 95 | * this would be used to terminate a stream 96 | * @return bool 97 | */ 98 | public function onPublishUpdate($addr, $clientid, $app, $flashVer, $swfUrl, $tcUrl, $pageUrl, $name) { 99 | return true; 100 | } 101 | 102 | /** 103 | * User is done streaming 104 | * 105 | * @param $addr 106 | * @param $clientid 107 | * @param $app 108 | * @param $flashVer 109 | * @param $swfUrl 110 | * @param $tcUrl 111 | * @param $pageUrl 112 | * @param $name 113 | * @return bool 114 | */ 115 | public function onPublishDone($addr, $clientid, $app, $flashVer, $swfUrl, $tcUrl, $pageUrl, $name) { 116 | return true; 117 | } 118 | 119 | 120 | /** 121 | * TODO: Figure out how to invoke 122 | * 123 | * @return bool 124 | */ 125 | public function onRecordDone() { 126 | return true; 127 | } 128 | 129 | 130 | 131 | } -------------------------------------------------------------------------------- /library/CRtmpLivestream/Laravel.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CallumCarmicheal/Livestream/e6f8a66846096f766b10ff4627fdaf1b6f0f1129/library/CRtmpLivestream/Laravel.php -------------------------------------------------------------------------------- /library/CRtmpLivestream/RtmpConstants.php: -------------------------------------------------------------------------------- 1 | settings = $settings; 17 | } 18 | 19 | /** 20 | * Checks if this is a accepted rtmp host 21 | * @return bool 22 | */ 23 | public function IsAllowedHost() { 24 | var_dump($_SERVER['REMOTE_ADDR']); 25 | 26 | return (in_array($_SERVER['REMOTE_ADDR'], $this->settings->acceptedServerHosts)); 27 | } 28 | 29 | public function Process() { 30 | $state = $this->Invoke(); 31 | 32 | ob_clean(); 33 | http_response_code($state ? 200 : 500); 34 | exit; 35 | } 36 | 37 | public function Invoke() { 38 | $data = $this->settings->requestMethodIsPost ? $_POST : $_GET; 39 | 40 | if (!isset($data['call'])) 41 | return false; 42 | 43 | switch($data['call']) { 44 | 45 | case "connect": 46 | return $this->settings->eventHandler->onConnect( 47 | $data['addr'], $data['app'], $data['flashver'], 48 | $data['swfurl'], $data['tcurl'], $data['pageurl']); 49 | 50 | case "done": 51 | return $this->settings->eventHandler->onDone( 52 | $data['addr'], $data['clientid'], $data['app'], $data['flashver'], 53 | $data['swfurl'], $data['tcurl'], $data['pageurl'], $data['name']); 54 | break; 55 | 56 | case "play": 57 | return $this->settings->eventHandler->onPlay( 58 | $data['addr'], $data['clientid'], $data['app'], $data['flashver'], 59 | $data['swfurl'], $data['tcurl'], $data['pageurl'], $data['name']); 60 | break; 61 | 62 | case "play_done": 63 | break; 64 | 65 | case "publish": 66 | return $this->settings->eventHandler->onPublish( 67 | $data['addr'], $data['clientid'], $data['app'], $data['flashver'], 68 | $data['swfurl'], $data['tcurl'], $data['pageurl'], $data['name'], 69 | $data['type']); 70 | 71 | case "update_publish": 72 | break; 73 | 74 | case "publish_done": 75 | return $this->settings->eventHandler->onPublishDone( 76 | $data['addr'], $data['clientid'], $data['app'], $data['flashver'], 77 | $data['swfurl'], $data['tcurl'], $data['pageurl'], $data['name']); 78 | 79 | case "record_done": 80 | break; 81 | 82 | default: return false; 83 | } 84 | 85 | } 86 | } -------------------------------------------------------------------------------- /library/CRtmpLivestream/RtmpSettings.php: -------------------------------------------------------------------------------- 1 |