def mergerByTsfiles(self, srcfilepaths, filepath, showshell=False): """ #Func : 合并ts文件 #Return : True/False """ filepath = os.path.abspath(filepath) exten = pathHelper.getFileExtension(filepath) tmppath = filepath.replace(exten, '.ts') tmppath2 = filepath.replace(exten, '2.ts') array = [ srcfilepaths[i:i + 25] for i in range(0, len(srcfilepaths), 25) ] pathHelper.remove(tmppath) pathHelper.remove(tmppath2) for item in array: for index, file in enumerate(item): item[index] = '"' + file + '"' form = ' + '.join(item) if os.access(tmppath, 0): form = '"' + tmppath + '" + ' + form cmd = 'copy /b ' + form + ' "' + tmppath2 + '"' ret = self.__process(cmd, 3, showshell, tmppath2) if ret is False: break pathHelper.remove(tmppath) os.rename(tmppath2, tmppath) if ret is True: cmd = "ffmpeg -i \"" + tmppath + "\" -c copy \"" + filepath + "\"" ret = self.__process(cmd, 3, showshell, filepath) pathHelper.remove(tmppath) pathHelper.remove(tmppath2) return ret
def setTrackMetadata(self, track_info, file_path, album_info, index): path = pathHelper.getDirName(file_path) name = pathHelper.getFileNameWithoutExtension(file_path) exte = pathHelper.getFileExtension(file_path) tmpfile = path + '/' + self.tmpfileFlag + name + exte try: tag = { 'Artist': track_info['artist']['name'], 'Album': track_info['album']['title'], 'Title': track_info['title'], 'CopyRight': track_info['copyright'], 'Track': track_info['trackNumber'] } if index is not None: tag['Track'] = str(index) if album_info is not None: tag['Date'] = album_info['releaseDate'] tag['Year'] = album_info['releaseDate'].split('-')[0] # tmp file pathHelper.copyFile(file_path, tmpfile) # set metadata ext = os.path.splitext(tmpfile)[1][1:] data = AudioSegment.from_file(tmpfile, ext) check = data.export(tmpfile, format=ext, tags=tag) # check file size if fileHelper.getFileSize(tmpfile) > 0: pathHelper.remove(file_path) pathHelper.copyFile(tmpfile, file_path) except: pass if os.access(tmpfile, 0): pathHelper.remove(tmpfile)
def __convertToM4a__(filepath, codec): if 'ac4' in codec or 'mha1' in codec: return filepath if '.mp4' not in filepath: return filepath newpath = filepath.replace('.mp4', '.m4a') remove(newpath) os.rename(filepath, newpath) return newpath
def covertMp4toM4a(self, file_path): if self.config.onlym4a != "True": return file_path if '.mp4' not in file_path: return file_path if not self.ffmpeg.enable: return file_path new_path = file_path.replace('.mp4', '.m4a') pathHelper.remove(new_path) if self.ffmpeg.covertFile(file_path, new_path): pathHelper.remove(file_path) return new_path else: return file_path
def _checkTool(self): check = False try: cmd = "ffmpeg -V" stdoutFile = 'ffmpegcheck-stdout.txt' fp = open(stdoutFile, 'w') if sys.version_info[0] > 2: res = subprocess.call(cmd, timeout=self.mergerTimeout, shell=True, stdout=fp, stderr=fp) else: res = subprocess.call(cmd, shell=True, stdout=fp, stderr=fp) fp.close() txt = fileHelper.getFileContent(stdoutFile) if 'version' in txt and 'Copyright' in txt: check = True except: pass pathHelper.remove(stdoutFile) return check
def mergerByTs(self, srcDir, filepath, showshell=False): srcDir = os.path.abspath(srcDir) filepath = os.path.abspath(filepath) if os.path.exists(srcDir) is False: return False exten = pathHelper.getFileExtension(filepath) tmppath = filepath.replace(exten, '.ts') if systemHelper.isWindows(): srcDir += '\\*.ts' cmd = 'copy /b "' + srcDir + '" "' + tmppath + '"' else: srcDir += '/*.ts' cmd = 'cat ' + srcDir + ' > "' + tmppath + '"' ret = self.__process(cmd, 3, showshell, tmppath) if ret is True: cmd = "ffmpeg -i \"" + tmppath + "\" -c copy \"" + filepath + "\"" ret = self.__process(cmd, 3, showshell, filepath) pathHelper.remove(tmppath) return ret
def mergerByM3u8_Multithreading2(self, url, filepath, showprogress=False, showshell=False): try: # Get urllist urllist = self.__parseM3u8(url) if len(urllist) <= 0: return False sdir = pathHelper.getDirName(filepath) pathHelper.mkdirs(sdir) ext = pathHelper.getFileExtension(filepath) tspath = filepath.replace(ext, '.ts') pathHelper.remove(tspath) if not netHelper.downloadFileByUrls(urllist, tspath, 30, True): return False if self.covertFile(tspath, filepath): pathHelper.remove(tspath) return True return False except: return False
def setTag(self, tag, srcfile, coverpath=None): path = pathHelper.getDirName(srcfile) name = pathHelper.getFileNameWithoutExtension(srcfile) ext = pathHelper.getFileExtension(srcfile) oext = ext if 'm4a' in ext or 'mp4' in ext: oext = '.mp3' if 'mp3' not in oext: coverpath = None tmpfile = path + '/' + 'TMP' + name + oext try: data = AudioSegment.from_file(srcfile, format=ext[1:]) check = data.export(tmpfile, format=oext[1:], tags=tag, cover=coverpath) check.close() except Exception as e: pathHelper.remove(tmpfile) return if fileHelper.getFileSize(tmpfile) > 0: pathHelper.remove(srcfile) os.rename(tmpfile, path + '/' + name + oext) else: pathHelper.remove(tmpfile)
def __process(self, cmd, retrycount, showshell, filename, removeFile=True): stdoutFile = None fp = None while retrycount >= 0: retrycount -= 1 try: if showshell: if sys.version_info[0] > 2: res = subprocess.call(cmd, timeout=self.mergerTimeout, shell=True) else: cmd = cmd.encode(sys.getfilesystemencoding()) res = subprocess.call(cmd, shell=True) else: exten = pathHelper.getFileExtension(filename) stdoutFile = filename.replace(exten, '-stdout.txt') fp = open(stdoutFile, 'w') if sys.version_info[0] > 2: res = subprocess.call(cmd, timeout=self.mergerTimeout, shell=True, stdout=fp, stderr=fp) else: res = subprocess.call(cmd, shell=True, stdout=fp, stderr=fp) fp.close() fp = None pathHelper.remove(stdoutFile) if res == 0: return True except: pass if fp: fp.close() pathHelper.remove(stdoutFile) if removeFile: pathHelper.remove(filename) return False
def __process(self, cmd, retrycount, showshell, filename): stdoutFile = None while retrycount >= 0: retrycount -= 1 try: if showshell: res = subprocess.call(cmd, timeout=self.mergerTimeout, shell=True) else: exten = pathHelper.getFileExtension(filename) stdoutFile = filename.replace(exten, '-stdout.txt') fp = open(stdoutFile, 'w') res = subprocess.call(cmd, timeout=self.mergerTimeout, shell=True, stdout=fp, stderr=fp) fp.close() pathHelper.remove(stdoutFile) if res == 0: return True except: pass pathHelper.remove(stdoutFile) pathHelper.remove(filename) return False
def _downloadFiles(self): check = pathHelper.remove(self.tmpPath) check = pathHelper.mkdirs(self.tmpPath) if self.netVer.mainFile is None: return False if self.netVer.isZip == 0: plist = [] plist.append(self.netVer.mainFile) for item in self.netVer.elseFileList: plist.append(item) for item in plist: urlpath = self.netUrl + '//' + item topath = self.tmpPath + '\\' + item if netHelper.downloadFile(urlpath, topath) is False: return False else: urlpath = self.netUrl + '//' + self.netVer.zipFile topath = self.tmpPath + '\\' + self.netVer.zipFile if netHelper.downloadFile(urlpath, topath) is False: return False return zipHelper.unzip(topath, self.tmpPath) return True
def removeTmpFile(self, path): for root, dirs, files in os.walk(path): for name in files: if self.tmpfileFlag in name: pathHelper.remove(os.path.join(root, name))
def downloadPlaylist(self, playlist_id=None): while True: targetDir = self.config.outputdir + "/Playlist/" if playlist_id is None: print("--------------PLAYLIST-----------------") sID = printChoice("Enter PlayListID(Enter '0' go back):") if sID == '0': return else: sID = playlist_id aPlaylistInfo, aItemInfo = self.tool.getPlaylist(sID) if self.tool.errmsg != "": printErr(0, "Get PlaylistInfo Err! " + self.tool.errmsg) return print("[Title] %s" % (aPlaylistInfo['title'])) print("[Type] %s" % (aPlaylistInfo['type'])) print("[NumberOfTracks] %s" % (aPlaylistInfo['numberOfTracks'])) print("[NumberOfVideos] %s" % (aPlaylistInfo['numberOfVideos'])) print("[Duration] %s\n" % (aPlaylistInfo['duration'])) # Creat OutputDir targetDir = targetDir + pathHelper.replaceLimitChar( aPlaylistInfo['title'], '-') targetDir = os.path.abspath(targetDir).strip() pathHelper.mkdirs(targetDir) # write msg string = self.tool.convertPlaylistInfoToString( aPlaylistInfo, aItemInfo) with codecs.open(targetDir + "/PlaylistInfo.txt", 'w', 'utf-8') as fd: fd.write(string) # download cover coverPath = targetDir + '/' + pathHelper.replaceLimitChar( aPlaylistInfo['title'], '-') + '.jpg' coverUrl = self.tool.getPlaylistArtworkUrl(aPlaylistInfo['uuid']) check = netHelper.downloadFile(coverUrl, coverPath) # download track bBreakFlag = False bFirstTime = True errIndex = [] index = 0 while bBreakFlag is False: self.check.clear() index = 0 tmpcoverpath = [] for item in aItemInfo: type = item['type'] item = item['item'] if type != 'track': continue index = index + 1 if bFirstTime is False: if self.check.isInErr(index - 1, errIndex) == False: continue streamInfo = self.tool.getStreamUrl( str(item['id']), self.config.quality) # streamInfo = self.tool.getStreamUrl(str(item['id']), 'DOLBY_ATMOS') if self.tool.errmsg != "" or not streamInfo: printErr( 14, item['title'] + "(Get Stream Url Err!!" + self.tool.errmsg + ")") continue aAlbumInfo = self.tool.getAlbum(item['album']['id']) fileType = self._getSongExtension(streamInfo['url']) # change targetDir targetDir2 = targetDir if self.config.plfile2arfolder == "True": targetDir2 = self.__creatAlbumDir(aAlbumInfo) filePath = self.__getAlbumSongSavePath( targetDir2, aAlbumInfo, item, fileType) paraList = { 'album': aAlbumInfo, 'title': item['title'], 'trackinfo': item, 'url': streamInfo['url'], 'path': filePath, 'retry': 3, 'key': streamInfo['encryptionKey'] } else: seq = self.tool.getIndexStr(index, len(aItemInfo)) filePath = targetDir2 + '/' + seq + " " + pathHelper.replaceLimitChar( item['title'], '-') + fileType paraList = { 'album': aAlbumInfo, 'index': index, 'title': item['title'], 'trackinfo': item, 'url': streamInfo['url'], 'path': filePath, 'retry': 3, 'key': streamInfo['encryptionKey'] } try: coverPath = targetDir2 + '/' + pathHelper.replaceLimitChar( aAlbumInfo['title'], '-') + '.jpg' coverUrl = self.tool.getAlbumArtworkUrl( aAlbumInfo['cover']) netHelper.downloadFile(coverUrl, coverPath) paraList['coverpath'] = coverPath tmpcoverpath.append(coverPath) except: cmdHelper.myprint( "Could not download artwork for '{}'".format( item['title']), cmdHelper.TextColor.Red, None) if self.config.onlym4a == "True": self.check.addPath(filePath.replace(".mp4", ".m4a")) else: self.check.addPath(filePath) self.thread.start(self.__thradfunc_dl, paraList) self.thread.waitAll() self.tool.removeTmpFile(targetDir) # remove cover if self.config.savephoto != 'True': for item in tmpcoverpath: pathHelper.remove(item) bBreakFlag = True bFirstTime = False # check isErr, errIndex = self.check.checkPaths() if isErr: check = printChoice( "[Err]\t\t" + str(len(errIndex)) + " Tracks Download Failed.Try Again?(y/n):") if check == 'y' or check == 'Y': bBreakFlag = False # download video for item in aItemInfo: type = item['type'] item = item['item'] if type != 'video': continue filePath = targetDir + '/' + pathHelper.replaceLimitChar( item['title'], '-') + ".mp4" filePath = os.path.abspath(filePath) if os.access(filePath, 0): os.remove(filePath) videoID = item['id'] resolutionList, urlList = self.tool.getVideoResolutionList( videoID) if urlList is None: printErr(14, item['title'] + '(' + self.tool.errmsg + ')') else: selectIndex = self.__getVideoResolutionIndex( resolutionList) if self.ffmpeg.mergerByM3u8_Multithreading2( urlList[int(selectIndex)], filePath, showprogress=self.showpro): printSUCCESS(14, item['title']) else: printErr(14, item['title'] + "(Download Or Merger Err!)") if playlist_id is not None: return return
def downloadTrack(self, track_id=None): while_count = 9999 while while_count > 0: while_count -= 1 if track_id is not None: while_count = 0 sID = track_id else: print("----------------TRACK------------------") sID = printChoice("Enter TrackID(Enter '0' go back):", True, 0) if sID == 0: return aTrackInfo = self.tool.getTrack(sID) if self.tool.errmsg != "": printErr(0, "Get TrackInfo Err! " + self.tool.errmsg) return aAlbumInfo = self.tool.getAlbum(aTrackInfo['album']['id']) if self.tool.errmsg != "": printErr(0, "Get TrackInfo Err! " + self.tool.errmsg) return # t = self.tool.getTrackContributors(sID) print("[AlbumTitle ] %s" % (aAlbumInfo['title'])) print("[TrackTitle ] %s" % (aTrackInfo['title'])) print("[Duration ] %s" % (aTrackInfo['duration'])) print("[TrackNumber] %s" % (aTrackInfo['trackNumber'])) print("[Explicit ] %s" % (aAlbumInfo['explicit'])) # print("[Version ] %s\n" % (aTrackInfo['version'])) # Creat OutputDir targetDir = self.__creatAlbumDir(aAlbumInfo) # download cover coverPath = targetDir + '/' + pathHelper.replaceLimitChar( aAlbumInfo['title'], '-') + '.jpg' if aAlbumInfo['cover'] is not None: coverUrl = self.tool.getAlbumArtworkUrl(aAlbumInfo['cover']) netHelper.downloadFile(coverUrl, coverPath) # download streamInfo = self.tool.getStreamUrl(sID, self.config.quality) if self.tool.errmsg != "" or not streamInfo: printErr( 14, aTrackInfo['title'] + "(Get Stream Url Err!" + self.tool.errmsg + ")") continue fileType = self._getSongExtension(streamInfo['url']) filePath = self.__getAlbumSongSavePath(targetDir, aAlbumInfo, aTrackInfo, fileType) paraList = { 'album': aAlbumInfo, 'title': aTrackInfo['title'], 'trackinfo': aTrackInfo, 'url': streamInfo['url'], 'path': filePath, 'retry': 3, 'key': streamInfo['encryptionKey'], 'coverpath': coverPath } self.thread.start(self.__thradfunc_dl, paraList) # wait all download thread self.thread.waitAll() self.tool.removeTmpFile(targetDir) # remove cover if self.config.savephoto != 'True': pathHelper.remove(coverPath) return
def downloadAlbum(self, album_id=None, redl_flag=None): while_count = 9999 while while_count > 0: while_count -= 1 if album_id is not None: while_count = 0 sID = album_id else: print("----------------ALBUM------------------") sID = printChoice("Enter AlbumID(Enter '0' go back):", True, 0) if sID == 0: return aAlbumInfo = self.tool.getAlbum(sID) if self.tool.errmsg != "": printErr(0, "Get AlbumInfo Err! " + self.tool.errmsg) continue print("[Title] %s" % (aAlbumInfo['title'])) print("[SongNum] %s\n" % (aAlbumInfo['numberOfTracks'])) # Get Tracks aAlbumTracks = self.tool.getAlbumTracks(sID) if self.tool.errmsg != "": printErr(0, "Get AlbumTracks Err!" + self.tool.errmsg) continue aAlbumVideos = self.tool.getAlbumVideos(sID) # Creat OutputDir targetDir = self.__creatAlbumDir(aAlbumInfo) # write msg string = self.tool.convertAlbumInfoToString( aAlbumInfo, aAlbumTracks) with codecs.open(targetDir + "/AlbumInfo.txt", 'w', 'utf-8') as fd: fd.write(string) # download cover coverPath = targetDir + '/' + pathHelper.replaceLimitChar( aAlbumInfo['title'], '-') + '.jpg' if aAlbumInfo['cover'] is not None: coverUrl = self.tool.getAlbumArtworkUrl(aAlbumInfo['cover']) netHelper.downloadFile(coverUrl, coverPath) # check exist files redownload = True if redl_flag is None: existFiles = pathHelper.getDirFiles(targetDir) for item in existFiles: if '.txt' in item: continue if '.jpg' in item: continue check = printChoice( "Some tracks already exist. Redownload?(y/n):") if not cmdHelper.isInputYes(check): redownload = False break else: redownload = redl_flag # download album tracks for item in aAlbumTracks['items']: streamInfo = self.tool.getStreamUrl(str(item['id']), self.config.quality) if self.tool.errmsg != "" or not streamInfo: printErr( 14, item['title'] + "(Get Stream Url Err!" + self.tool.errmsg + ")") continue fileType = self._getSongExtension(streamInfo['url']) filePath = self.__getAlbumSongSavePath(targetDir, aAlbumInfo, item, fileType) paraList = { 'album': aAlbumInfo, 'redownload': redownload, 'title': item['title'], 'trackinfo': item, 'url': streamInfo['url'], 'path': filePath, 'retry': 3, 'key': streamInfo['encryptionKey'], 'coverpath': coverPath } self.thread.start(self.__thradfunc_dl, paraList) # wait all download thread self.thread.waitAll() self.tool.removeTmpFile(targetDir) # remove cover if self.config.savephoto != 'True': pathHelper.remove(coverPath) # download video for item in aAlbumVideos: item = item['item'] filePath = targetDir + '/' + pathHelper.replaceLimitChar( item['title'], '-') + ".mp4" filePath = os.path.abspath(filePath) if os.access(filePath, 0): os.remove(filePath) try: resolutionList, urlList = self.tool.getVideoResolutionList( item['id']) selectIndex = self.__getVideoResolutionIndex( resolutionList) if self.ffmpeg.mergerByM3u8_Multithreading2( urlList[int(selectIndex)], filePath, showprogress=self.showpro): printSUCCESS(14, item['title']) else: printErr(14, item['title']) except: printErr(14, item['title']) # return return