Play file in browser or with external helper application
Create a new `play.jim` in html/browse. The `/play` subtree is now obsolete and can be removed. Fix DLNA playback on HDR `urlbase` is the host name Remove typos (missing }s, $) Make new file 'play.jim' executable
This commit is contained in:
parent
e79e85af81
commit
f032f8b469
|
@ -13,10 +13,14 @@ if {$file == 0} exit
|
|||
|
||||
set sz [pretty_size [file size $file]]
|
||||
|
||||
set flags {}
|
||||
set url ""
|
||||
|
||||
# assumption: the type is only ts if fetch has already been checked
|
||||
if {$type eq "ts"} {
|
||||
require epg.class ts.class
|
||||
|
||||
set ts [ts fetch $file]
|
||||
set ts [ts fetch $file 1]
|
||||
|
||||
# Causes other series information to be automatically populated
|
||||
set epname [$ts episode_name]
|
||||
|
@ -199,7 +203,7 @@ eval_plugins browsetsfile
|
|||
|
||||
puts "<tr>
|
||||
<th>Flags</th>
|
||||
<td>[$ts get flags]</td>
|
||||
<td>[set flags [$ts get flags]]</td>
|
||||
</tr>
|
||||
"
|
||||
|
||||
|
@ -215,9 +219,6 @@ if {[$ts get bookmarks]} {
|
|||
"
|
||||
}
|
||||
|
||||
puts "
|
||||
</table>
|
||||
"
|
||||
puts "<div class=hidden id=file>$file</div>"
|
||||
puts {
|
||||
<script type=text/javascript>
|
||||
|
@ -256,12 +257,12 @@ $('img.rollimg').hover(
|
|||
|
||||
</script>
|
||||
}
|
||||
exit
|
||||
}
|
||||
|
||||
# Otherwise, for a general file.
|
||||
|
||||
puts "
|
||||
if {$type ne "ts"} {
|
||||
puts "
|
||||
<table class=keyval>
|
||||
<tr>
|
||||
<th>File</th>
|
||||
|
@ -269,20 +270,29 @@ puts "
|
|||
</tr><tr>
|
||||
<th>Size</th>
|
||||
<td>$sz</td>
|
||||
</tr><tr>
|
||||
</tr>"
|
||||
}
|
||||
|
||||
set hasffmpeg 0
|
||||
if {$type ne "ts" || ("ODEncrypted" ni $flags && $url eq "") } {
|
||||
puts "<tr>
|
||||
<th>Info</th>
|
||||
<td class=pre id=ffmpeg>
|
||||
<img src=/img/spin.gif><i>Loading...</i>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
"
|
||||
</tr>"
|
||||
set hasffmpeg 1
|
||||
}
|
||||
puts "
|
||||
</table>
|
||||
"
|
||||
|
||||
set url "/browse/ffmpeg.jim?file=[cgi_quote_url $file]"
|
||||
puts { <script type="text/javascript"> }
|
||||
puts "var url = \"$url\";"
|
||||
puts {
|
||||
$('#ffmpeg').load(url);
|
||||
if {$hasffmpeg} {
|
||||
set url "/browse/ffmpeg.jim?file=[cgi_quote_url $file]"
|
||||
puts { <script type="text/javascript"> }
|
||||
puts "var url = \"$url\";"
|
||||
puts {
|
||||
$('#ffmpeg').load(url, function() { $('#play').button('enable'); });
|
||||
</script>
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
#!/mod/bin/jimsh
|
||||
|
||||
package require cgi
|
||||
source /mod/webif/lib/setup
|
||||
require system.class
|
||||
require ts.class
|
||||
|
||||
set file [cgi_get file]
|
||||
set urlbase [cgi_get base ""]
|
||||
set duration [cgi_get duration 1]
|
||||
set fmts [split [cgi_get fmts ""] ","]
|
||||
set vc [cgi_get vc ""]
|
||||
|
||||
# Default to just downloading the raw file.
|
||||
set url $file
|
||||
|
||||
# Prefer to use DLNA server ... (necessary if encrypted)
|
||||
set dlna [system dlnaurl $url $urlbase]
|
||||
if {[llength $dlna]} {
|
||||
set url [lindex $dlna 0]
|
||||
} elseif {[regexp {^(https?://(.+:.*@)?[[:alnum:].]+(:[[:digit:]]+)?)/} $urlbase x y]} {
|
||||
set url "$y$url"
|
||||
} else {
|
||||
set url "http://[system ip]$url"
|
||||
}
|
||||
|
||||
if {[file extension $file] in {.ts .TS}} {
|
||||
if {![catch {set ts [ts fetch $file]}] && $ts != 0} {
|
||||
set duration [$ts duration 1]
|
||||
}
|
||||
}
|
||||
|
||||
set file [file tail $file]
|
||||
set playlist [file tempfile "[env "TMPDIR" [env "TMP" "/tmp"]]/playXXXXXX"]
|
||||
set pl ""
|
||||
try {
|
||||
set pl [open $playlist w]
|
||||
$pl puts "#EXTM3U"
|
||||
$pl puts "#EXTINF:$duration,$file"
|
||||
$pl puts "#PLAYLIST:$file"
|
||||
$pl puts $url
|
||||
} finally {
|
||||
if {$pl ne ""} {
|
||||
$pl close
|
||||
}
|
||||
}
|
||||
|
||||
httpheader "application/x-mpegurl" 0 [list \
|
||||
"Content-Disposition" "attachment; filename=\"[file rootname $file].m3u\"" \
|
||||
"Content-Length" "[file size $playlist]" \
|
||||
]
|
||||
set pl ""
|
||||
try {
|
||||
set pl [open $playlist r]
|
||||
$pl copyto stdout
|
||||
} finally {
|
||||
if {$pl ne ""} {
|
||||
$pl close
|
||||
}
|
||||
}
|
||||
catch {file delete $playlist}
|
||||
|
|
@ -787,12 +787,14 @@ $('img.doopt').contextMenu(
|
|||
// Disable items which are not yet implemented.
|
||||
$('#optmenu').disableContextMenuItems('#title');
|
||||
|
||||
var $buttons = {
|
||||
"Close" : function() {$(this).dialog('close');}
|
||||
};
|
||||
var $buttonsp = $.extend(
|
||||
{"Play" : function() { doplay(); }},
|
||||
$buttons);
|
||||
var $buttons = [
|
||||
{ id: 'close',
|
||||
text: 'Close',
|
||||
click: function() {$(this).dialog('close');}},
|
||||
{ id: 'play',
|
||||
text: 'Play',
|
||||
click: function() { doplay(this); }}
|
||||
];
|
||||
|
||||
// Create reusable dialogue.
|
||||
var $dialog = $('#dialogue').dialog({
|
||||
|
@ -806,16 +808,47 @@ var $dialog = $('#dialogue').dialog({
|
|||
'<img src="/img/spin.gif">Retrieving data...'); }
|
||||
});
|
||||
|
||||
function doplay()
|
||||
function doplay(it)
|
||||
{
|
||||
var file = $dialog.attr('file');
|
||||
var type = $dialog.attr('type');
|
||||
|
||||
disableall();
|
||||
var duration = 0;
|
||||
var fmts = "";
|
||||
var vc = ""
|
||||
var ff = $('#ffmpeg')[0];
|
||||
|
||||
if (ff) {
|
||||
/* extract duration, container and video codec from ffmpeg output */
|
||||
ff = ff.innerHTML;
|
||||
var match = /Duration:\s+([0-9.:]+),/.exec(ff);
|
||||
if (match && match[1])
|
||||
duration = (new Date('1970-01-01T' + match[1] + 'Z')).getTime()/1000;
|
||||
match = /Input #0,\s+([-A-Za-z0-9_,]+),\s/.exec(ff);
|
||||
if (match && match[1]) fmts = match[1];
|
||||
match = /Stream #.+\sVideo:\s+([-A-Za-z0-9_]+)\s/.exec(ff);
|
||||
if (match && match[1]) vc = match[1];
|
||||
}
|
||||
|
||||
window.location = '/play/play.jim?' +
|
||||
'dir=' + encodeURIComponent(dir) +
|
||||
'&file=' + encodeURIComponent(file);
|
||||
fmts = /mp4|webm/.exec(fmts);
|
||||
if (fmts && fmts[0])
|
||||
vc = /h264|av1|vp9/.exec(vc);
|
||||
else
|
||||
vc = null;
|
||||
|
||||
if (vc && vc[0]) {
|
||||
/* base on page address to handle client on external network, etc */
|
||||
var hh = new URL(file, window.location.href);
|
||||
window.location = hh.href;
|
||||
} else {
|
||||
window.location = '/browse/play.jim?' +
|
||||
'dir=' + encodeURIComponent(dir) +
|
||||
'&base=' + encodeURI(window.location.hostname) +
|
||||
'&duration=' + duration +
|
||||
'&file=' + encodeURIComponent(file);
|
||||
}
|
||||
|
||||
$(it).dialog('close');
|
||||
}
|
||||
|
||||
// Bind dialogue open to filenames.
|
||||
|
@ -834,11 +867,9 @@ $('a.bf').click(function(e) {
|
|||
$dialog.attr('file', file);
|
||||
$dialog.attr('type', type);
|
||||
|
||||
if (type == 'ts' &&
|
||||
(opt.attr('odencd') == 0 || opt.attr('dlna') == 1))
|
||||
$dialog.dialog("option", "buttons", $buttonsp);
|
||||
else
|
||||
$dialog.dialog("option", "buttons", $buttons);
|
||||
if (!(type == 'ts' &&
|
||||
(opt.attr('odencd') == 0 || opt.attr('dlna') == 1)))
|
||||
$('#play').button('disable');
|
||||
$dialog.dialog('open');
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue