mirror of
				https://github.com/9001/copyparty.git
				synced 2025-11-02 04:53:15 +00:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | ff8313d0fb | 
| @@ -324,6 +324,9 @@ def run_argparse(argv, formatter): | ||||
|     ap2.add_argument("-mtp", metavar="M=[f,]bin", action="append", type=str, help="read tag M using bin") | ||||
|     ap2.add_argument("--srch-time", metavar="SEC", type=int, default=30, help="search deadline") | ||||
|  | ||||
|     ap2 = ap.add_argument_group('video streaming options') | ||||
|     ap2.add_argument("--vcr", action="store_true", help="enable video streaming") | ||||
|  | ||||
|     ap2 = ap.add_argument_group('appearance options') | ||||
|     ap2.add_argument("--css-browser", metavar="L", help="URL to additional CSS to include") | ||||
|  | ||||
|   | ||||
| @@ -18,6 +18,8 @@ from .util import *  # noqa  # pylint: disable=unused-wildcard-import | ||||
| from .authsrv import AuthSrv | ||||
| from .szip import StreamZip | ||||
| from .star import StreamTar | ||||
| from .vcr import VCR_Direct | ||||
| from .th_srv import FMT_FF | ||||
|  | ||||
| if not PY2: | ||||
|     unicode = str | ||||
| @@ -229,7 +231,9 @@ class HttpCli(object): | ||||
|     def send_headers(self, length, status=200, mime=None, headers={}): | ||||
|         response = ["{} {} {}".format(self.http_ver, status, HTTPCODE[status])] | ||||
|  | ||||
|         if length is not None: | ||||
|         if length is None: | ||||
|             self.keepalive = False | ||||
|         else: | ||||
|             response.append("Content-Length: " + unicode(length)) | ||||
|  | ||||
|         # close if unknown length, otherwise take client's preference | ||||
| @@ -1563,6 +1567,15 @@ class HttpCli(object): | ||||
|             if rem.startswith(".hist/up2k."): | ||||
|                 raise Pebkac(403) | ||||
|  | ||||
|             if "vcr" in self.uparam: | ||||
|                 ext = abspath.rsplit(".")[-1] | ||||
|                 if not self.args.vcr or ext not in FMT_FF: | ||||
|                     raise Pebkac(403) | ||||
|  | ||||
|                 vcr = VCR_Direct(self, abspath) | ||||
|                 vcr.run() | ||||
|                 return False | ||||
|  | ||||
|             is_dir = stat.S_ISDIR(st.st_mode) | ||||
|             th_fmt = self.uparam.get("th") | ||||
|             if th_fmt is not None: | ||||
|   | ||||
							
								
								
									
										80
									
								
								copyparty/vcr.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								copyparty/vcr.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| # coding: utf-8 | ||||
| from __future__ import print_function, unicode_literals | ||||
|  | ||||
| import time | ||||
| import shlex | ||||
| import subprocess as sp | ||||
|  | ||||
| from .__init__ import PY2 | ||||
| from .util import fsenc | ||||
|  | ||||
|  | ||||
| class VCR_Direct(object): | ||||
|     def __init__(self, cli, fpath): | ||||
|         self.cli = cli | ||||
|         self.fpath = fpath | ||||
|  | ||||
|         self.log_func = cli.log_func | ||||
|         self.log_src = cli.log_src | ||||
|  | ||||
|     def log(self, msg, c=0): | ||||
|         self.log_func(self.log_src, "vcr: {}".format(msg), c) | ||||
|  | ||||
|     def run(self): | ||||
|         opts = self.cli.uparam | ||||
|  | ||||
|         # fmt: off | ||||
|         cmd = [ | ||||
|             "ffmpeg", | ||||
|             "-nostdin", | ||||
|             "-hide_banner", | ||||
|             "-v", "warning", | ||||
|             "-i", fsenc(self.fpath), | ||||
|             "-vf", "scale=640:-4", | ||||
|             "-c:a", "libopus", | ||||
|             "-b:a", "128k", | ||||
|             "-c:v", "libvpx", | ||||
|             "-deadline", "realtime", | ||||
|             "-row-mt", "1" | ||||
|         ] | ||||
|         # fmt: on | ||||
|  | ||||
|         if "ss" in opts: | ||||
|             cmd.extend(["-ss", opts["ss"]]) | ||||
|  | ||||
|         if "crf" in opts: | ||||
|             cmd.extend(["-b:v", "0", "-crf", opts["crf"]]) | ||||
|         else: | ||||
|             cmd.extend(["-b:v", "{}M".format(opts.get("mbps", 1.2))]) | ||||
|  | ||||
|         cmd.extend(["-f", "webm", "-"]) | ||||
|  | ||||
|         comp = str if not PY2 else unicode | ||||
|         cmd = [x.encode("utf-8") if isinstance(x, comp) else x for x in cmd] | ||||
|  | ||||
|         self.log(" ".join([shlex.quote(x.decode("utf-8", "replace")) for x in cmd])) | ||||
|  | ||||
|         p = sp.Popen(cmd, stdout=sp.PIPE) | ||||
|  | ||||
|         self.cli.send_headers(None, mime="video/webm") | ||||
|  | ||||
|         fails = 0 | ||||
|         while True: | ||||
|             self.log("read") | ||||
|             buf = p.stdout.read(1024 * 4) | ||||
|             if not buf: | ||||
|                 fails += 1 | ||||
|                 if p.poll() is not None or fails > 30: | ||||
|                     self.log("ffmpeg exited") | ||||
|                     return | ||||
|  | ||||
|                 time.sleep(0.1) | ||||
|                 continue | ||||
|  | ||||
|             fails = 0 | ||||
|             try: | ||||
|                 self.cli.s.sendall(buf) | ||||
|             except: | ||||
|                 self.log("client disconnected") | ||||
|                 p.kill() | ||||
|                 return | ||||
| @@ -1552,6 +1552,7 @@ var thegrid = (function () { | ||||
| 			href = this.getAttribute('href'), | ||||
| 			aplay = ebi('a' + oth.getAttribute('id')), | ||||
| 			is_img = /\.(gif|jpe?g|png|webp)(\?|$)/i.test(href), | ||||
| 			is_vid = /\.(av1|asf|avi|flv|m4v|mkv|mjpeg|mjpg|mpg|mpeg|mpg2|mpeg2|h264|avc|h265|hevc|mov|3gp|mp4|ts|mpegts|nut|ogv|ogm|rm|vob|webm|wmv)(\?|$)/i.test(href), | ||||
| 			in_tree = null, | ||||
| 			have_sel = QS('#files tr.sel'), | ||||
| 			td = oth.closest('td').nextSibling, | ||||
| @@ -1579,6 +1580,9 @@ var thegrid = (function () { | ||||
| 		else if (in_tree && !have_sel) | ||||
| 			in_tree.click(); | ||||
|  | ||||
| 		else if (is_vid) | ||||
| 			window.open(href + (href.indexOf('?') === -1 ? '?' : '&') + 'vcr', '_blank'); | ||||
|  | ||||
| 		else if (!is_img && have_sel) | ||||
| 			window.open(href, '_blank'); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user