├── res
├── .gitignore
└── ffmpeg.png
├── update.xml
├── LICENSE
├── README.md
├── ttmg.py
└── FFmpeg_for_GDrive.ipynb
/res/.gitignore:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/res/ffmpeg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/menukaonline/FFmpeg-for-GDrive/HEAD/res/ffmpeg.png
--------------------------------------------------------------------------------
/update.xml:
--------------------------------------------------------------------------------
1 |
2 | 1.3.0
3 | is now available!
4 |
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 sudo-ken
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Notice on username change
2 |
3 | Hi there!
Thank you for visiting this repository.
4 |
5 | Please note that my GitHub username has recently changed from [@cheems](https://github.com/cheems) to [@menukaonline](https://github.com/menukaonline). If you are looking for my other repositories, you can find them under my new username ([@menukaonline](https://github.com/menukaonline)).
6 |
7 | 

8 |
9 | In order to ensure that visitors from old URLs are still able to find my repositories, I have created a GitHub organization with the previous handle ([@cheems](https://github.com/cheems)) which will be used to publish updates about my current repositories.
10 |
11 | Thank you for your understanding and I apologize for any inconvenience this may have caused.
12 |
13 | Best regards,
14 | [@menukaonline](https://github.com/menukaonline) ([@cheems](https://github.com/cheems))
15 |
16 | ##
17 |
18 | # FFmpeg-for-GDrive
19 | This is a Google Colab notebook with FFmpeg for converting multimedia files on Google Drive
20 |
Usage:
21 |
22 |
23 | 1. Click on the "Open in Colab" button and press ctrl+f9
24 |
--------------------------------------------------------------------------------
/ttmg.py:
--------------------------------------------------------------------------------
1 | #Shared by cheems(https://github.com/cheems)
2 | import os
3 | from sys import exit as exx
4 | import time
5 | import uuid
6 | import re
7 | from subprocess import Popen,PIPE
8 |
9 | HOME = os.path.expanduser("~")
10 | CWD = os.getcwd()
11 |
12 | # All found ngrok authtoken from github
13 | tokens = {
14 | "lostcatbox": "1X7aYWPuFKYzvewLbnNoMo71kZi_2uzbB966Q4TU5cpgNPKhy",
15 | "zero-structure": "1UqHsShi6o3ketf426P5UtVdTfs_5XFD6sFRMkryka8fAbLd3",
16 | "ekkleesia": "7LE18LK8zeaDYeybp5fKP_6GNG1oHEfhTnQE7s9qpw",
17 | "SEARteam1928": "1Qe1IeySOQWSTnpQ3eFfr8j7Oi5_2zhanqnpZwHBhsfANd6yf",
18 | "angenalZZZ": "7pWLVhS1gxiMAQdaFeYJy_31krnw9drNLLJftaNSFnm",
19 | "lukikrk": "1XJNNnG8kZsPjjFmLsYNWCC0gIo_7VpBhwTcvhiuK4o2G2jbt",
20 | "bhavya7777": "1XzP70k7YVrg7MMaHQWPks0Q8Za_7y6b1mTDJDmJWcuqt5qTp",
21 | "hector605": "1Y14GB7E4acXxWYnVTiBejgnLuV_853z7mAgaTJxE9KY3HnCW",
22 | "fouille": "1XkoKNLcyiPECcQfGUjrTVzN64P_7tv2YgC4DSnazyVtpCpHm",
23 | "rikitz": "1Xc7z0uHxDoI9Ah06EQKgH61zoP_6WTPXDGvjFmcp2o7gNmqa",
24 | "VictorM369": "3c4WZaxPbjeRwRibY5opU_2N4TTRKaDubtEWMeKkFXn",
25 | "YHF7": "3fW4eXHdUN3ziCBXcahZ_3tnDdaTyLw8tKzJtKZkLp",
26 | "cyberkallan": "3CqeFZQht43cG5Z2YKfyv_6aKTrgrbo1HtyRi78hRKK",
27 | "Toxic-Omega": "1RCQwctVjSz8AIzHO6S55jm8XB8_5N6PqyZVnoN7mUVqF1yvT",
28 | "DevLuDaley": "1XTxsRKP8XyxvaJigX9XFXU2FvK_4dqzLxNRJHBz8A3aoPC85",
29 | "randyramig": "3Y8YSw6bvC9CsbYeRczmt_8akMuLYA3bAUshP1NCMnW",
30 | "sz-xcf": "1XSYq8gmxzNgMlYQzERmC50uBot_6qURZnj43KsYF2GWaUamm",
31 | "api1": "6qGnEsrCL4GqZ7hMfqpyz_7ejAThUCjVnU9gD5pbP5u",
32 | "api2": "1Q4i7F6isO7zZRrrjBKZzZhwsMu_74yJqoEs1HrJh1zYyxNo1",
33 | "api3": "1SCsbuawjv9d79jlhlfNljaFTaB_5heVkcR6C7Sk8UBaQ1U1C",
34 | "api5": "1Q45NXgsx6oyusN3GiNAYvkNJPS_AveYUDBcPHsvRvf21WZv",
35 | "api6": "1Q6smHt4Bzz9VEXTwj3a7p5Gdx2_5mp6ivT6N6nB3YmRHUEM3",
36 | "api7": "7VJwGkCTTUubiGhgz6Gv6_5fMLganRSKj9ntdefnF5o",
37 | "api9": "5S28rBKgc22ZW7evyedNT_YvEm15RZSHdXgS4QwYbk",
38 | "api12": "3VnrrXDQVHoNp9HvHFhqX_3X4JExwm6L9n6w4ppL1qy",
39 | "api13": "1ShshNwfhQcyOqlMjnBDVE5X5jC_3WAmzomMHAgkunka4dSck",
40 | "api14": "772yFAui6ynH9AYx29HHS_5Xcr88pHtPTQLwewv7Ctk",
41 | "api16": "5HmAWwzDdkYp8CdzDQMDS_4BGwsK7AdMssLnSttZEeh",
42 | "api17": "1T750atJi3xccndeUqJ4ewiS62o_2s6f8GUccL1qDUXTGSftN",
43 | "api18": "1QUysRUo97w5mdB6sCZvTTMM0aK_3unoMs6nYd7grgCkuhbj3",
44 | "api19": "3CqeFZQht43cG5Z2YKfyv_6aKTrgrbo1HtyRi78hRKK",
45 | "api20": "5eMywZLisJNdybqpFLVgs_4XQDeF3YCMHu1Ybf7mVE6",
46 | "api21": "4Cg1cEwCT7Ek89zT4VcdB_4GPAjMFgu6nhwY7SxQm94",
47 | "api22": "1SGs4s9NrhxP9FRURszjL1nITSv_otcpfpb6aMVEL13u3dv1",
48 | "api23": "1StL3sIccfR624Uc3BGV36XA0qG_6cAMMYFdKtPjtWax3AHSK",
49 | "api24": "1SuK2ukM9Z4NohoJbU9224uMzXr_6h1ABdCrJU2EviZv4RN4r",
50 | "api26": "7ecmt2Kux5uYsTUHrrqGU_3W9CJnaSeSyxiwkjxNhHc",
51 | "api27": "3CqeFZQht43cG5Z2YKfyv_6aKTrgrbo1HtyRi78hRKK",
52 | "api28": "2DXURjrUhAZZNMhqN5m1F_6HHzejcfRecP8upwJnNBd"
53 | }
54 |
55 |
56 | class ngrok:
57 |
58 | def __init__(self, TOKEN=None, USE_FREE_TOKEN=True,
59 | service=[['Service1', 80, 'tcp'], ['Service2', 8080, 'tcp']],
60 | region='us',
61 | dBug=[f"{HOME}/.ngrok2/ngrok.yml", 4040]):
62 | self.region = region
63 | self.configPath, self.dport = dBug
64 | self.TOKEN = TOKEN
65 | self.USE_FREE_TOKEN = USE_FREE_TOKEN
66 | self.service = service
67 | if USE_FREE_TOKEN:
68 | self.sdict = {}
69 | for i, sn in enumerate(service):
70 | tempcP = f'{HOME}/.ngrok2/'+sn[0]+'.yml'
71 | # Port, Protocol, config path
72 | self.sdict[sn[0]] = [self.dport+i, sn[2], tempcP]
73 |
74 | def nameport(self, TOKEN, AUTO):
75 | if AUTO:
76 | try:
77 | return tokens.popitem()[1]
78 | except KeyError:
79 | return "Invalid Token"
80 | elif not TOKEN:
81 | if not 'your' in tokens.keys():
82 | from IPython import get_ipython
83 | from IPython.display import clear_output
84 | ipython = get_ipython()
85 |
86 | print(r"Copy authtoken from https://dashboard.ngrok.com/auth")
87 | __temp = ipython.magic('%sx read -p "Token :"')
88 | tokens['your'] = __temp[0].split(':')[1]
89 | USR_Api = "your"
90 | clear_output()
91 | else:
92 | USR_Api = "your"
93 | else:
94 | USR_Api = "mind"
95 | tokens["mind"] = TOKEN
96 | return tokens[USR_Api]
97 |
98 |
99 | def ngrok_config(self, token, Gport, configPath, region, service):
100 | import os
101 | data = """
102 | region: {}
103 | update: false
104 | update_channel: stable
105 | web_addr: localhost:{}
106 | tunnels:\n""".format(region, Gport)
107 | if not self.USE_FREE_TOKEN:
108 | auth ="""
109 | authtoken: {}""".format(token)
110 | data = auth+data
111 | tunnels = ""
112 | for S in service:
113 | Sn, Sp, SpC = S
114 | tunnels += """ {}:
115 | addr: {}
116 | proto: {}
117 | inspect: false\n""".format(Sn, Sp, SpC)
118 | data = data + tunnels
119 | os.makedirs(f'{HOME}/.ngrok2/', exist_ok=True)
120 | with open(configPath, "w+") as configFile:
121 | configFile.write(data)
122 | return True
123 |
124 |
125 | def startWebUi(self, token, dport, nServer, region, btc, configPath,
126 | displayB, service, v):
127 | import os, time, urllib
128 | from IPython.display import clear_output
129 | from json import loads
130 |
131 | if token == "Invalid Token":
132 | print(tokens)
133 | os.exit()
134 |
135 | installNgrok()
136 | if v:
137 | clear_output()
138 | loadingAn(name="lds")
139 | textAn("Starting ngrok ...", ty='twg')
140 | if self.USE_FREE_TOKEN:
141 | for sn in service:
142 | self.ngrok_config(
143 | token,
144 | self.sdict[nServer][0],
145 | self.sdict[nServer][2],
146 | region,
147 | service)
148 | if sn[0] == nServer:
149 | runSh(f"ngrok {sn[2]} -config={self.sdict[nServer][2]} {sn[1]} &", shell=True)
150 | else:
151 | self.ngrok_config(token, dport, configPath, region, service)
152 | runSh(f"ngrok start --config {configPath} --all &", shell=True)
153 | time.sleep(3)
154 | try:
155 | if self.USE_FREE_TOKEN:
156 | dport = self.sdict[nServer][0]
157 | nServer = 'command_line'
158 | host = urllib.request.urlopen(f"http://localhost:{dport}/api/tunnels")
159 | else:
160 | host = urllib.request.urlopen(f"http://localhost:{dport}/api/tunnels")
161 | host = loads(host.read())['tunnels']
162 | for h in host:
163 | if h['name'] == nServer:
164 | host = h['public_url'][8:]
165 | break
166 | except urllib.error.URLError:
167 | if v:
168 | clear_output()
169 | loadingAn(name="lds")
170 | textAn("Ngrok Token is in used!. Again trying token ...", ty='twg')
171 | time.sleep(2)
172 | return True
173 |
174 | data = {"url": f"http://{host}"}
175 | if displayB:
176 | displayUrl(data, btc)
177 | return data
178 |
179 |
180 | def start(self, nServer, btc='b', displayB=True, v=True):
181 | import urllib
182 | from IPython.display import clear_output
183 | from json import loads
184 |
185 | try:
186 | nServerbk = nServer
187 | if self.USE_FREE_TOKEN:
188 | dport = self.sdict[nServer][0]
189 | nServer = 'command_line'
190 | else:
191 | dport = self.dport
192 | host = urllib.request.urlopen(f"http://localhost:{dport}/api/tunnels")
193 | host = loads(host.read())['tunnels']
194 | for h in host:
195 | if h['name'] == nServer:
196 | host = h['public_url'][8:]
197 | data = {"url": f"http://{host}"}
198 | if displayB:
199 | displayUrl(data, btc)
200 | return data
201 |
202 | raise Exception('Not found tunnels')
203 | except urllib.error.URLError:
204 | for run in range(10):
205 | if v:
206 | clear_output()
207 | loadingAn(name='lds')
208 | dati = self.startWebUi(
209 | self.nameport(self.TOKEN, self.USE_FREE_TOKEN) if not self.USE_FREE_TOKEN else {},
210 | self.dport,
211 | nServerbk,
212 | self.region,
213 | btc,
214 | self.configPath,
215 | displayB,
216 | self.service,
217 | v
218 | )
219 | if dati == True:
220 | continue
221 | return dati
222 |
223 | def checkAvailable(path_="", userPath=False):
224 | from os import path as _p
225 |
226 | if path_ == "":
227 | return False
228 | else:
229 | return (
230 | _p.exists(path_)
231 | if not userPath
232 | else _p.exists(f"/usr/local/sessionSettings/{path_}")
233 | )
234 |
235 | def accessSettingFile(file="", setting={}, v=True):
236 | from json import load, dump
237 |
238 | if not isinstance(setting, dict):
239 | if v:print("Only accept Dictionary object.")
240 | exx()
241 | fullPath = f"/usr/local/sessionSettings/{file}"
242 | try:
243 | if not len(setting):
244 | if not checkAvailable(fullPath):
245 | if v:print(f"File unavailable: {fullPath}.")
246 | exx()
247 | with open(fullPath) as jsonObj:
248 | return load(jsonObj)
249 | else:
250 | with open(fullPath, "w+") as outfile:
251 | dump(setting, outfile)
252 | except:
253 | if v:print(f"Error accessing the file: {fullPath}.")
254 |
255 |
256 | def displayUrl(data, btc='b', pNamU='Public URL: ', EcUrl=None, ExUrl=None, cls=True):
257 | from IPython.display import HTML, clear_output
258 |
259 | if cls:
260 | clear_output()
261 | showTxT = f'{pNamU}{data["url"]}'
262 | if EcUrl:
263 | showUrL = data["url"]+EcUrl
264 | elif ExUrl:
265 | showUrL = ExUrl
266 | else:
267 | showUrL = data["url"]
268 | if btc == 'b':
269 | # blue
270 | bttxt = 'hsla(210, 50%, 85%, 1)'
271 | btcolor = 'hsl(210, 80%, 42%)'
272 | btshado = 'hsla(210, 40%, 52%, .4)'
273 | elif btc == 'g':
274 | # green
275 | bttxt = 'hsla(110, 50%, 85%, 1)'
276 | btcolor = 'hsla(110, 86%, 56%, 1)'
277 | btshado = 'hsla(110, 40%, 52%, .4)'
278 | elif btc == 'r':
279 | # red
280 | bttxt = 'hsla(10, 50%, 85%, 1)'
281 | btcolor = 'hsla(10, 86%, 56%, 1)'
282 | btshado = 'hsla(10, 40%, 52%, .4)'
283 |
284 | return display(HTML('''
'''))
285 |
286 |
287 | def findProcess(process, command="", isPid=False):
288 | from psutil import pids, Process
289 |
290 | if isinstance(process, int):
291 | if process in pids():
292 | return True
293 | else:
294 | for pid in pids():
295 | try:
296 | p = Process(pid)
297 | if process in p.name():
298 | for arg in p.cmdline():
299 | if command in str(arg):
300 | return True if not isPid else str(pid)
301 | else:
302 | pass
303 | else:
304 | pass
305 | except:
306 | continue
307 |
308 | def installNgrok():
309 | if checkAvailable("/usr/local/bin/ngrok"):
310 | return
311 | else:
312 | import os
313 | from zipfile import ZipFile
314 | from urllib.request import urlretrieve
315 |
316 | ngURL = "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip"
317 | urlretrieve(ngURL, 'ngrok-amd64.zip')
318 | with ZipFile('ngrok-amd64.zip', 'r') as zip_ref:
319 | zip_ref.extractall('/usr/local/bin/')
320 | os.chmod('/usr/local/bin/ngrok', 0o755)
321 | os.unlink('ngrok-amd64.zip')
322 |
323 | def installAutoSSH():
324 | if checkAvailable("/usr/bin/autossh"):
325 | return
326 | else:
327 | runSh("apt-get install autossh -qq -y")
328 |
329 |
330 |
331 | def runSh(args, *, output=False, shell=False, cd=None):
332 | import subprocess, shlex
333 |
334 | if not shell:
335 | if output:
336 | proc = subprocess.Popen(
337 | shlex.split(args), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=cd
338 | )
339 | while True:
340 | output = proc.stdout.readline()
341 | if output == b"" and proc.poll() is not None:
342 | return
343 | if output:
344 | print(output.decode("utf-8").strip())
345 | return subprocess.run(shlex.split(args), cwd=cd).returncode
346 | else:
347 | if output:
348 | return (
349 | subprocess.run(
350 | args,
351 | shell=True,
352 | stdout=subprocess.PIPE,
353 | stderr=subprocess.STDOUT,
354 | cwd=cd,
355 | )
356 | .stdout.decode("utf-8")
357 | .strip()
358 | )
359 | return subprocess.run(args, shell=True, cwd=cd).returncode
360 |
361 | def loadingAn(name="cal"):
362 | from IPython.display import HTML
363 |
364 | if name == "cal":
365 | return display(HTML(''))
366 | elif name == "lds":
367 | return display(HTML(''''''))
368 |
369 | def textAn(TEXT, ty='d'):
370 | from IPython.display import HTML
371 |
372 | if ty == 'd':
373 | return display(HTML(''''''))
374 | elif ty == 'twg':
375 | textcover = str(len(TEXT)*0.55)
376 | return display(HTML(''''''+TEXT+'''
'''))
377 |
378 | def updateCheck(self, Version):
379 | class UpdateChecker(object):
380 |
381 | def __init__(self):
382 | getMessage = self.getMessage
383 | getVersion = self.getVersion
384 |
385 | def getVersion(self, currentTag):
386 | from urllib.request import urlopen
387 | from lxml.etree import XML
388 |
389 | url = self.URL
390 | update = urlopen(url).read()
391 | root = XML(update)
392 | cur_version = root.find(".//"+currentTag)
393 | current = cur_version.text
394 | return current
395 |
396 | def getMessage(self, messageTag):
397 | from urllib.request import urlopen
398 | from lxml.etree import XML
399 |
400 | url = self.URL
401 | update = urlopen(url).read()
402 | root = XML(update)
403 | mess = root.find(".//"+messageTag)
404 | message = mess.text
405 | return message
406 |
407 | check = UpdateChecker()
408 | check.URL = "https://raw.githubusercontent.com/sudo-ken/FFmpeg-for-GDrive/master/update.xml"
409 | currentVersion = check.getVersion("currentVersion")
410 | message = check.getMessage("message")
411 |
412 | if Version != currentVersion:
413 | from IPython.display import HTML
414 |
415 | print("Script Update Checker: Version "+currentVersion+" "+message+" Your version: "+Version+"")
416 | display(HTML(''))
417 | return True
418 | else:
419 | print("Script Update Checker: Your script is up to date")
420 |
421 | class LocalhostRun:
422 | def __init__(self,port,id=None,interval=30,retries=30):
423 | import os
424 | filePath = "/usr/local/sessionSettings/localhostDB.json"
425 | if not os.path.exists(filePath):
426 | os.makedirs(filePath[:-16], exist_ok=True)
427 | open(filePath, 'w').close()
428 | installAutoSSH()
429 | if not id:id=str(uuid.uuid4())[:8]
430 | self.connection=None
431 | self.id=id
432 | self.port=port
433 | self.interval=interval
434 | self.retries=retries
435 |
436 | def start(self):
437 | if self.connection:self.connection.kill()
438 | self.connection=Popen(f"ssh -R 80:localhost:{self.port} {self.id}@ssh.localhost.run -o StrictHostKeyChecking=no".split(), stdout=PIPE, stdin=PIPE)
439 | try:
440 | return re.findall("http://(.*?.localhost.run)",self.connection.stdout.readline().decode("utf-8"))[0]
441 | except:
442 | raise Exception(self.connection.stdout.readline().decode("utf-8"))
443 |
444 | def keep_alive(self):
445 | # if self.connection:self.connection.kill()
446 | import urllib
447 | try:
448 | localhostOpenDB = dict(accessSettingFile("localhostDB.json", v=False))
449 | except TypeError:
450 | localhostOpenDB = dict()
451 |
452 | if findProcess("autossh", f"80:localhost:{self.port}"):
453 | try:
454 | oldAddr = localhostOpenDB[str(self.port)]
455 | urllib.request.urlopen("http://"+oldAddr)
456 | return oldAddr
457 | except:
458 | pass
459 |
460 | self.connection=Popen(f"autossh -R 80:localhost:{self.port} {self.id}@ssh.localhost.run -o StrictHostKeyChecking=no -o ServerAliveInterval={self.interval} -o ServerAliveCountMax={self.retries}".split(), stdout=PIPE, stdin=PIPE)
461 | #print("ssh -R 80:localhost:{self.port} {self.id}@ssh.localhost.run -o StrictHostKeyChecking=no -o ServerAliveInterval={self.interval} -o ServerAliveCountMax={self.retries}")
462 | try:
463 | newAddr = re.findall("http://(.*?.localhost.run)",self.connection.stdout.readline().decode("utf-8"))[0]
464 | localhostOpenDB[str(self.port)] = newAddr
465 | accessSettingFile("localhostDB.json" , localhostOpenDB, v=False)
466 | return newAddr
467 | except:
468 | raise Exception(self.connection.stdout.readline().decode("utf-8"))
469 |
470 | def kill(self):
471 | self.connection.kill()
472 |
473 |
474 | class PortForward:
475 | def __init__(self,connections,region=None,SERVICE="localhost",TOKEN=None,USE_FREE_TOKEN=None,config=None):
476 | c=dict()
477 | for con in connections:
478 | c[con[0]]=dict(port=con[1],proto=con[2])
479 | self.connections=c
480 | self.ngrok=ngrok(TOKEN,USE_FREE_TOKEN,connections,region,config)
481 | self.SERVICE = SERVICE
482 |
483 | def start(self,name,btc='b',displayB=True,v=True):
484 | from IPython.display import clear_output
485 |
486 | if self.SERVICE == "localhost":
487 | con=self.connections[name]
488 | port=con["port"]
489 | proto=con["proto"]
490 | if(proto=="tcp"):
491 | return self.ngrok.start(name,btc,displayB,v)
492 | else:
493 | if v:
494 | clear_output()
495 | loadingAn(name="lds")
496 | textAn("Starting localhost ...", ty="twg")
497 | data = dict(url="http://"+LocalhostRun(port).keep_alive())
498 | if displayB:
499 | displayUrl(data, btc)
500 | return data
501 | elif self.SERVICE == "ngrok":
502 | return self.ngrok.start(name,btc,displayB,v)
503 |
504 |
505 | class PortForward_wrapper(PortForward):
506 | def __init__(self,SERVICE,TOKEN,USE_FREE_TOKEN,connections,region,config):
507 | super(self.__class__,self).__init__(connections,region,SERVICE,TOKEN,USE_FREE_TOKEN,config)
508 |
--------------------------------------------------------------------------------
/FFmpeg_for_GDrive.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "name": "FFmpeg for GDrive",
7 | "provenance": [],
8 | "collapsed_sections": [
9 | "EFOqhHG6hOVH",
10 | "CUq1_Dnegrs1",
11 | "KgNPvGccgwd8",
12 | "RDHuIkoi6l9a",
13 | "NQ0TxfKeghR8",
14 | "NObEcBWAJoaz",
15 | "FpJXJiRl6-gK",
16 | "SNDGdMRn3PA-",
17 | "2f-THZmDoOaY",
18 | "MSUasbRUDP3B",
19 | "9UagRtLPyKoQ",
20 | "GahMjYf8miNs",
21 | "7-3O4en4C4IL",
22 | "VRk2Ye1exWVA",
23 | "tozwpAhhnm69"
24 | ],
25 | "toc_visible": true
26 | },
27 | "kernelspec": {
28 | "name": "python3",
29 | "display_name": "Python 3"
30 | },
31 | "accelerator": "GPU"
32 | },
33 | "cells": [
34 | {
35 | "cell_type": "markdown",
36 | "metadata": {
37 | "id": "view-in-github",
38 | "colab_type": "text"
39 | },
40 | "source": [
41 | "
"
42 | ]
43 | },
44 | {
45 | "cell_type": "markdown",
46 | "metadata": {
47 | "id": "pety7rf841Dg",
48 | "colab_type": "text"
49 | },
50 | "source": [
51 | "# ** FFmpeg for GDrive - Shared by [cheems](https://github.com/cheems) **"
52 | ]
53 | },
54 | {
55 | "cell_type": "markdown",
56 | "metadata": {
57 | "id": "EFOqhHG6hOVH",
58 | "colab_type": "text"
59 | },
60 | "source": [
61 | "#__1. Install FFmpeg__"
62 | ]
63 | },
64 | {
65 | "cell_type": "code",
66 | "metadata": {
67 | "id": "hFeE-qPuhTiK",
68 | "colab_type": "code",
69 | "cellView": "form",
70 | "colab": {}
71 | },
72 | "source": [
73 | "#@markdown
\n",
74 | "#@markdown Upgrade FFmpeg to v4.2.2
\n",
75 | "from IPython.display import clear_output\n",
76 | "import os, urllib.request\n",
77 | "HOME = os.path.expanduser(\"~\")\n",
78 | "pathDoneCMD = f'{HOME}/doneCMD.sh'\n",
79 | "if not os.path.exists(f\"{HOME}/.ipython/ttmg.py\"):\n",
80 | " hCode = \"https://raw.githubusercontent.com/cheems/FFmpeg-for-GDrive/master/ttmg.py\"\n",
81 | " urllib.request.urlretrieve(hCode, f\"{HOME}/.ipython/ttmg.py\")\n",
82 | "\n",
83 | "from ttmg import (\n",
84 | " loadingAn,\n",
85 | " textAn,\n",
86 | ")\n",
87 | "\n",
88 | "loadingAn(name=\"lds\")\n",
89 | "textAn(\"Installing Dependencies...\", ty='twg')\n",
90 | "os.system('pip install git+git://github.com/AWConant/jikanpy.git')\n",
91 | "os.system('add-apt-repository -y ppa:jonathonf/ffmpeg-4')\n",
92 | "os.system('apt-get update')\n",
93 | "os.system('apt install mediainfo')\n",
94 | "os.system('apt-get install ffmpeg')\n",
95 | "clear_output()\n",
96 | "print('Installation finished.')"
97 | ],
98 | "execution_count": null,
99 | "outputs": []
100 | },
101 | {
102 | "cell_type": "markdown",
103 | "metadata": {
104 | "id": "CUq1_Dnegrs1",
105 | "colab_type": "text"
106 | },
107 | "source": [
108 | "#__2. Mount Google Drive__\n",
109 | "\n",
110 | "\n",
111 | "\n"
112 | ]
113 | },
114 | {
115 | "cell_type": "code",
116 | "metadata": {
117 | "id": "ojI73noUg1If",
118 | "colab_type": "code",
119 | "colab": {},
120 | "cellView": "form"
121 | },
122 | "source": [
123 | "#@markdown
\n",
124 | "#@markdown Mount GDrive to /content/drive
\n",
125 | "MODE = \"MOUNT\" #@param [\"MOUNT\", \"UNMOUNT\"]\n",
126 | "#Mount your Gdrive! \n",
127 | "from google.colab import drive\n",
128 | "drive.mount._DEBUG = False\n",
129 | "if MODE == \"MOUNT\":\n",
130 | " drive.mount('/content/drive', force_remount=True)\n",
131 | "elif MODE == \"UNMOUNT\":\n",
132 | " try:\n",
133 | " drive.flush_and_unmount()\n",
134 | " except ValueError:\n",
135 | " pass\n",
136 | " get_ipython().system_raw(\"rm -rf /root/.config/Google/DriveFS\")"
137 | ],
138 | "execution_count": null,
139 | "outputs": []
140 | },
141 | {
142 | "cell_type": "markdown",
143 | "metadata": {
144 | "id": "KgNPvGccgwd8",
145 | "colab_type": "text"
146 | },
147 | "source": [
148 | "#__3. Run FFmpeg Scripts (Convert, Edit, Trim + more)__"
149 | ]
150 | },
151 | {
152 | "cell_type": "markdown",
153 | "metadata": {
154 | "id": "RDHuIkoi6l9a",
155 | "colab_type": "text"
156 | },
157 | "source": [
158 | "###__Display Media File Metadata__"
159 | ]
160 | },
161 | {
162 | "cell_type": "code",
163 | "metadata": {
164 | "id": "Sv8au_RO6WUs",
165 | "colab_type": "code",
166 | "cellView": "form",
167 | "colab": {}
168 | },
169 | "source": [
170 | "import os, sys, re\n",
171 | "\n",
172 | "media_file_path = \"\" #@param {type:\"string\"}\n",
173 | "\n",
174 | "os.environ['inputFile'] = media_file_path\n",
175 | "\n",
176 | "!ffmpeg -i \"$inputFile\" -hide_banner"
177 | ],
178 | "execution_count": null,
179 | "outputs": []
180 | },
181 | {
182 | "cell_type": "markdown",
183 | "metadata": {
184 | "id": "X4yIG_nqYAoH",
185 | "colab_type": "text"
186 | },
187 | "source": [
188 | "> *You can ignore the* \"`At least one output file must be specified`\" *error after running this.*\n",
189 | "\n",
190 | "\n"
191 | ]
192 | },
193 | {
194 | "cell_type": "markdown",
195 | "metadata": {
196 | "id": "NQ0TxfKeghR8",
197 | "colab_type": "text"
198 | },
199 | "source": [
200 | "###__Convert Video File ➔ .mp4 (Lossless)__"
201 | ]
202 | },
203 | {
204 | "cell_type": "code",
205 | "metadata": {
206 | "id": "Ls4O5VLwief-",
207 | "colab_type": "code",
208 | "cellView": "form",
209 | "colab": {}
210 | },
211 | "source": [
212 | "import os, sys, re\n",
213 | "\n",
214 | "video_file_path = \"\" #@param {type:\"string\"}\n",
215 | "\n",
216 | "output_file_path = re.search(\"^[\\/].+\\/\", video_file_path)\n",
217 | "output_file_path_raw = output_file_path.group(0)\n",
218 | "delsplit = re.search(\"\\/(?:.(?!\\/))+$\", video_file_path)\n",
219 | "filename = re.sub(\"^[\\/]\", \"\", delsplit.group(0))\n",
220 | "filename_raw = re.sub(\".{4}$\", \"\", filename)\n",
221 | "file_extension = re.search(\".{3}$\", filename)\n",
222 | "file_extension_raw = file_extension.group(0)\n",
223 | "\n",
224 | "os.environ['inputFile'] = video_file_path\n",
225 | "os.environ['outputPath'] = output_file_path_raw\n",
226 | "os.environ['fileName'] = filename_raw\n",
227 | "os.environ['fileExtension'] = file_extension_raw\n",
228 | "\n",
229 | "!ffmpeg -hide_banner -i \"$inputFile\" -c copy -strict -2 \"$outputPath\"/\"$fileName\".mp4"
230 | ],
231 | "execution_count": null,
232 | "outputs": []
233 | },
234 | {
235 | "cell_type": "markdown",
236 | "metadata": {
237 | "colab_type": "text",
238 | "id": "NObEcBWAJoaz"
239 | },
240 | "source": [
241 | "###__Convert Video File ➔ .mkv (Lossless)__"
242 | ]
243 | },
244 | {
245 | "cell_type": "code",
246 | "metadata": {
247 | "colab_type": "code",
248 | "cellView": "form",
249 | "id": "zsx4JFLRJoa0",
250 | "colab": {}
251 | },
252 | "source": [
253 | "import os, sys, re\n",
254 | "\n",
255 | "video_file_path = \"\" #@param {type:\"string\"}\n",
256 | "\n",
257 | "output_file_path = re.search(\"^[\\/].+\\/\", video_file_path)\n",
258 | "output_file_path_raw = output_file_path.group(0)\n",
259 | "delsplit = re.search(\"\\/(?:.(?!\\/))+$\", video_file_path)\n",
260 | "filename = re.sub(\"^[\\/]\", \"\", delsplit.group(0))\n",
261 | "filename_raw = re.sub(\".{4}$\", \"\", filename)\n",
262 | "file_extension = re.search(\".{3}$\", filename)\n",
263 | "file_extension_raw = file_extension.group(0)\n",
264 | "\n",
265 | "os.environ['inputFile'] = video_file_path\n",
266 | "os.environ['outputPath'] = output_file_path_raw\n",
267 | "os.environ['fileName'] = filename_raw\n",
268 | "os.environ['fileExtension'] = file_extension_raw\n",
269 | "\n",
270 | "!ffmpeg -hide_banner -i \"$inputFile\" -c copy -strict -2 \"$outputPath\"/\"$fileName\".mkv"
271 | ],
272 | "execution_count": null,
273 | "outputs": []
274 | },
275 | {
276 | "cell_type": "markdown",
277 | "metadata": {
278 | "id": "FpJXJiRl6-gK",
279 | "colab_type": "text"
280 | },
281 | "source": [
282 | "###__Trim Video File (Lossless)__"
283 | ]
284 | },
285 | {
286 | "cell_type": "code",
287 | "metadata": {
288 | "id": "iFBUeQhn7QTc",
289 | "colab_type": "code",
290 | "cellView": "form",
291 | "colab": {}
292 | },
293 | "source": [
294 | "import os, sys, re\n",
295 | "\n",
296 | "video_file_path = \"\" #@param {type:\"string\"}\n",
297 | "start_time = \"00:00:00.000\" #@param {type:\"string\"}\n",
298 | "end_time = \"00:01:00.000\" #@param {type:\"string\"}\n",
299 | "\n",
300 | "output_file_path = re.search(\"^[\\/].+\\/\", video_file_path)\n",
301 | "output_file_path_raw = output_file_path.group(0)\n",
302 | "delsplit = re.search(\"\\/(?:.(?!\\/))+$\", video_file_path)\n",
303 | "filename = re.sub(\"^[\\/]\", \"\", delsplit.group(0))\n",
304 | "filename_raw = re.sub(\".{4}$\", \"\", filename)\n",
305 | "file_extension = re.search(\".{3}$\", filename)\n",
306 | "file_extension_raw = file_extension.group(0)\n",
307 | "\n",
308 | "os.environ['inputFile'] = video_file_path\n",
309 | "os.environ['outputPath'] = output_file_path_raw\n",
310 | "os.environ['startTime'] = start_time\n",
311 | "os.environ['endTime'] = end_time\n",
312 | "os.environ['fileName'] = filename_raw\n",
313 | "os.environ['fileExtension'] = file_extension_raw\n",
314 | "\n",
315 | "!ffmpeg -hide_banner -i \"$inputFile\" -ss \"$startTime\" -to \"$endTime\" -c copy \"$outputPath\"/\"$fileName\"-TRIM.\"$fileExtension\""
316 | ],
317 | "execution_count": null,
318 | "outputs": []
319 | },
320 | {
321 | "cell_type": "markdown",
322 | "metadata": {
323 | "colab_type": "text",
324 | "id": "SNDGdMRn3PA-"
325 | },
326 | "source": [
327 | "###__Crop Video__"
328 | ]
329 | },
330 | {
331 | "cell_type": "markdown",
332 | "metadata": {
333 | "id": "KFcIThDuBii_",
334 | "colab_type": "text"
335 | },
336 | "source": [
337 | " Crop Variables Explanation:\n",
338 | "\n",
339 | "* `out_width` = The width of your cropped video file.\n",
340 | "* `out_height` = The height of your cropped video file.\n",
341 | "* `starting_position_x` & `starting_position_y` = These values define the x & y coordinates of the top left corner of your original video to start cropping from.\n",
342 | "\n",
343 | "###### *Example: For cropping the black bars from a video that looked like* [this](https://i.imgur.com/ud8nbvT.png):\n",
344 | "* *For your starting coordinates* (`x` , `y`) *you would use* (`0` , `138`).\n",
345 | "* *For* `out_width` *you would use* `1920`. *And for* `out_height` *you would use `804`.*\n",
346 | "\n",
347 | "\n",
348 | "\n"
349 | ]
350 | },
351 | {
352 | "cell_type": "code",
353 | "metadata": {
354 | "colab_type": "code",
355 | "cellView": "form",
356 | "id": "CEHi5EMm9lXG",
357 | "colab": {}
358 | },
359 | "source": [
360 | "import os, sys, re\n",
361 | "\n",
362 | "video_file_path = \"\" #@param {type:\"string\"}\n",
363 | "out_width = \"1920\" #@param {type:\"string\"}\n",
364 | "out_height = \"804\" #@param {type:\"string\"}\n",
365 | "starting_position_x = \"0\" #@param {type:\"string\"}\n",
366 | "starting_position_y = \"138\" #@param {type:\"string\"}\n",
367 | "\n",
368 | "output_file_path = re.search(\"^[\\/].+\\/\", video_file_path)\n",
369 | "output_file_path_raw = output_file_path.group(0)\n",
370 | "delsplit = re.search(\"\\/(?:.(?!\\/))+$\", video_file_path)\n",
371 | "filename = re.sub(\"^[\\/]\", \"\", delsplit.group(0))\n",
372 | "filename_raw = re.sub(\".{4}$\", \"\", filename)\n",
373 | "file_extension = re.search(\".{3}$\", filename)\n",
374 | "file_extension_raw = file_extension.group(0)\n",
375 | "\n",
376 | "os.environ['inputFile'] = video_file_path\n",
377 | "os.environ['outputPath'] = output_file_path_raw\n",
378 | "os.environ['outWidth'] = out_width\n",
379 | "os.environ['outHeight'] = out_height\n",
380 | "os.environ['positionX'] = starting_position_x\n",
381 | "os.environ['positionY'] = starting_position_y\n",
382 | "os.environ['fileName'] = filename_raw\n",
383 | "os.environ['fileExtension'] = file_extension_raw\n",
384 | "\n",
385 | "!ffmpeg -hide_banner -i \"$inputFile\" -filter:v \"crop=$outWidth:$outHeight:$positionX:$positionY\" \"$outputPath\"/\"$fileName\"-CROP.\"$fileExtension\""
386 | ],
387 | "execution_count": null,
388 | "outputs": []
389 | },
390 | {
391 | "cell_type": "markdown",
392 | "metadata": {
393 | "colab_type": "text",
394 | "id": "2f-THZmDoOaY"
395 | },
396 | "source": [
397 | "###__Extract Audio from Video File (Lossless)__"
398 | ]
399 | },
400 | {
401 | "cell_type": "code",
402 | "metadata": {
403 | "id": "nSeO98YQoTJe",
404 | "colab_type": "code",
405 | "cellView": "form",
406 | "colab": {}
407 | },
408 | "source": [
409 | "import os, sys, re\n",
410 | "\n",
411 | "video_file_path = \"\" #@param {type:\"string\"}\n",
412 | "output_file_extension = 'm4a' #@param [\"m4a\", \"mp3\", \"opus\", \"flac\", \"wav\"]\n",
413 | "\n",
414 | "delsplit = re.search(\"\\/(?:.(?!\\/))+$\", video_file_path)\n",
415 | "output_file_path = re.search(\"^[\\/].+\\/\", video_file_path)\n",
416 | "filename = re.sub(\"^[\\/]\", \"\", delsplit.group(0))\n",
417 | "filename_raw = re.sub(\".{4}$\", \"\", filename)\n",
418 | "\n",
419 | "os.environ['inputFile'] = video_file_path\n",
420 | "os.environ['outputPath'] = output_file_path.group(0)\n",
421 | "os.environ['fileName'] = filename_raw\n",
422 | "os.environ['fileType'] = output_file_extension\n",
423 | "\n",
424 | "!ffmpeg -hide_banner -i \"$inputFile\" -vn -c:a copy \"$outputPath\"/\"$fileName\"-audio.\"$fileType\""
425 | ],
426 | "execution_count": null,
427 | "outputs": []
428 | },
429 | {
430 | "cell_type": "markdown",
431 | "metadata": {
432 | "id": "MSUasbRUDP3B",
433 | "colab_type": "text"
434 | },
435 | "source": [
436 | "###__Re-encode a Video to a Different Resolution__"
437 | ]
438 | },
439 | {
440 | "cell_type": "code",
441 | "metadata": {
442 | "id": "nd2LvSRZCxRe",
443 | "colab_type": "code",
444 | "cellView": "form",
445 | "colab": {}
446 | },
447 | "source": [
448 | "import os, sys, re\n",
449 | "\n",
450 | "video_file_path = '' #@param {type:\"string\"}\n",
451 | "resolution = '1080p' #@param [\"2160p\", \"1440p\", \"1080p\", \"720p\", \"480p\", \"360p\", \"240p\"]\n",
452 | "file_type = 'mp4' #@param [\"mkv\", \"mp4\"]\n",
453 | "\n",
454 | "delsplit = re.search(\"\\/(?:.(?!\\/))+$\", video_file_path)\n",
455 | "testsplit = video_file_path.split(\"/\")\n",
456 | "filename = re.sub(\"^[\\/]\", \"\", delsplit.group(0))\n",
457 | "filename_raw = re.sub(\".{4}$\", \"\", filename)\n",
458 | "resolution_raw = re.search(\"[^p]{3,4}\", resolution)\n",
459 | "output_file_path = re.search(\"^[\\/].+\\/\", video_file_path)\n",
460 | "\n",
461 | "os.environ['inputFile'] = video_file_path\n",
462 | "os.environ['outputPath'] = output_file_path.group(0)\n",
463 | "os.environ['fileName'] = filename_raw\n",
464 | "os.environ['fileType'] = file_type\n",
465 | "os.environ['resolutionHeight'] = resolution_raw.group(0)\n",
466 | "\n",
467 | "!ffmpeg -hide_banner -i \"$inputFile\" -vf \"scale=-1:\"$resolutionHeight\"\" -c:a copy -strict experimental \"$outputPath\"/\"$fileName\"-\"$resolutionHeight\"p.\"$fileType\""
468 | ],
469 | "execution_count": null,
470 | "outputs": []
471 | },
472 | {
473 | "cell_type": "markdown",
474 | "metadata": {
475 | "colab_type": "text",
476 | "id": "9UagRtLPyKoQ"
477 | },
478 | "source": [
479 | "###__Extract Individual Frames from Video__"
480 | ]
481 | },
482 | {
483 | "cell_type": "code",
484 | "metadata": {
485 | "colab_type": "code",
486 | "cellView": "form",
487 | "id": "jTnByMhAyKoF",
488 | "colab": {}
489 | },
490 | "source": [
491 | "#@markdown This will create a folder in the same directory titled \"`Extracted Frames`\"\n",
492 | "#@markdown - [Example](https://i.imgur.com/yPDk1hO.png) of output folder\n",
493 | "import os, sys, re\n",
494 | "\n",
495 | "video_file_path = \"\" #@param {type:\"string\"}\n",
496 | "start_time = \"00:01:00.000\" #@param {type:\"string\"}\n",
497 | "end_time = \"00:01:05.000\" #@param {type:\"string\"}\n",
498 | "frame_rate = \"23.976\" #@param {type:\"string\"}\n",
499 | "\n",
500 | "output_file_path = re.search(\"^[\\/].+\\/\", video_file_path)\n",
501 | "output_file_path_raw = output_file_path.group(0)\n",
502 | "delsplit = re.search(\"\\/(?:.(?!\\/))+$\", video_file_path)\n",
503 | "filename = re.sub(\"^[\\/]\", \"\", delsplit.group(0))\n",
504 | "filename_raw = re.sub(\".{4}$\", \"\", filename)\n",
505 | "file_extension = re.search(\".{3}$\", filename)\n",
506 | "file_extension_raw = file_extension.group(0)\n",
507 | "\n",
508 | "os.environ['inputFile'] = video_file_path\n",
509 | "os.environ['outputPath'] = output_file_path_raw\n",
510 | "os.environ['startTime'] = start_time\n",
511 | "os.environ['endTime'] = end_time\n",
512 | "os.environ['frameRate'] = frame_rate\n",
513 | "os.environ['fileName'] = filename_raw\n",
514 | "os.environ['fileExtension'] = file_extension_raw\n",
515 | "\n",
516 | "!mkdir \"$outputPath\"/\"Extracted Frames\"\n",
517 | "!ffmpeg -hide_banner -i \"$inputFile\" -ss \"$startTime\" -to \"$endTime\" -r \"$frameRate\"/1 \"$outputPath\"/\"Extracted Frames\"/frame%04d.png"
518 | ],
519 | "execution_count": null,
520 | "outputs": []
521 | },
522 | {
523 | "cell_type": "markdown",
524 | "metadata": {
525 | "colab_type": "text",
526 | "id": "GahMjYf8miNs"
527 | },
528 | "source": [
529 | "###__Generate Thumbnails - Preview from Video (3x2)__"
530 | ]
531 | },
532 | {
533 | "cell_type": "code",
534 | "metadata": {
535 | "colab_type": "code",
536 | "cellView": "form",
537 | "id": "J2u-Rha8miNy",
538 | "colab": {}
539 | },
540 | "source": [
541 | "#@markdown Example of output image: https://i.imgur.com/0ymP144.png
\n",
542 | "import os, sys, re\n",
543 | "\n",
544 | "video_file_path = \"\" #@param {type:\"string\"}\n",
545 | "output_file_type = 'png' #@param [\"png\", \"jpg\"]\n",
546 | "\n",
547 | "output_file_path = re.search(\"^[\\/].+\\/\", video_file_path)\n",
548 | "output_file_path_raw = output_file_path.group(0)\n",
549 | "delsplit = re.search(\"\\/(?:.(?!\\/))+$\", video_file_path)\n",
550 | "filename = re.sub(\"^[\\/]\", \"\", delsplit.group(0))\n",
551 | "filename_raw = re.sub(\".{4}$\", \"\", filename)\n",
552 | "file_extension = re.search(\".{3}$\", filename)\n",
553 | "file_extension_raw = file_extension.group(0)\n",
554 | "\n",
555 | "os.environ['inputFile'] = video_file_path\n",
556 | "os.environ['outputPath'] = output_file_path_raw\n",
557 | "os.environ['outputExtension'] = output_file_type\n",
558 | "os.environ['fileName'] = filename_raw\n",
559 | "os.environ['fileExtension'] = file_extension_raw\n",
560 | "\n",
561 | "!ffmpeg -hide_banner -i \"$inputFile\" -vframes 1 -q:v 2 -vf \"select=not(mod(n\\,200)),scale=-1:480,tile=3x2\" -an \"$outputPath\"/\"$fileName\"_thumbnails.\"$outputExtension\""
562 | ],
563 | "execution_count": null,
564 | "outputs": []
565 | },
566 | {
567 | "cell_type": "markdown",
568 | "metadata": {
569 | "id": "7-3O4en4C4IL",
570 | "colab_type": "text"
571 | },
572 | "source": [
573 | "###__Convert Audio Filetype (mp3, m4a, ogg, flac, etc.)__"
574 | ]
575 | },
576 | {
577 | "cell_type": "code",
578 | "metadata": {
579 | "id": "aURlOf9BC1P3",
580 | "colab_type": "code",
581 | "cellView": "form",
582 | "colab": {}
583 | },
584 | "source": [
585 | "import os, sys, re\n",
586 | "\n",
587 | "audio_file_path = \"\" #@param {type:\"string\"}\n",
588 | "output_file_type = \"mp3\" #@param [\"mp3\", \"ogg\", \"m4a\", \"opus\", \"flac\", \"alac\", \"wav\"]\n",
589 | "\n",
590 | "output_file_path = re.search(\"^[\\/].+\\/\", audio_file_path)\n",
591 | "output_file_path_raw = output_file_path.group(0)\n",
592 | "delsplit = re.search(\"\\/(?:.(?!\\/))+$\", audio_file_path)\n",
593 | "filename = re.sub(\"^[\\/]\", \"\", delsplit.group(0))\n",
594 | "filename_raw = re.sub(\".{4}$\", \"\", filename)\n",
595 | "file_extension = re.search(\".{3}$\", filename)\n",
596 | "file_extension_raw = file_extension.group(0)\n",
597 | "\n",
598 | "os.environ['inputFile'] = audio_file_path\n",
599 | "os.environ['outputPath'] = output_file_path_raw\n",
600 | "os.environ['fileExtension'] = output_file_type\n",
601 | "os.environ['fileName'] = filename_raw\n",
602 | "\n",
603 | "!ffmpeg -hide_banner -i \"$inputFile\" \"$outputPath\"/\"$fileName\"converted.\"$fileExtension\""
604 | ],
605 | "execution_count": null,
606 | "outputs": []
607 | },
608 | {
609 | "cell_type": "markdown",
610 | "metadata": {
611 | "colab_type": "text",
612 | "id": "VRk2Ye1exWVA"
613 | },
614 | "source": [
615 | "###__Sharable Links of Randomly Extracted Frames from Video__"
616 | ]
617 | },
618 | {
619 | "cell_type": "code",
620 | "metadata": {
621 | "colab_type": "code",
622 | "cellView": "form",
623 | "id": "BIGsgarfxWVI",
624 | "colab": {}
625 | },
626 | "source": [
627 | "import os, re, time, pathlib\n",
628 | "import urllib.request\n",
629 | "from IPython.display import clear_output\n",
630 | "\n",
631 | "Auto_UP_Gdrive = False \n",
632 | "AUTO_MOVE_PATH = \"/content\" \n",
633 | "HOME = os.path.expanduser(\"~\")\n",
634 | "pathDoneCMD = f'{HOME}/doneCMD.sh'\n",
635 | "\n",
636 | "if not os.path.exists(f\"{HOME}/.ipython/ttmg.py\"):\n",
637 | " hCode = \"https://raw.githubusercontent.com/biplobsd/\" \\\n",
638 | " \"Google-Colab-CloudTorrent/master/res/ttmg.py\"\n",
639 | " urllib.request.urlretrieve(hCode, f\"{HOME}/.ipython/ttmg.py\")\n",
640 | "\n",
641 | "from ttmg import (\n",
642 | " runSh,\n",
643 | " findProcess,\n",
644 | " loadingAn,\n",
645 | " updateCheck,\n",
646 | " ngrok\n",
647 | ")\n",
648 | "\n",
649 | "video_file_path = \"\" #@param {type:\"string\"}\n",
650 | "\n",
651 | "output_file_path = re.search(\"^[\\/].+\\/\", video_file_path)\n",
652 | "output_file_path_raw = output_file_path.group(0)\n",
653 | "delsplit = re.search(\"\\/(?:.(?!\\/))+$\", video_file_path)\n",
654 | "filename = re.sub(\"^[\\/]\", \"\", delsplit.group(0))\n",
655 | "filename_raw = re.sub(\".{4}$\", \"\", filename)\n",
656 | "file_extension = re.search(\".{3}$\", filename)\n",
657 | "file_extension_raw = file_extension.group(0)\n",
658 | "\n",
659 | "os.environ['inputFile'] = video_file_path\n",
660 | "os.environ['outputPath'] = output_file_path_raw\n",
661 | "os.environ['fileName'] = filename_raw\n",
662 | "os.environ['fileExtension'] = file_extension_raw\n",
663 | "\n",
664 | "!mkdir -p \"/content/frames\"\n",
665 | "\n",
666 | "for i in range(10):\n",
667 | " clear_output()\n",
668 | " loadingAn()\n",
669 | " print(\"Uploading Frames...\")\n",
670 | "\n",
671 | "%cd \"/content/frames\"\n",
672 | "!ffmpeg -hide_banner -ss 00:56.0 -i \"$inputFile\" -vframes 1 -q:v 1 -y \"/content/frames/frame1.png\"\n",
673 | "!curl --silent -F \"reqtype=fileupload\" -F \"fileToUpload=@frame1.png\" https://catbox.moe/user/api.php -o frame1.txt\n",
674 | "f1 = open('frame1.txt', 'r')\n",
675 | "%cd \"/content\"\n",
676 | "file_content1 = f1.read()\n",
677 | "\n",
678 | "%cd \"/content/frames\"\n",
679 | "!ffmpeg -hide_banner -ss 02:20.0 -i \"$inputFile\" -vframes 1 -q:v 1 -y \"/content/frames/frame2.png\"\n",
680 | "!curl --silent -F \"reqtype=fileupload\" -F \"fileToUpload=@frame2.png\" https://catbox.moe/user/api.php -o frame2.txt\n",
681 | "%cd \"/content/frames\"\n",
682 | "f2 = open('frame2.txt', 'r')\n",
683 | "%cd \"/content\"\n",
684 | "file_content2 = f2.read()\n",
685 | "\n",
686 | "clear_output()\n",
687 | "print (\"Screenshot URLs:\")\n",
688 | "print (\"1. \" + file_content1)\n",
689 | "print (\"2. \" + file_content2)"
690 | ],
691 | "execution_count": null,
692 | "outputs": []
693 | },
694 | {
695 | "cell_type": "markdown",
696 | "metadata": {
697 | "id": "tozwpAhhnm69",
698 | "colab_type": "text"
699 | },
700 | "source": [
701 | "\n",
702 | "###__MediaInfo__"
703 | ]
704 | },
705 | {
706 | "cell_type": "code",
707 | "metadata": {
708 | "id": "NTULRguzu0b0",
709 | "colab_type": "code",
710 | "cellView": "form",
711 | "colab": {}
712 | },
713 | "source": [
714 | "path = \"\" #@param {type:\"string\"}\n",
715 | "save_txt = True #@param {type:\"boolean\"}\n",
716 | "import os, uuid, re, IPython\n",
717 | "import ipywidgets as widgets\n",
718 | "import time\n",
719 | "\n",
720 | "from glob import glob\n",
721 | "from IPython.display import HTML, clear_output\n",
722 | "from google.colab import output, drive\n",
723 | "\n",
724 | "def mediainfo():\n",
725 | " display(HTML(\"
\"))\n",
726 | "# print(path.split(\"/\")[::-1][0])\n",
727 | " display(HTML(\"
\"))\n",
728 | "# media = !mediainfo \"$path\"\n",
729 | "# media = \"\\n\".join(media).replace(os.path.dirname(path)+\"/\", \"\")\n",
730 | " get_ipython().system_raw(\"\"\"mediainfo --LogFile=\"/root/.nfo\" \"$path\" \"\"\")\n",
731 | " with open('/root/.nfo', 'r') as file:\n",
732 | " media = file.read()\n",
733 | " media = media.replace(os.path.dirname(path)+\"/\", \"\")\n",
734 | " print(media)\n",
735 | " get_ipython().system_raw(\"rm -f '/root/.nfo'\")\n",
736 | " \n",
737 | " if save_txt:\n",
738 | " txt = path.rpartition('.')[0] + \".txt\"\n",
739 | " if os.path.exists(txt):\n",
740 | " get_ipython().system_raw(\"rm -f '$txt'\")\n",
741 | " !curl -s https://pastebin.com/raw/TV8Byydt -o \"$txt\"\n",
742 | " with open(txt, 'a+') as file:\n",
743 | " file.write(\"\\n\\n\")\n",
744 | " file.write(media)\n",
745 | "\n",
746 | "while not os.path.exists(\"/content/drive\"):\n",
747 | " try:\n",
748 | " drive.mount(\"/content/drive\")\n",
749 | " clear_output(wait=True)\n",
750 | " except:\n",
751 | " clear_output()\n",
752 | " \n",
753 | "if not os.path.exists(\"/usr/bin/mediainfo\"):\n",
754 | " get_ipython().system_raw(\"apt-get install mediainfo\")\n",
755 | " \n",
756 | "mediainfo()"
757 | ],
758 | "execution_count": null,
759 | "outputs": []
760 | },
761 | {
762 | "cell_type": "markdown",
763 | "metadata": {
764 | "id": "XDp_IAgx46fP",
765 | "colab_type": "text"
766 | },
767 | "source": [
768 | "# 📚 Follow me on GitHub for more: [_@cheems_](https://github.com/cheems)\n",
769 | "# 📦 Repo: [Github](https://github.com/cheems/FFmpeg-for-GDrive)"
770 | ]
771 | }
772 | ]
773 | }
774 |
--------------------------------------------------------------------------------