From 20c035873e03fcdcb67f2dee21568b2fa50b00eb Mon Sep 17 00:00:00 2001 From: df Date: Fri, 12 Feb 2021 14:28:05 +0000 Subject: [PATCH 01/14] Remove invalid use of video/ts MIME type --- webif/html/browse/download.jim | 2 +- webif/lib/system.class | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/webif/html/browse/download.jim b/webif/html/browse/download.jim index 41447e7..dcf113f 100755 --- a/webif/html/browse/download.jim +++ b/webif/html/browse/download.jim @@ -10,7 +10,7 @@ set urlbase [cgi_get base ""] # Default to just downloading the raw file. set url $file -set mime "video/ts" +set mime "video/mp2t" if {[string match {*.ts} $file]} { if {![catch {set ts [ts fetch $file]}]} { diff --git a/webif/lib/system.class b/webif/lib/system.class index e0ffb9a..6d1fe5c 100644 --- a/webif/lib/system.class +++ b/webif/lib/system.class @@ -269,7 +269,7 @@ proc {system dlnadb} {} { } proc {system _dlnaurl} {file urlbase} { - set mime "video/ts" + set mime "video/mp2t" if {[catch {set db [sqlite3.open [system dlnadb]]}]} { return {} } @@ -278,7 +278,10 @@ proc {system _dlnaurl} {file urlbase} { from tblresource join tblmedia using (mediaid) where localurl = '%s'} $file] if {[llength $muri]} { - lassign [lindex $muri 0] x mime x xuri + lassign [lindex $muri 0] x maybemime x xuri + if {$maybemime ne "video/ts"} { + set mime $maybemime + } } else { # Try for partially linked entry set muri [$db query { -- 2.42.0 From 75b32ad3e091671a5be7ff3b23868a170dd40ca3 Mon Sep 17 00:00:00 2001 From: df Date: Mon, 15 Mar 2021 15:50:30 +0000 Subject: [PATCH 02/14] Make 127.0.0.1 the default host for DLNA functions (pt 2) --- webif/lib/system.class | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webif/lib/system.class b/webif/lib/system.class index 6d1fe5c..a740e98 100644 --- a/webif/lib/system.class +++ b/webif/lib/system.class @@ -300,7 +300,7 @@ proc {system _dlnaurl} {file urlbase} { return [list $url $mime] } -proc {system dlnaurl} {file {urlbase ""}} { +proc {system dlnaurl} {file {urlbase "127.0.0.1"}} { if {$urlbase eq ""} { set urlbase [system ip] } set retries 5 set ret {} -- 2.42.0 From 3454302a98a697bab97edac6ce0f4d9c161f6554 Mon Sep 17 00:00:00 2001 From: df Date: Tue, 16 Feb 2021 00:28:24 +0000 Subject: [PATCH 03/14] Use dicts for `httpheader` --- webif/lib/setup | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/webif/lib/setup b/webif/lib/setup index 82f17a0..4ae354b 100644 --- a/webif/lib/setup +++ b/webif/lib/setup @@ -33,16 +33,24 @@ if {![exists -proc require]} { exit } - proc httpheader {{type "text/html"} {cache 0} {extra ""}} {{done 0}} { + proc httpheader {{type "text/html"} {cache 0} {extra {}}} {{done 0}} { if {$done} return if {!$cache} { - puts -nonewline "Content-Type: $type; charset=\"UTF-8\"; no-cache\r\n" - puts -nonewline "Expires: -1\r\n" - puts -nonewline "Connection: close\r\n" - puts -nonewline "Pragma: no-cache\r\n" - puts -nonewline "Cache-Control: no-cache\r\n" + set hdr [dict create \ + "Content-Type" "$type; charset=\"UTF-8\"; no-cache" \ + "Expires" "-1" \ + "Connection" "close" \ + "Pragma" "no-cache" \ + "Cache-Control" "no-cache"] } else { - puts -nonewline "Content-Type: $type; charset=\"UTF-8\"\r\n" + set hdr [dict create "Content-Type" "$type; charset=\"UTF-8\""] + } + if {![catch {dict size $extra}]} { + set hdr [dict merge $hdr $extra] + set extra "" + } + dict for {k v} $hdr { + puts -nonewline "$k: $v\r\n" } if {$extra ne ""} { puts -nonewline "$extra" } puts -nonewline "\r\n" -- 2.42.0 From 68d9d7f5b5229a308396e3c7f2ef26568ae30ead Mon Sep 17 00:00:00 2001 From: df Date: Tue, 16 Feb 2021 01:01:25 +0000 Subject: [PATCH 04/14] Add webm to displayed file types Also handle files with no "definition" as not ts. --- webif/html/browse/index.jim | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/webif/html/browse/index.jim b/webif/html/browse/index.jim index be17858..8e6f27c 100755 --- a/webif/html/browse/index.jim +++ b/webif/html/browse/index.jim @@ -21,7 +21,7 @@ header set nicesplice [system pkginst nicesplice] set ignore {.nts .thm .hmi} -set include {.ts .avi .mpg .mpeg .wmv .mkv .mp3 .mp4 .mov .hmt .m4v .m4a} +set include {.ts .avi .mpg .mpeg .wmv .mkv .mp3 .mp4 .mov .hmt .m4v .m4a .webm} if {![dict exists $env SCRIPT_NAME]} { set env(SCRIPT_NAME) "" @@ -139,6 +139,14 @@ proc entry {file} {{i 0}} { set img Video_Failed } set omenu opt + if {[$ts get definition] eq ""} { + set type gen + set ts 0 + set img Video_Other + set omenu oopt + } else { + set omenu opt + } if {[file exists "${base}.thm"]} { set thmok 1 } } elseif {$ext eq ".hmt"} { if {[file exists "${base}.ts"]} { return } -- 2.42.0 From e79e85af816f621837c2e528235f42ca8236899e Mon Sep 17 00:00:00 2001 From: df Date: Mon, 15 Mar 2021 13:25:44 +0000 Subject: [PATCH 05/14] Make {system dlnaurl} handle any valid pathname for a file --- webif/html/browse/index.jim | 4 ++-- webif/lib/system.class | 4 ++++ webif/lib/ts.class | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/webif/html/browse/index.jim b/webif/html/browse/index.jim index 8e6f27c..587f67e 100755 --- a/webif/html/browse/index.jim +++ b/webif/html/browse/index.jim @@ -215,8 +215,8 @@ proc entry {file} {{i 0}} { # Indexed set dlna 0 - if {$::dlnaok && $::model eq "HDR" && [llength [ - system dlnaurl [file normalize $file]]]} { + if {$::dlnaok && $::model eq "HDR" && + [llength [system dlnaurl $file]]} { icon "/img/dlna.png" "Indexed by DLNA Server" set dlna 1 } diff --git a/webif/lib/system.class b/webif/lib/system.class index a740e98..db3ce76 100644 --- a/webif/lib/system.class +++ b/webif/lib/system.class @@ -270,6 +270,10 @@ proc {system dlnadb} {} { proc {system _dlnaurl} {file urlbase} { set mime "video/mp2t" + set nfile $file + if {![catch {set nfile [file normalize $file]}]} { + set file $nfile + } if {[catch {set db [sqlite3.open [system dlnadb]]}]} { return {} } diff --git a/webif/lib/ts.class b/webif/lib/ts.class index 6eb0b51..d4de7ff 100644 --- a/webif/lib/ts.class +++ b/webif/lib/ts.class @@ -331,7 +331,7 @@ ts method setgenre {newgenre} { } ts method dlnaloc {{urlbase ""}} { - return [system dlnaurl [file normalize $file] $urlbase] + return [system dlnaurl $file $urlbase] } ts method cleanbmp {} { -- 2.42.0 From f032f8b4696295e786fb066011a94d40a5894a21 Mon Sep 17 00:00:00 2001 From: df Date: Tue, 16 Feb 2021 00:49:28 +0000 Subject: [PATCH 06/14] 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 --- webif/html/browse/file.jim | 44 ++++++++++++++++---------- webif/html/browse/play.jim | 62 ++++++++++++++++++++++++++++++++++++ webif/html/browse/script.js | 63 +++++++++++++++++++++++++++---------- 3 files changed, 136 insertions(+), 33 deletions(-) create mode 100755 webif/html/browse/play.jim diff --git a/webif/html/browse/file.jim b/webif/html/browse/file.jim index e35e86d..04c227c 100755 --- a/webif/html/browse/file.jim +++ b/webif/html/browse/file.jim @@ -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 " Flags - [$ts get flags] + [set flags [$ts get flags]] " @@ -215,9 +219,6 @@ if {[$ts get bookmarks]} { " } -puts " - -" puts "" puts { } - exit } # Otherwise, for a general file. -puts " +if {$type ne "ts"} { + puts " @@ -269,20 +270,29 @@ puts " - +" +} + +set hasffmpeg 0 +if {$type ne "ts" || ("ODEncrypted" ni $flags && $url eq "") } { + puts " - -
File
Size $sz
Info Loading...
-" +" + set hasffmpeg 1 +} +puts " + + " -set url "/browse/ffmpeg.jim?file=[cgi_quote_url $file]" -puts { } - +} diff --git a/webif/html/browse/play.jim b/webif/html/browse/play.jim new file mode 100755 index 0000000..3eb8dc3 --- /dev/null +++ b/webif/html/browse/play.jim @@ -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} + diff --git a/webif/html/browse/script.js b/webif/html/browse/script.js index 5269fa0..2ed094f 100755 --- a/webif/html/browse/script.js +++ b/webif/html/browse/script.js @@ -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({ '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'); }); -- 2.42.0 From 7964145677c638f2dd161b0e5440a267ec2c1b36 Mon Sep 17 00:00:00 2001 From: df Date: Mon, 15 Mar 2021 16:37:13 +0000 Subject: [PATCH 07/14] Don't play HTML5 media in the WebIf Browse Files window --- webif/html/browse/script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webif/html/browse/script.js b/webif/html/browse/script.js index 2ed094f..be4a9bf 100755 --- a/webif/html/browse/script.js +++ b/webif/html/browse/script.js @@ -839,7 +839,7 @@ function doplay(it) 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; + window.open(hh.href, 'WebIf_Player'); } else { window.location = '/browse/play.jim?' + 'dir=' + encodeURIComponent(dir) + -- 2.42.0 From 4845a4b0cfe78ca762ed69105185101f4fb122be Mon Sep 17 00:00:00 2001 From: df Date: Tue, 13 Apr 2021 12:58:20 +0000 Subject: [PATCH 08/14] Add Download button --- webif/html/browse/file.jim | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/webif/html/browse/file.jim b/webif/html/browse/file.jim index 04c227c..6675248 100755 --- a/webif/html/browse/file.jim +++ b/webif/html/browse/file.jim @@ -282,6 +282,10 @@ if {$type ne "ts" || ("ODEncrypted" ni $flags && $url eq "") } { " set hasffmpeg 1 +} elseif {$type eq "ts" && $url ne ""} { + puts { } } puts " @@ -292,7 +296,7 @@ if {$hasffmpeg} { puts { } } -- 2.42.0 From c8f51adfaacde53f5477f7ce533e0daaeab58acb Mon Sep 17 00:00:00 2001 From: df Date: Fri, 16 Apr 2021 10:29:27 +0000 Subject: [PATCH 09/14] Add Download button --- webif/html/browse/script.js | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/webif/html/browse/script.js b/webif/html/browse/script.js index be4a9bf..daf0075 100755 --- a/webif/html/browse/script.js +++ b/webif/html/browse/script.js @@ -10,7 +10,7 @@ var plugins = { dmenu_prepare: {} }; -// pattern matches directory path prefix +// pattern matches directory path prefix and suffix var pathre = /.*\/|\.[^.]*$/g; // IDs of size, img elements for folders use RFC4648 s5 encoding of name @@ -808,6 +808,15 @@ var $dialog = $('#dialogue').dialog({ 'Retrieving data...'); } }); +/* insert button-like Download link before Play */ +$('#play').before(function(i){ + var dl = document.createElement('a'); + dl.setAttribute('class', this.className); + dl.id = this.id + 'DL'; + dl.innerHTML = 'Download'; + return dl; +}); + function doplay(it) { var file = $dialog.attr('file'); @@ -864,12 +873,18 @@ $('a.bf').click(function(e) { type: type }); - $dialog.attr('file', file); - $dialog.attr('type', type); + if (type == 'ts') { + if (opt.attr('odencd') != 0) { + /* encrypted: link to be enabled once populated */ + $('#playDL').disable(); + /* ... but if no DLNA never Play */ + if (opt.attr('dlna') != 1) $('#play').disable(); + } + } else { + /* generic: enable Play once media file is parsed */ + $('#play').disable(); + } - if (!(type == 'ts' && - (opt.attr('odencd') == 0 || opt.attr('dlna') == 1))) - $('#play').button('disable'); $dialog.dialog('open'); }); -- 2.42.0 From 8bbc28d3c259892defe6bf7a2986f647cf4a2882 Mon Sep 17 00:00:00 2001 From: df Date: Fri, 16 Apr 2021 10:32:20 +0000 Subject: [PATCH 10/14] Add Download button --- webif/html/browse/style.css | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/webif/html/browse/style.css b/webif/html/browse/style.css index d2e2fa3..93e63e4 100644 --- a/webif/html/browse/style.css +++ b/webif/html/browse/style.css @@ -35,3 +35,13 @@ input.uint8_t width: 6ch; } +/* a link that looks like a button */ +button + a.ui-button +{ + margin-right: 0.4em; +} +.ui-button:link +{ + background-color: rgb(254, 206, 47) !important; +} + -- 2.42.0 From 243dfdd59542f548f06ec4f2faedfd123adbe083 Mon Sep 17 00:00:00 2001 From: df Date: Sat, 17 Apr 2021 01:55:33 +0000 Subject: [PATCH 11/14] Fix quoting and escaping of JS fragments NB jQuery $('#id') in a string looks like an [expr ...] to Jim! --- webif/html/browse/file.jim | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/webif/html/browse/file.jim b/webif/html/browse/file.jim index 6675248..9ef4f5c 100755 --- a/webif/html/browse/file.jim +++ b/webif/html/browse/file.jim @@ -283,9 +283,10 @@ if {$type ne "ts" || ("ODEncrypted" ni $flags && $url eq "") } { " set hasffmpeg 1 } elseif {$type eq "ts" && $url ne ""} { - puts { } + puts [format { + } $url] } puts " @@ -293,10 +294,9 @@ puts " if {$hasffmpeg} { set url "/browse/ffmpeg.jim?file=[cgi_quote_url $file]" - puts { -} + puts [format { + } $url] } -- 2.42.0 From 8b795a0a7d845b4fabffb28b88acd62e7cea7d25 Mon Sep 17 00:00:00 2001 From: df Date: Sat, 17 Apr 2021 12:09:25 +0000 Subject: [PATCH 12/14] Fix quoting and escaping of JS fragments --- webif/html/browse/file.jim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webif/html/browse/file.jim b/webif/html/browse/file.jim index 9ef4f5c..17527bf 100755 --- a/webif/html/browse/file.jim +++ b/webif/html/browse/file.jim @@ -297,6 +297,6 @@ if {$hasffmpeg} { puts [format { } $url] } -- 2.42.0 From bf838ed5e4a19f16d9e97ac7238e5e40718121a8 Mon Sep 17 00:00:00 2001 From: df Date: Sat, 17 Apr 2021 13:42:50 +0000 Subject: [PATCH 13/14] Add Download button --- webif/html/browse/script.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/webif/html/browse/script.js b/webif/html/browse/script.js index daf0075..765afb7 100755 --- a/webif/html/browse/script.js +++ b/webif/html/browse/script.js @@ -873,16 +873,22 @@ $('a.bf').click(function(e) { type: type }); + $('#playDL').attr('download', file.replace(/.*\//, '')); + if (type == 'ts') { if (opt.attr('odencd') != 0) { /* encrypted: link to be enabled once populated */ $('#playDL').disable(); /* ... but if no DLNA never Play */ if (opt.attr('dlna') != 1) $('#play').disable(); + } else { + /* link unencrypted file directly */ + $('#playDL').attr('href', file); } } else { /* generic: enable Play once media file is parsed */ $('#play').disable(); + $('#playDL').attr('href', file); } $dialog.dialog('open'); -- 2.42.0 From da7d07a891b030c93abf230a58fd70ade2b1f682 Mon Sep 17 00:00:00 2001 From: df Date: Sat, 17 Apr 2021 14:13:04 +0000 Subject: [PATCH 14/14] Add Download button --- webif/html/browse/script.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/webif/html/browse/script.js b/webif/html/browse/script.js index 765afb7..11bb2cd 100755 --- a/webif/html/browse/script.js +++ b/webif/html/browse/script.js @@ -873,6 +873,9 @@ $('a.bf').click(function(e) { type: type }); + $dialog.attr('file', file); + $dialog.attr('type', type); + $('#playDL').attr('download', file.replace(/.*\//, '')); if (type == 'ts') { -- 2.42.0