index.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <?php
  2. //--------------------------------------------------------------------
  3. // $Id: index.php,v 0.7 2008/07/24 18:46:16 tmerkel Exp $
  4. // Copyright 2008 Frubar Network (drscream@frubar.net | wiedi@frubar.net)
  5. //--------------------------------------------------------------------
  6. /*
  7. * information:
  8. * - vlc under gentoo is compiled with the following useflags:
  9. * X a52 aac aalib alsa avahi bidi dbus dts dvb dvd esd ffmpeg flac
  10. * gnutls hal httpd libgcrypt mmx modplug mp3 mpeg musepack musicbrainz
  11. * ncurses ogg opengl png pvr qt4 samba sdl shout sse stream taglib
  12. * truetype upnp v4l v4l2 vcd vcdx vlm vorbis xml xv
  13. * - apache must in the same group that the dvb device, for example
  14. * video and audio.
  15. * - the channels.dvb must be in the following format (the first is the
  16. * line number :P ):
  17. * 1: # generated by tmerkel
  18. * 2: info:channel name:frequency:orientation:unknown:symbols:unused:unused:channel
  19. * 3: TV :Das Erste :11836 :h :0 :27500 :101 :102 :28106
  20. * example line:
  21. * 4: TV:Das Erste:11836:h:0:27500:101:102:28106
  22. *
  23. */
  24. define( 'NL', "\n" );
  25. error_reporting( 0 );
  26. /*
  27. * functions
  28. */
  29. function rmnl( $in ) {
  30. return str_replace("\n", "", $in);
  31. }
  32. function init( $station = 0 ) {
  33. $channels = array();
  34. $chandb[0] = file('channels.dvb');
  35. $chandb[1] = count($chandb[0]);
  36. foreach( $chandb[0] as $chan ) {
  37. $channels[] = rmnl(explode(':', $chan));
  38. }
  39. for( $s = 0; $chandb[1] >= $s; $s++ ) {
  40. $channels[$s]['channel'] = $channels[$s][8];
  41. $channels[$s]['frequency'] = $channels[$s][2] . '000';
  42. $channels[$s]['symbols'] = $channels[$s][5] . '000';
  43. if($channels[$s][3] == 'v')
  44. $channels[$s]['voltage'] = 13;
  45. else
  46. $channels[$s]['voltage'] = 18;
  47. }
  48. if( $station > 0 )
  49. return $channels[$station];
  50. else
  51. return $channels;
  52. }
  53. function inerr( $error, $text ) {
  54. if ( $error ) {
  55. echo $text; exit();
  56. } else {
  57. echo $text;
  58. }
  59. }
  60. function channelname( $station, $channels ) {
  61. return $channels[$station][1];
  62. }
  63. function epg( $channel ) {
  64. if( $xml = @simplexml_load_file('epg.xml') ) {
  65. $path ="/tv/programme[@channel='".$channel.".dvb.guide']";
  66. foreach( $xml->xpath($path) as $res ) {
  67. $datetime['start'] = strtotime((string)$res->attributes()->start);
  68. $datetime['stop'] = strtotime((string)$res->attributes()->stop);
  69. if( $datetime['start'] < time() && $datetime['stop'] > time() ) {
  70. $return = array(
  71. 'title' => (string)$res->title,
  72. 'start' => (string)$res->attributes()->start,
  73. 'stop' => (string)$res->attributes()->stop,
  74. 'desc' => (string)$res->desc
  75. );
  76. return $return;
  77. }
  78. }
  79. }
  80. return false;
  81. }
  82. function vlc_status( ) {
  83. // proccess check
  84. $pid = @file_get_contents('vlc.pid');
  85. if( $pid )
  86. $s['s'] = true;
  87. else
  88. $s['s'] = false;
  89. if( $s['s'] ) {
  90. $tuned = @file_get_contents('tuning.dat');
  91. $s['i'] = $tuned;
  92. $s['p'] = $pid;
  93. }
  94. return $s;
  95. }
  96. function exec_vlc( $station, $cmd_http ) {
  97. $status = vlc_status();
  98. if( $status['s'] ) {
  99. kill_vlc( $status['p'] );
  100. }
  101. shell_exec( 'env -i bash -c '.escapeshellarg($cmd_http) );
  102. file_put_contents( 'tuning.dat', $station );
  103. $status = vlc_status();
  104. if( $status['s'] )
  105. return true;
  106. else
  107. return false;
  108. }
  109. function kill_vlc( $pid = 0 ) {
  110. if( !$pid ) {
  111. $status = vlc_status();
  112. $pid = $status['p'];
  113. }
  114. exec( 'kill -9 '.(int)$pid );
  115. unlink( 'vlc.pid' );
  116. sleep( 1 );
  117. $status = vlc_status();
  118. if( !$status['s'] ) {
  119. return true;
  120. }
  121. else {
  122. return false;
  123. }
  124. }
  125. function playlist( $channels ) {
  126. header('Content-type: application/xspf+xml');
  127. header('Content-Disposition: attachment; filename="tv.xspf"');
  128. echo '<?xml version="1.0" encoding="UTF-8"?>' . NL
  129. . '<playlist version="1" xmlns="http://xspf.org/ns/0/">' . NL
  130. . '<trackList>' . NL
  131. . '<track><location>http://'.$_SERVER[HTTP_HOST].':8080</location><title>Last Tuned</title></track>';
  132. foreach( $channels as $num => $c ) {
  133. if( $c[0] != 'TV' && $c[0] != 'RA' ) continue;
  134. echo '<track><location>http://'.$_SERVER[HTTP_HOST].'/frutv/?station=' . $num
  135. . '&amp;playlist=true</location><title>' . $c[0]
  136. . ': ' . htmlspecialchars(utf8_encode($c[1])). '</title></track>'.NL;
  137. }
  138. echo '</trackList></playlist>';
  139. exit();
  140. }
  141. /*
  142. * parameters
  143. */
  144. function cmd( $channel, $frequency, $voltage, $symbols ) {
  145. $cmd_http = '/usr/bin/vlc -d --pidfile vlc.pid --ts-es-id-pid'
  146. . ' --program ' . $channel
  147. . ' --dvb-frequency=' . $frequency
  148. . ' --dvb-adapter=0'
  149. . ' dvb://'
  150. . ' -I telnet --telnet-host 127.0.0.1 --telnet-port 4212 --telnet-password asdfjedn3jdsw3jd'
  151. . ' --dvb-voltage=' . $voltage
  152. . ' --dvb-srate=' . $symbols
  153. . ' --sout \'#duplicate{dst="standard{access'
  154. . '=http,mux=ts,url=lafe.doc.fruky.net:8080/tv},select="program=' . $channel . '"}\' ';
  155. // . ' --sout \'#duplicate{dst="transcode{acodec=mpga, vcodec=mp4v,vb=1600,ab=128,vt=800000,keyint=80,deinterlace}:standard{access'
  156. // . '=http,mux=ts,url=lafe.doc.fruky.net:8080/tv}",select="program=' . $channel . '"}\' ';
  157. return $cmd_http;
  158. }
  159. /*
  160. * main
  161. */
  162. // param
  163. $playlist = $_GET['playlist'];
  164. $station = (int)$_GET['station'];
  165. $stop = $_GET['stop'];
  166. $channels = init( $station );
  167. if( $station > 0 ) {
  168. $cmd = cmd( $channels['channel'],
  169. $channels['frequency'],
  170. $channels['voltage'],
  171. $channels['symbols']);
  172. $status = exec_vlc( $station, $cmd );
  173. if( isset($playlist) ) {
  174. sleep(5); // fix for a slow machine, slow dvb card...
  175. header( 'Location: http://'.$_SERVER[HTTP_HOST].':8080/', true, 303 );
  176. } elseif( $status )
  177. header( 'Location: http://'.$_SERVER[HTTP_HOST].'/frutv/' );
  178. }
  179. elseif( isset($playlist) ) {
  180. playlist( $channels );
  181. }
  182. elseif( isset($stop) ) {
  183. kill_vlc();
  184. header( 'Location: http://'.$_SERVER[HTTP_HOST].'/frutv/' );
  185. }
  186. else {
  187. $status = vlc_status();
  188. $channelname = channelname( $status['i'], $channels );
  189. $channelname = ( $channelname ) ? 'currrent channel: '.$channelname.' (<a href="?stop">stop</a>)' : '';
  190. // default channel list
  191. echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"'.NL
  192. .'"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'.NL
  193. .'<html xmlns="http://www.w3.org/1999/xhtml">'.NL
  194. .' <head>'.NL
  195. .' <title>FruTV</title>'.NL
  196. .' <meta http-equiv="content-type" content="text/html; charset=utf-8" />'.NL
  197. .' <link rel="stylesheet" type="text/css" href="frutv.css" />'.NL
  198. .' <link rel="shortcut icon" type="image/png" href="frutv_ico.png" />'.NL
  199. .' </head>'.NL
  200. .' <body>'.NL;
  201. echo ' <div class="head">FruTV</div>'.NL
  202. .' <p>'.$channelname.'</p>'.NL
  203. .' <p><a href="?playlist">&raquo; playlist</a></p>'.NL
  204. .' <div class="content"><div>'.NL;
  205. foreach($channels as $num => $c) {
  206. if($num == 0) continue;
  207. if(preg_match("/^#/", $c[0])) {
  208. echo '</div><div class="headline">'.preg_replace("/^# /", "", $c[0]).'</div>'.NL
  209. .' <div class="box">'.NL;
  210. }
  211. if($c[0] != 'TV' && $c[0] != 'RA') continue;
  212. $epg = epg( $c[8] ); $epg = $epg['title']; if( empty($epg) ) $epg = "-";
  213. echo ' <div class="box_head"><a href="?station=' . $num . '">' . $c[1] . '</a></div>'.NL
  214. .' <div class="box_content"><div class="box_text">'.$epg.'</div></div>'.NL;
  215. }
  216. echo ' </div></div>'.NL
  217. .' <div class="footer">&copy; FruTV, Frubar Network</div>'.NL
  218. .' </body>'.NL
  219. .'</html>';
  220. }
  221. // vim:syntax=php
  222. ?>