Ticket #12943: 0026-mythweb-add-HTML5-streaming-support-v6.patch
File 0026-mythweb-add-HTML5-streaming-support-v6.patch, 34.6 KB (added by , 6 years ago) |
---|
-
mythplugins/mythweb/includes/utils.php
diff -Naur mythtv-old/mythplugins/mythweb/includes/utils.php mythtv-new/mythplugins/mythweb/includes/utils.php
old new 246 246 case 'flvp': return "$url.flvp"; 247 247 case 'flv' : return "$url.flv"; 248 248 case 'mp4' : return "$url.mp4"; 249 case 'ogv' : return "$url.ogv"; 250 case 'webm': return "$url.webm"; 249 251 } 250 252 // No more dsmyth filters, so return the URL no matter what the browser is. 251 253 return $url; -
mythplugins/mythweb/modules/mythweb/set_flvplayer.php
diff -Naur mythtv-old/mythplugins/mythweb/modules/mythweb/set_flvplayer.php mythtv-new/mythplugins/mythweb/modules/mythweb/set_flvplayer.php
old new 23 23 // Bitrates 24 24 setting('WebFLV_vb', null, $_POST['vbitrate'] > 0 ? $_POST['vbitrate'] : 256); 25 25 setting('WebFLV_ab', null, $_POST['abitrate'] > 0 ? $_POST['abitrate'] : 64); 26 // HTML5 streaming on/off 27 setting('WebHTML5Stream_on', null, $_POST['HTML5stream'] ? 1 : 0); 26 28 27 29 } 28 30 -
mythplugins/mythweb/modules/mythweb/tmpl/default/set_flvplayer.php
diff -Naur mythtv-old/mythplugins/mythweb/modules/mythweb/tmpl/default/set_flvplayer.php mythtv-new/mythplugins/mythweb/modules/mythweb/tmpl/default/set_flvplayer.php
old new 64 64 value="<?php echo html_entities(_or(setting('WebFLV_ab'), 64)) ?>" /> 65 65 kbps</td> 66 66 </tr><tr> 67 <th><?php echo t('HTML5 Streaming') ?>:</th> 68 <td><input class="radio" type="checkbox" name="HTML5stream" 69 title="Enable HTML5 Streaming (with Flash Video as fallback)" 70 <?php if (setting('WebHTML5Stream_on')) echo ' CHECKED' ?>></td> 71 </tr><tr> 67 72 <td align="right"><input type="reset" class="submit" value="<?php echo t('Reset') ?>"></td> 68 73 <td align="center"><input type="submit" class="submit" name="save" value="<?php echo t('Save') ?>"></td> 69 74 </tr> -
mythplugins/mythweb/modules/mythweb/tmpl/lite/set_flvplayer.php
diff -Naur mythtv-old/mythplugins/mythweb/modules/mythweb/tmpl/lite/set_flvplayer.php mythtv-new/mythplugins/mythweb/modules/mythweb/tmpl/lite/set_flvplayer.php
old new 47 47 value="<?php echo html_entities(_or(setting('WebFLV_ab'), 64)) ?>" /> 48 48 kbps</td> 49 49 </tr><tr> 50 <th><?php echo t('HTML5 Streaming') ?>:</th> 51 <td><input class="radio" type="checkbox" name="HTML5stream" 52 title="Enable HTML5 Streaming (with Flash Video as fallback)" 53 <?php if (setting('WebHTML5Stream_on')) echo ' CHECKED' ?>></td> 54 </tr><tr> 50 55 <td align="right"><input type="reset" class="submit" value="<?php echo t('Reset') ?>"></td> 51 56 <td align="center"><input type="submit" class="submit" name="save" value="<?php echo t('Save') ?>"></td> 52 57 </tr> -
mythplugins/mythweb/modules/_shared/lang/English.lang
diff -Naur mythtv-old/mythplugins/mythweb/modules/_shared/lang/English.lang mythtv-new/mythplugins/mythweb/modules/_shared/lang/English.lang
old new 32 32 "%s Songs (%s)" 33 33 "(height is calculated automatically from the recording aspect ratio)" 34 34 "1 - Lowest" 35 "1080" 35 36 "4 - Highest" 37 "720" 36 38 "Aborted" 37 39 "Aborting" 38 40 "Action" 39 41 "Activate" 40 42 "Add" 41 43 "Add Album to Current Playlist" 44 "Add Artist to Current Playlist" 42 45 "Add Mix" 43 46 "Add Song to Current Playlist" 44 47 "add string" … … 49 52 "Advanced" 50 53 "Advanced Options" 51 54 "Advanced Search" 52 "airdate"53 55 "Airdate" 56 "airdate" 54 57 "Airtime" 55 58 "Album Listing" 56 59 "Album Tracks" … … 134 137 "Cancelled" 135 138 "Caps Lock" 136 139 "Cast" 137 "category"138 140 "Category" 141 "category" 139 142 "Category Legend" 140 143 "CC" 141 144 "Chan. Callsign" 142 145 "Chan. Name" 143 146 "Chan. Number" 144 "channel"145 147 "Channel" 148 "channel" 146 149 "Channel "Jump to"" 147 150 "Channel Detail" 148 151 "Channel Info" … … 240 243 "End Late" 241 244 "Enter" 242 245 "Enter a new name for your playlist" 243 "enter your search terms"244 246 "Enter your search terms" 247 "enter your search terms" 245 248 "Episode" 246 249 "Episode Number" 247 250 "Error" … … 310 313 "Hosted by" 311 314 "Hour" 312 315 "Hour Format" 316 "HTML5 Streaming" 313 317 "hue" 314 318 "Identifiable episode" 315 319 "Ignore generic shows" … … 325 329 "info: dont record" 326 330 "info: flvplayer" 327 331 <p> 328 Flash video playback is currently only a proof-of-concept and should be 329 considered <b>EXTREMELY</b> experimental, which is why it has been disabled by 330 default. 331 </p> 332 Video streaming in mythweb is currently based on HTML5 webm/ogg and flash flv. 333 <strong>NOTE</strong>: Today there is no single format supported by all browsers. 334 By this different browsers needs different configuration<br> 335 mythweb provides following streaming support: 336 <ul> 337 <li><strong>Google Chrome:</strong> Highly unstable. Flash fall-back adviced. Uncheck "HTML5 Streaming"</li> 338 <li><strong>Mozilla Firefox:</strong> v57 of Mozilla works well. Enable HTML5 streaming by checking "HTML5 Streaming"</li> 339 <li><strong>Safari (MacOS):</strong> Only Flash fall-back possible so uncheck "HTML5 Streaming"</li> 340 <li><strong>Safati (iOS):</strong> Flash is not supported so no fall-back possible. Use HLS client"</li> 341 <li><strong>IE8 and older:</strong> Only Flash fall-back possible so uncheck "HTML5 Streaming"</li> 342 <li><strong>IE9 and newer:</strong> Highly unstable. Prefer Flash fall-back by unchecking "HTML5 Streaming"</li> 343 </ul> 332 344 <p> 333 It currently expects that ffmpeg is installed and compiled with mp3 334 support, and that the recordings files are accessible to your webserver 335 userid. It probably won't work with Nupplevideo files, and in the end, 336 it may just not work at all (or maybe even worse). 345 This feature expects that myth is build with: libx264, libvpx and libtheora libraries. Also for 346 flash fallback, Adobe Flash player must be installed on client side. 337 347 </p> 338 348 <p> 339 Enable this feature at your own risk, and don't expect too much 340 official help until it has left the experimental phase. 349 Enabling HTML5 streaming may cause not stable streaming as majority browsers (except Mozzilla) 350 offers not good video playabck stability. By this prefered mode is Flash fall-back mode 351 (with "HTML5 Streaming" option disabled). 341 352 </p> 342 353 "info: hidden advanced schedule" 343 354 The advanced scheduling options are currently hidden. … … 358 369 "Internet Reference #" 359 370 "Jump" 360 371 "Jump Points" 361 "Jump to"362 372 "Jump To" 373 "Jump to" 363 374 "JumpPoints Editor" 364 375 "Key Bindings" 365 376 "Key bindings" … … 377 388 "Left" 378 389 "left" 379 390 "leftl" 380 "length"381 391 "Length" 392 "length" 382 393 "Length (min)" 383 394 "Length in minutes" 384 395 "Listing "Jump to"" … … 414 425 "Modify unidentified episodes" 415 426 "Monday" 416 427 "Mono" 417 "more"418 428 "More" 429 "more" 419 430 "Move Item Down in Playlist" 420 431 "Move Item Up in Playlist" 421 432 "movie" … … 423 434 "Movies" 424 435 "Movies, 3½ Stars or more" 425 436 "Movies, Stinkers (2 Stars or less)" 437 "mplexid" 426 438 "Music" 427 439 "Music Specials" 428 440 "My Session" … … 457 469 "New Titles, Premieres" 458 470 "No" 459 471 "NO DATA" 472 "No episodes" 460 473 "No Frontends allow remote control." 461 474 "No Genre" 462 475 "No matches found" … … 515 528 "Play" 516 529 "Play Recording on Frontend" 517 530 "Play this Album Now" 531 "Play this Artist Now" 518 532 "Play This Playlist Now" 519 533 "Play this Playlist Now" 520 534 "Play this Song Now" … … 563 577 "Priority for movies by the year of release" 564 578 "Priority when shown once" 565 579 "Produced by" 566 "profile"567 580 "Profile" 581 "profile" 568 582 "Program Categories" 569 583 "Program Detail" 570 584 "Program ID" … … 582 596 "Rating:" 583 597 "Recently Added Albums" 584 598 "Recently completed jobs" 585 "Recently Played Songs"586 599 "Recently Played Albums" 600 "Recently Played Songs" 587 601 "recgroup" 588 602 "Recommend Videos" 589 603 "Recommended" … … 688 702 "Reset template and skin to defaults" 689 703 "Retry" 690 704 "Return to Statistics Page" 691 "right"692 705 "Right" 706 "right" 693 707 "Root Directory" 694 708 "Rows to show between timeslot info" 695 709 "Running" … … 732 746 "Select the correct show" 733 747 "Server returned invalid data when attempting to retrieve metadata." 734 748 "Server Statistics" 735 "mplexid"736 749 "serviceid" 737 750 "Set Host" 738 "settings"739 751 "Settings" 752 "settings" 740 753 "Settings Table" 741 754 "settings/stream: protocol" 742 755 Many media players are incapable of playing files that are streamed from<br/> … … 829 842 "Toggle Interactive Mode" 830 843 "Too Many" 831 844 "Top $1" 832 "Top Played Songs"833 845 "Top Played Albums" 834 846 "Top Played Artist" 847 "Top Played Songs" 835 848 "Top Rated Songs" 836 849 "Total Length" 837 850 "Total Recorded" … … 849 862 "TV" 850 863 "TV functions, including recorded programs." 851 864 "TV.com" 852 "type"853 865 "Type" 866 "type" 854 867 "Uncategorized" 855 868 "Undelete" 856 869 "Undelete: $1" -
mythplugins/mythweb/modules/_shared/lang/Polish.lang
diff -Naur mythtv-old/mythplugins/mythweb/modules/_shared/lang/Polish.lang mythtv-new/mythplugins/mythweb/modules/_shared/lang/Polish.lang
old new 44 44 "%s Songs (%s)" 45 45 "(height is calculated automatically from the recording aspect ratio)" 46 46 "1 - Lowest" 47 "1080" 47 48 "4 - Highest" 49 "720" 48 50 "Aborted" 49 51 "Aborting" 50 52 "Action" … … 53 55 Uaktywnij 54 56 "Add" 55 57 "Add Album to Current Playlist" 58 "Add Artist to Current Playlist" 56 59 "Add Mix" 57 60 "Add Song to Current Playlist" 58 61 "add string" … … 66 69 Zaawansowane opcje 67 70 "Advanced Search" 68 71 Szukanie zaawansowane 69 "airdate"70 72 "Airdate" 73 "airdate" 71 74 "Airtime" 72 75 "Album Listing" 73 76 "Album Tracks" … … 162 165 "Caps Lock" 163 166 "Cast" 164 167 Obsada 165 "category"166 kategoria167 168 "Category" 168 169 Kategoria 170 "category" 171 kategoria 169 172 "Category Legend" 170 173 Legenda kategorie 171 174 "CC" … … 228 231 "Custom Schedule" 229 232 "Custom Search" 230 233 "Customize Screens" 234 "Damaged" 231 235 "Data" 232 236 Dane 233 237 "Database" … … 258 262 "DELETE this Saved Playlist" 259 263 "DeleteKey" 260 264 "Depending on the Search type this is where you enter actual main search commands" 261 "description"262 opis263 265 "Description" 264 266 Opis 267 "description" 268 opis 265 269 "Destination" 266 270 Cel 267 271 "Details for: $1" … … 379 383 Godzina 380 384 "Hour Format" 381 385 Format godziny 386 "HTML5 Streaming" 382 387 "hue" 383 388 kolor 384 389 "Identifiable episode" … … 392 397 "info: default recording" 393 398 "info: dont record" 394 399 "info: flvplayer" 400 <p> 401 Video streaming in mythweb is currently based on HTML5 webm/ogg and flash flv. 402 <strong>NOTE</strong>: Today there is no single format supported by all browsers.. 403 By this different browsers needs different configuration<br> 404 mythweb provides following streaming support: 405 <ul> 406 <li><strong>Google Chrome:</strong> Highly unstable. Flash fall-back adviced. Uncheck "HTML5 Streaming"</li> 407 <li><strong>Mozilla Firefox:</strong> v52.0 or newer is stable and plays perfectly. Enable HTML5 streaming by checking "HTML5 Streaming"</li> 408 <li><strong>Safari (MacOS):</strong> Only Flash fall-back possible so uncheck "HTML5 Streaming"</li> 409 <li><strong>Safati (iOS):</strong> Flash is not supported so no fall-back possible. Use HLS client"</li> 410 <li><strong>IE8 and older:</strong> Only Flash fall-back possible so uncheck "HTML5 Streaming"</li> 411 <li><strong>IE9 and newer:</strong> Highly unstable. Prefer Flash fall-back by unchecking "HTML5 Streaming"</li> 412 </ul> 413 <p> 414 This feature expects that myth is build with libx264, libvpx and libtheora libraries. Also for 415 flash fallback, Adobe Flash player must be installed on client side. 416 </p> 417 <p> 418 Enabling HTML5 streaming may cause not stable streaming as majority browsers (except Mozzilla). 419 offers not good video playabck stability. By this prefered mode is Flash fall-back mode. 420 (with "HTML5 Streaming" option disabled). 421 </p> 395 422 "info: hidden advanced schedule" 396 423 "info: record this" 397 424 "info:forget old" … … 403 430 "Jump" 404 431 Skocz 405 432 "Jump Points" 406 "Jump to"407 Skocz do408 433 "Jump To" 409 434 Skocz Do 435 "Jump to" 436 Skocz do 410 437 "JumpPoints Editor" 411 438 "Key Bindings" 412 439 "Key bindings" … … 423 450 "Last recording" 424 451 "Last showing of each episode" 425 452 "Later" 426 "left"427 453 "Left" 454 "left" 428 455 "leftl" 429 "length"430 dÅugoÅÄ431 456 "Length" 432 457 DÅugoÅÄ 458 "length" 459 dÅugoÅÄ 433 460 "Length (min)" 434 461 Czas trwania (minut): 435 462 "Length in minutes" … … 463 490 "Missing Cover" 464 491 "Modify priority by star rating (0.0 to 1.0 for movies only)" 465 492 "Modify priority for a station on an input" 466 "Modify priority for all inputs on a card"467 493 "Modify priority for an input (Input priority)" 468 494 "Modify priority for every card on a host" 469 495 "Modify unidentified episodes" … … 481 507 "Movies, 3½ Stars or more" 482 508 Filmy 3½ gwiazdy lub wiÄcej 483 509 "Movies, Stinkers (2 Stars or less)" 510 "mplexid" 484 511 "Music" 485 512 Muzyka 486 513 "Music Specials" … … 520 547 Nowe tytuÅy, premiery 521 548 "No" 522 549 "NO DATA" 550 "No episodes" 523 551 "No Frontends allow remote control." 524 552 "No Genre" 525 553 "No matches found" … … 579 607 "Play" 580 608 "Play Recording on Frontend" 581 609 "Play this Album Now" 610 "Play this Artist Now" 582 611 "Play This Playlist Now" 583 612 "Play this Playlist Now" 584 613 "Play this Song Now" … … 649 678 "Rating:" 650 679 "Recently Added Albums" 651 680 "Recently completed jobs" 681 "Recently Played Albums" 652 682 "Recently Played Songs" 653 683 "recgroup" 654 684 "Recommend Videos" … … 764 794 "Reset template and skin to defaults" 765 795 "Retry" 766 796 "Return to Statistics Page" 767 "right"768 797 "Right" 798 "right" 769 799 "Root Directory" 770 800 "Rows to show between timeslot info" 771 801 "Running" … … 820 850 "Server returned invalid data when attempting to retrieve metadata." 821 851 "Server Statistics" 822 852 "serviceid" 823 "mplexid"824 853 "Set Host" 825 854 "Settings" 826 855 Ustawienia … … 909 938 "Time Span" 910 939 "Time Stretch" 911 940 "Timeslot size" 912 "title"913 tytuÅ914 941 "Title" 915 942 TytuÅ 943 "title" 944 tytuÅ 916 945 "Title Match" 917 "Title search"918 946 "Title Search" 919 947 Szukanie TytuÅu 948 "Title search" 920 949 "Title Search:" 921 950 "Title:" 922 951 "Toggle Interactive Mode" 923 952 "Too Many" 924 953 "Top $1" 925 954 Szczyt $1 955 "Top Played Albums" 956 "Top Played Artist" 926 957 "Top Played Songs" 927 958 "Top Rated Songs" 928 959 "Total Length" … … 932 963 CaÅkowity Czas 933 964 "Total Time: %s" 934 965 "Track #%s from the album '%s'" 966 "Trakt.tv Home Page" 935 967 "Transcode" 936 968 "Transcoded" 937 "transcoder"938 969 "Transcoder" 970 "transcoder" 939 971 "Tuesday" 940 972 Wtorek 941 973 "Tuner Busy" 942 974 "TV" 943 975 "TV functions, including recorded programs." 944 976 "TV.com" 945 "type"946 typ947 977 "Type" 948 978 Typ 979 "type" 980 typ 949 981 "Uncategorized" 950 982 "Undelete" 951 983 "Undelete: $1" -
mythplugins/mythweb/modules/stream/handler.pl
diff -Naur mythtv-old/mythplugins/mythweb/modules/stream/handler.pl mythtv-new/mythplugins/mythweb/modules/stream/handler.pl
old new 12 12 13 13 require "modules/$Path[0]/tv.pl"; 14 14 15 # Use the MythTV Services API URL if the $filename URL is not local 15 16 unless ($filename) { 16 print header(), 17 "$basename does not exist in any recognized storage group directories for this host."; 18 exit; 17 # Retrieve the backend IP and port 18 $sh = $dbh->prepare('SELECT data FROM settings WHERE value=?'); 19 $sh->execute('BackendServerIP'); 20 my ($backend_server_ip) = $sh->fetchrow_array; 21 $sh->execute('BackendStatusPort'); 22 my ($backend_status_port) = $sh->fetchrow_array; 23 $sh->finish(); 24 25 # Reformat the recording start time 26 use HTTP::Date qw(time2isoz); 27 $starttime_isoz = time2isoz($starttime); 28 $starttime_isoz =~ s/ /T/g; 29 30 # Generate the MythTV Services API URL 31 $filename = "http://${backend_server_ip}:${backend_status_port}/Content/GetRecording?ChanId=${chanid}&StartTime=${starttime_isoz}"; 19 32 } 20 33 34 # HTML5 video/ogv 35 if ($ENV{'REQUEST_URI'} =~ /\.ogv$/i) { 36 require "modules/$Path[0]/stream_ogv.pl"; 37 } 38 # HTML5 video/webm 39 elsif ($ENV{'REQUEST_URI'} =~ /\.webm$/i) { 40 require "modules/$Path[0]/stream_webm.pl"; 41 } 21 42 # ASX mode? 22 if ($ENV{'REQUEST_URI'} =~ /\.asx$/i) {43 elsif ($ENV{'REQUEST_URI'} =~ /\.asx$/i) { 23 44 require "modules/$Path[0]/stream_asx.pl"; 24 45 } 25 46 # Flash? -
mythplugins/mythweb/modules/stream/stream_ogv.pl
diff -Naur mythtv-old/mythplugins/mythweb/modules/stream/stream_ogv.pl mythtv-new/mythplugins/mythweb/modules/stream/stream_ogv.pl
old new 1 #!/usr/bin/perl 2 # 3 # MythWeb Streaming/Download module 4 # 5 # @url $URL$ 6 # @date $2016/11/23$ 7 # @version $v1.0$ 8 # @author $Piotr Oniszczuk$ 9 # 10 11 use POSIX qw(ceil floor); 12 13 # round to the nearest even integer 14 sub round_even { 15 my ($in) = @_; 16 my $n = floor($in); 17 return ($n % 2 == 0) ? $n : ceil($in); 18 } 19 20 our $ffmpeg_pid; 21 our $ffmpeg_pgid; 22 23 # Shutdown cleanup 24 $ffmpeg_pgid = setpgrp(0,0); 25 $SIG{'TERM'} = \&shutdown_handler; 26 $SIG{'PIPE'} = \&shutdown_handler; 27 END { 28 shutdown_handler(); 29 } 30 sub shutdown_handler { 31 kill(1, $ffmpeg_pid) if ($ffmpeg_pid); 32 kill(-1, $ffmpeg_pid) if ($ffmpeg_pid); 33 } 34 35 # Find ffmpeg 36 $ffmpeg = ''; 37 foreach my $path (split(/:/, $ENV{'PATH'}.':/usr/local/bin:/usr/bin'), '.') { 38 if (-e "$path/mythffmpeg") { 39 $ffmpeg = "$path/mythffmpeg"; 40 last; 41 } 42 if (-e "$path/ffmpeg") { 43 $ffmpeg = "$path/ffmpeg"; 44 last; 45 } 46 elsif ($^O eq 'darwin' && -e "$path/ffmpeg.app") { 47 $ffmpeg = "$path/ffmpeg.app"; 48 last; 49 } 50 } 51 52 # Load some conversion settings from the database 53 $sh = $dbh->prepare('SELECT data FROM settings WHERE value=? AND hostname IS NULL'); 54 $sh->execute('WebFLV_w'); 55 my ($width) = $sh->fetchrow_array; 56 $sh->execute('WebFLV_vb'); 57 my ($vbitrate) = $sh->fetchrow_array; 58 $sh->execute('WebFLV_ab'); 59 my ($abitrate) = $sh->fetchrow_array; 60 $sh->finish(); 61 62 # auto-detect height based on aspect ratio 63 $sh = $dbh->prepare('SELECT data FROM recordedmarkup WHERE chanid=? ' . 64 'AND starttime=FROM_UNIXTIME(?) AND type=30 ' . 65 'AND data IS NOT NULL ORDER BY mark LIMIT 1'); 66 $sh->execute($chanid,$starttime); 67 $x = $sh->fetchrow_array; # type = 30 68 $sh->finish(); 69 70 $sh = $dbh->prepare('SELECT data FROM recordedmarkup WHERE chanid=? ' . 71 'AND starttime=FROM_UNIXTIME(?) AND type=31 ' . 72 'AND data IS NOT NULL ORDER BY mark LIMIT 1'); 73 $sh->execute($chanid,$starttime); 74 $y = $sh->fetchrow_array if ($x); # type = 31 75 $sh->finish(); 76 77 if (!$x || !$y || $x <= 720) { # <=720 means SD 78 $sh = $dbh->prepare('SELECT recordedmarkup.type, ' . 79 'recordedmarkup.data '. 80 'FROM recordedmarkup ' . 81 'WHERE recordedmarkup.chanid = ? ' . 82 'AND recordedmarkup.starttime = FROM_UNIXTIME(?) ' . 83 'AND recordedmarkup.type IN (10, 11, 12, 13, 14) ' . 84 'GROUP BY recordedmarkup.type ' . 85 'ORDER BY SUM((SELECT IFNULL(rm.mark, recordedmarkup.mark) ' . 86 ' FROM recordedmarkup AS rm ' . 87 ' WHERE rm.chanid = recordedmarkup.chanid ' . 88 ' AND rm.starttime = recordedmarkup.starttime ' . 89 ' AND rm.type IN (10, 11, 12, 13, 14) ' . 90 ' AND rm.mark > recordedmarkup.mark ' . 91 ' ORDER BY rm.mark ASC LIMIT 1)- recordedmarkup.mark) DESC ' . 92 'LIMIT 1'); 93 $sh->execute($chanid,$starttime); 94 $aspect = $sh->fetchrow_hashref; 95 $sh->finish(); 96 97 if( $aspect->{'type'} ) { 98 if( $aspect->{'type'} == 10 ) { 99 $x = $y = 1; 100 } elsif( $aspect->{'type'}== 11 ) { 101 $x = 4; $y = 3; 102 } elsif( $aspect->{'type'}== 12 ) { 103 $x = 16; $y = 9; 104 } elsif( $aspect->{'type'}== 13 ) { 105 $x = 2.21; $y = 1; 106 } elsif( $aspect->{'type'}== 14 ) { 107 $x = $aspect->{'data'}; $y = 1000000; 108 } else { 109 $x = 4; $y = 3; 110 } 111 } 112 else { 113 $x = 4; $y = 3; 114 } 115 116 } 117 $height = round_even($width * ($y/$x)); 118 119 $width = 320 unless ($width && $width > 1); 120 $height = 240 unless ($height && $height > 1); 121 $vbitrate = 256 unless ($vbitrate && $vbitrate > 1); 122 $abitrate = 64 unless ($abitrate && $abitrate > 1); 123 124 # build appropriate encoder commad 125 my $ffmpeg_command = $ffmpeg 126 .' -y' 127 .' -i '.shell_escape("$filename") 128 .' -s '.shell_escape("${width}x${height}") 129 .' -g 30' 130 .' -r 24' 131 .' -f ogg' 132 .' -codec:a vorbis' 133 .' -codec:v libtheora' 134 .' -strict -2' 135 .' -deinterlace' 136 .' -async 2' 137 .' -ac 2' 138 .' -ar 44100' 139 .' -b:a '.shell_escape("${abitrate}k") 140 .' -b:v '.shell_escape("${vbitrate}k") 141 .' -sn' 142 .' /dev/stdout 2>/var/log/mythweb-streaming-ogg.log |'; 143 144 # start to encode content 145 $ffmpeg_pid = open(DATA, $ffmpeg_command); 146 unless ($ffmpeg_pid) { 147 print header(), 148 "Can't execute ffmpeg. Command was: $!\n${ffmpeg_command}"; 149 exit; 150 } 151 152 # Guess the filesize based on duration and bitrate. This allows progressive download. Print header with 153 # guessed file size 154 my $lengthSec; 155 my $length; 156 my $range; 157 $dur = `$ffmpeg -i $filename 2>&1 | /usr/bin/grep "Duration" | /usr/bin/cut -d ' ' -f 4 | /bin/sed s/,//`; 158 if ($dur && $dur =~ /\d*:\d*:.*/) { 159 @times = split(':',$dur); 160 $lengthSec = $times[0]*3600+$times[1]*60+$times[2]; 161 $length = int($lengthSec); 162 $size = int(0.85*$lengthSec*($vbitrate*1024+$abitrate*1024)/8); 163 $range = $size-1; 164 print header(-type => 'video/ogg', 165 -Content_length => $size, 166 -Accept_Ranges => 'bytes', 167 -Timing_Allow_Origin => '*', 168 -Content_Duration => $length, 169 -Content_Range => 'bytes 0-'.$range.'/'.$size, 170 -X_Content_Duration => $length 171 ); 172 } else { 173 print header(-type => 'video/ogg'); 174 175 } 176 177 if ($ENV{'REQUEST_METHOD'} eq 'HEAD') { 178 exit; 179 } 180 181 # send encoded data to browser 182 my $buffer; 183 while (read DATA, $buffer, 262144) { 184 unless (print $buffer ) { 185 last; 186 } 187 } 188 189 close DATA; 190 -
mythplugins/mythweb/modules/stream/stream_webm.pl
diff -Naur mythtv-old/mythplugins/mythweb/modules/stream/stream_webm.pl mythtv-new/mythplugins/mythweb/modules/stream/stream_webm.pl
old new 1 #!/usr/bin/perl 2 # 3 # MythWeb Streaming/Download module 4 # 5 # @url $URL$ 6 # @date $2016/11/23$ 7 # @version $v1.0$ 8 # @author $Piotr Oniszczuk$ 9 # 10 11 use POSIX qw(ceil floor); 12 13 # round to the nearest even integer 14 sub round_even { 15 my ($in) = @_; 16 my $n = floor($in); 17 return ($n % 2 == 0) ? $n : ceil($in); 18 } 19 20 our $ffmpeg_pid; 21 our $ffmpeg_pgid; 22 23 # Shutdown cleanup 24 $ffmpeg_pgid = setpgrp(0,0); 25 $SIG{'TERM'} = \&shutdown_handler; 26 $SIG{'PIPE'} = \&shutdown_handler; 27 END { 28 shutdown_handler(); 29 } 30 sub shutdown_handler { 31 kill(1, $ffmpeg_pid) if ($ffmpeg_pid); 32 kill(-1, $ffmpeg_pid) if ($ffmpeg_pid); 33 } 34 35 # Find ffmpeg 36 $ffmpeg = ''; 37 foreach my $path (split(/:/, $ENV{'PATH'}.':/usr/local/bin:/usr/bin'), '.') { 38 if (-e "$path/mythffmpeg") { 39 $ffmpeg = "$path/mythffmpeg"; 40 last; 41 } 42 if (-e "$path/ffmpeg") { 43 $ffmpeg = "$path/ffmpeg"; 44 last; 45 } 46 elsif ($^O eq 'darwin' && -e "$path/ffmpeg.app") { 47 $ffmpeg = "$path/ffmpeg.app"; 48 last; 49 } 50 } 51 52 # Load some conversion settings from the database 53 $sh = $dbh->prepare('SELECT data FROM settings WHERE value=? AND hostname IS NULL'); 54 $sh->execute('WebFLV_w'); 55 my ($width) = $sh->fetchrow_array; 56 $sh->execute('WebFLV_vb'); 57 my ($vbitrate) = $sh->fetchrow_array; 58 $sh->execute('WebFLV_ab'); 59 my ($abitrate) = $sh->fetchrow_array; 60 $sh->finish(); 61 62 # auto-detect height based on aspect ratio 63 $sh = $dbh->prepare('SELECT data FROM recordedmarkup WHERE chanid=? ' . 64 'AND starttime=FROM_UNIXTIME(?) AND type=30 ' . 65 'AND data IS NOT NULL ORDER BY mark LIMIT 1'); 66 $sh->execute($chanid,$starttime); 67 $x = $sh->fetchrow_array; # type = 30 68 $sh->finish(); 69 70 $sh = $dbh->prepare('SELECT data FROM recordedmarkup WHERE chanid=? ' . 71 'AND starttime=FROM_UNIXTIME(?) AND type=31 ' . 72 'AND data IS NOT NULL ORDER BY mark LIMIT 1'); 73 $sh->execute($chanid,$starttime); 74 $y = $sh->fetchrow_array if ($x); # type = 31 75 $sh->finish(); 76 77 if (!$x || !$y || $x <= 720) { # <=720 means SD 78 $sh = $dbh->prepare('SELECT recordedmarkup.type, ' . 79 'recordedmarkup.data '. 80 'FROM recordedmarkup ' . 81 'WHERE recordedmarkup.chanid = ? ' . 82 'AND recordedmarkup.starttime = FROM_UNIXTIME(?) ' . 83 'AND recordedmarkup.type IN (10, 11, 12, 13, 14) ' . 84 'GROUP BY recordedmarkup.type ' . 85 'ORDER BY SUM((SELECT IFNULL(rm.mark, recordedmarkup.mark) ' . 86 ' FROM recordedmarkup AS rm ' . 87 ' WHERE rm.chanid = recordedmarkup.chanid ' . 88 ' AND rm.starttime = recordedmarkup.starttime ' . 89 ' AND rm.type IN (10, 11, 12, 13, 14) ' . 90 ' AND rm.mark > recordedmarkup.mark ' . 91 ' ORDER BY rm.mark ASC LIMIT 1)- recordedmarkup.mark) DESC ' . 92 'LIMIT 1'); 93 $sh->execute($chanid,$starttime); 94 $aspect = $sh->fetchrow_hashref; 95 $sh->finish(); 96 97 if( $aspect->{'type'} ) { 98 if( $aspect->{'type'} == 10 ) { 99 $x = $y = 1; 100 } elsif( $aspect->{'type'}== 11 ) { 101 $x = 4; $y = 3; 102 } elsif( $aspect->{'type'}== 12 ) { 103 $x = 16; $y = 9; 104 } elsif( $aspect->{'type'}== 13 ) { 105 $x = 2.21; $y = 1; 106 } elsif( $aspect->{'type'}== 14 ) { 107 $x = $aspect->{'data'}; $y = 1000000; 108 } else { 109 $x = 4; $y = 3; 110 } 111 } 112 else { 113 $x = 4; $y = 3; 114 } 115 } 116 $height = round_even($width * ($y/$x)); 117 118 $width = 320 unless ($width && $width > 1); 119 $height = 240 unless ($height && $height > 1); 120 $vbitrate = 256 unless ($vbitrate && $vbitrate > 1); 121 $abitrate = 64 unless ($abitrate && $abitrate > 1); 122 123 # build appropriate encoder commad 124 my $ffmpeg_command = $ffmpeg 125 .' -y' 126 .' -i '.shell_escape("$filename") 127 .' -s '.shell_escape("${width}x${height}") 128 .' -g 30' 129 .' -r 24' 130 .' -f webm' 131 .' -codec:a vorbis' 132 .' -codec:v libvpx' 133 .' -cpu-used -8' 134 .' -deadline realtime' 135 .' -strict -2' 136 .' -deinterlace' 137 .' -async 2' 138 .' -ac 2' 139 .' -ar 44100' 140 .' -b:a '.shell_escape("${abitrate}k") 141 .' -b:v '.shell_escape("${vbitrate}k") 142 .' -sn' 143 .' /dev/stdout 2>/var/log/mythweb-streaming-webm.log |'; 144 145 # start to encode content 146 $ffmpeg_pid = open(DATA, $ffmpeg_command); 147 unless ($ffmpeg_pid) { 148 print header(), 149 "Can't execute ffmpeg. Command was: $!\n${ffmpeg_command}"; 150 exit; 151 } 152 153 # Guess the filesize based on duration and bitrate. This allows progressive download. Print header with 154 # guessed file size 155 my $lengthSec; 156 my $length; 157 my $range; 158 $dur = `$ffmpeg -i $filename 2>&1 | /usr/bin/grep "Duration" | /usr/bin/cut -d ' ' -f 4 | /bin/sed s/,//`; 159 if ($dur && $dur =~ /\d*:\d*:.*/) { 160 @times = split(':',$dur); 161 $lengthSec = $times[0]*3600+$times[1]*60+$times[2]; 162 $length = int($lengthSec); 163 $size = int(0.90*$lengthSec*($vbitrate*1024+$abitrate*1024)/8); 164 $range = $size-1; 165 print header(-type => 'video/webm', 166 -Content_length => $size, 167 -Accept_Ranges => 'bytes', 168 -Timing_Allow_Origin => '*', 169 -Content_Duration => $length, 170 -Content_Range => 'bytes 0-'.$range.'/'.$size, 171 -X_Content_Duration => $length 172 ); 173 } else { 174 print header(-type => 'video/webm'); 175 176 } 177 178 if ($ENV{'REQUEST_METHOD'} eq 'HEAD') { 179 exit; 180 } 181 182 # send encoded data to browser 183 my $buffer; 184 while (read DATA, $buffer, 262144) { 185 unless (print $buffer ) { 186 last; 187 } 188 } 189 190 close DATA; 191 -
mythplugins/mythweb/modules/tv/tmpl/default/detail.php
diff -Naur mythtv-old/mythplugins/mythweb/modules/tv/tmpl/default/detail.php mythtv-new/mythplugins/mythweb/modules/tv/tmpl/default/detail.php
old new 37 37 <script type="text/javascript"> 38 38 <!-- 39 39 40 // Android devices need the following to play HTML5 video. Taken from ticket #10529 41 var video = document.getElementById('video'); 42 video.addEventListener('click', function(){ 43 video.play(); 44 }, false); 45 40 46 // Keep track of the autoexpire flag 41 47 var autoexpire = <?php echo $program->auto_expire ? 1 : 0 ?>; 42 48 … … 665 671 666 672 <div class="x-pixmap"> 667 673 <?php if (setting('WebFLV_on')) { ?> 674 <?php if (setting('WebHTML5Stream_on')) { ?> 675 <video id="video" controls="controls" preload="metadata" width="<?php echo $flv_w ?>" height="<?php echo $flv_h ?>" poster="<?php echo $program->thumb_url($flv_w,0) ?>"> 676 <source src="<?php echo video_url($program, 'webm'); ?>" type="video/webm" /> 677 <source src="<?php echo video_url($program, 'ogv'); ?>" type="video/ogg" /> 678 <?php } ?> 668 679 <?php if (file_exists('js/libs/flowplayer/flowplayer.swf')) { ?> 669 670 671 <!-- this A tag is where your Flowplayer will be placed. it can be anywhere --> 672 <a href="" 673 style="display:block;width:<?php echo $flv_w ?>px;height:<?php echo $flv_h ?>px" 674 id="player"> 675 </a> 676 677 <!-- this will install flowplayer inside previous A- tag. --> 678 <script> 679 flowplayer( 680 "player", 681 "<?php echo root_url ?>js/libs/flowplayer/flowplayer.swf", { 682 playlist: [ 680 <a href="" style="display:block;width:<?php echo $flv_w ?>px;height:<?php echo $flv_h ?>px" id="flash-player"></a> 681 <script> 682 flowplayer("flash-player","<?php echo root_url ?>js/libs/flowplayer/flowplayer.swf", { 683 playlist: [ 683 684 // this first PNG clip works as a splash image 684 685 { 685 686 url: '<?php echo $program->thumb_url($flv_w,0) ?>', 686 687 scaling: 'orig' 687 688 }, 688 689 // Then we have the video 689 690 { 690 691 url: "<?php echo video_url($program, 'flv'); ?>", … … 694 695 // Would be nice to auto-buffer, but we don't want to 695 696 // waste bandwidth and CPU on the remote machine. 696 697 autoBuffering: false 697 698 } 698 699 ]} 699 700 ); 700 </script>701 </script> 701 702 <?php } elseif (file_exists('modules/tv/MFPlayer.swf')) { ?> 702 703 <script language="JavaScript" type="text/javascript"> 703 704 <!-- … … 813 814 <?php } else { ?> 814 815 <a href="<?php echo $program->url ?>" title="<?php echo t('Direct Download') ?>" 815 816 ><img src="<?php echo $program->thumb_url($flv_w,0) ?>" width="<?php echo $flv_w ?>"></a> 816 <?php } ?></td> 817 <?php } ?> 818 <?php if (setting('WebHTML5Stream_on')) { ?> 819 </video> 820 <?php } ?> 821 822 </td> 817 823 </div> 818 824 <div class="x-links"> 819 825 <a href="<?php echo video_url($program, 'asx') ?>" title="<?php echo t('ASX Stream') ?>" -
mythplugins/mythweb/mythweb.conf.apache
diff -Naur mythtv-old/mythplugins/mythweb/mythweb.conf.apache mythtv-new/mythplugins/mythweb/mythweb.conf.apache
old new 194 194 # those are, so we should tell it. 195 195 AddType video/nuppelvideo .nuv 196 196 197 # Support HTML5 video formats which can be encoded and streamed "on-the-fly" 198 AddType video/ogg .ogv .ogg 199 AddType video/webm .webm 200 197 201 # Specify the MIME type for favicon.ico in case the server configuration 198 202 # doesn't or in case the server configuration uses the IANA-approved MIME type 199 203 # (image/vnd.microsoft.icon)--which most browsers won't recognize.