├── 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 | Open In Colab 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('''
'''+TEXT+'''
''')) 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('

Open Latest Version

')) 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 | "\"Open" 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
\"Gdrive-logo\"/
\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
\"Gdrive-logo\"/
\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 | --------------------------------------------------------------------------------