Catalog
Functional Implementation Analysis
Techniques used: Python Foundation and ffepeg
Needs Analysis (a simple mind map)
demand
This software converts the mobile cache of station b directly into a video that can be opened directly. After the user has set it up in Config, running the program can achieve automatic conversion. (Here I copy the settings in Config directly to the top of the code)
Functional Implementation Analysis
Conversion rules:
1. Total Video Folder Outside pure numbers are normal videos av number of pure digital video s_ Start with a pantomime-type video 2. Episode Folder Point open av folder, inside c_ Beginning with cid for video 3. Video Information Folder Point to open cid's folder, entry.json contains the json information of the video, including the video title, av id bv number (bvid), page_data, CID of the video and the name of the minute p, and the definition code of the video (for example, 80 for 1080P). danmaku.xml is the xml marquee of the video. 4. Video Folders Open the definition code folder with audio inside. M4S and video.m4s, in which case ffmpeg is used to merge: ffmpeg -i "audio.m4s" -i "video.m4s" "output.mp4" This allows you to merge directly into MP4 files. For blv files, ffmpeg is also used to encapsulate directly into MP4: ffmpeg -i "0.blv" -acodec copy -vcodec copy "output.mp4" Note that ffmpeg is not very good at Chinese support, try not to use Chinese naming directly on the command line, but to rename the software after the operation is completed. *
Action required
1. Open the general folder and classify videos by name (3 categories, pantomime category, ordinary video P category, ordinary single P video)
2. Parse each video. Enter the video json file to parse the video information and find the naming information.
3. Convert the video files in each video into MP4 files. The video files in bilibili bili are divided into two types (one is two m4s files separated for audio and video, the other is a blv file, which cannot be played directly)
Techniques used: Python Foundation and ffepeg
Needs Analysis (a simple mind map)
source code
import json import os # bilibili cache video address input_path = "C:/Users/Promise/Desktop/download" # Save Video Folder out_path = 'C:/Users/Promise/Desktop/bili_video' # Whether to convert normal video class files c_video = True # Whether to convert pantomime files c_anime = True # Whether the pantomime conversion is placed in the same folder (similar to haggling mass downloads) anime_folder = True # Whether videos with multiple points are placed in the same folder video_folder = True # Whether to output xml marquees c_xml = True # Whether to convert xml to ass xml2ass=True # Whether to use the naming rules for Chao Down or cid for False enable_JJDown_rename = True # Do you want to delete the source file after the conversion is complete delete_input_file = False # Open General Folder def open_download(): # All Cached Videos all_video = os.listdir(input_path) # path completion list = [] for video in all_video: video = input_path + '/' +video list.append(video) return list # Judging Large Types def judge_huge_type(video): # Determine type by file name if 's_' in video: type = 's' return type else: type = 'c' return type # Determine whether ordinary video is divided into P def c_judge_p(video_path): # Open Folder by Path # Determine whether the score is P based on the number of files sub_video_list = os.listdir(video_path) if len(sub_video_list) > 1: return True else: return False def sub_file(video_path): # Open episodes folder by path # Determine whether the score is P based on the number of files sub_video_list = os.listdir(video_path) sub_list = [] for sub_video in sub_video_list: sub_video = video_path+ '/' +sub_video sub_list.append(sub_video) return sub_list def subsub_file(sub_video_path): # Enter each episode information folder based on episode path subsub_video_info = os.listdir(sub_video_path) video_info = [] for fileinfo in subsub_video_info: fileinfo = sub_video_path + '/' +fileinfo video_info.append(fileinfo) return video_info def get_name(video_info): # Get Name for video_file_info in video_info: if str(video_file_info).endswith('json'): with open(video_file_info, 'r', encoding='utf8') as out: json_data = json.load(out) # print(json_data['title']) return json_data['title'] def get_anime_index(video_info): # Get episode information for video_file_info in video_info: if str(video_file_info).endswith('json'): with open(video_file_info, 'r', encoding='utf8') as out: json_data = json.load(out) info = json_data['ep'] result = info['index']+' '+info['index_title'] return result def get_pages_index(video_info): # Get Score P Video Information for video_file_info in video_info: if str(video_file_info).endswith('json'): with open(video_file_info, 'r', encoding='utf8') as out: json_data = json.load(out) info = json_data['page_data'] result = info['part'] return result def last_file(video_info): # Enter the last folder last_list = [] for video_file_info in video_info: if not str(video_file_info).endswith('json') and not str(video_file_info).endswith('xml') : last_file_list = os.listdir(video_file_info) for last_file_info in last_file_list: last_file_info = video_file_info + '/' +last_file_info last_list.append(last_file_info) return last_list def convert_mp4(last_list,last_file_path): # Convert two m4s files into MP4 files m4s_count = 0 blv_count = 0 m4sfile_list = [] blvfile_list = [] for last_file in last_list: if str(last_file).endswith('m4s'): m4sfile_list.append(last_file) m4s_count += 1 elif str(last_file).endswith('blv'): blvfile_list.append(last_file) blv_count += 1 else: pass if m4s_count == 2: os.system('ffmpeg -i ' + '"' + m4sfile_list[0] + '" ' + '-i' + ' "' + m4sfile_list[1] + '" -acodec copy -vcodec copy ' + '"' + last_file_path + '"') elif blv_count == 1: os.system('ffmpeg -i ' + '"' + blvfile_list[0] + '"' + ' -acodec copy -vcodec copy ' + '"' + last_file_path + '"') else: pass print(last_file_path , 'Conversion Successful!') if __name__ == '__main__': # Open Video Folder all_video = open_download() # Traverse Video Folders for video in all_video: # Determine video type (pantomime or regular video) type = judge_huge_type(video) if type == 's': print('Panda') # If the conversion is turned on in the settings to True if c_anime: # Open the episodes folder all_sub_video= sub_file(video) # Traverse the episodes folder for sub_video in all_sub_video: # Open the video information folder for each episode video_info = subsub_file(sub_video) # Remove video-related information from json file # Video Name name = get_name(video_info) # Episode Name index_name = get_anime_index(video_info) # Save Location save_dirpath = out_path # If pantomimes need to be saved with a zero-folder if anime_folder: # Add a folder of pantomime titles save_dirpath = out_path + '/' + name # create folder if not os.path.exists(save_dirpath): os.mkdir(save_dirpath) # Write Final File Path last_file_path = save_dirpath + '/' + index_name + '.mp4' last_list = last_file(video_info) # Convert file format convert_mp4(last_list, last_file_path) else: print('ordinary') # Ditto if c_video: if c_judge_p(video): print('branch p') all_sub_video = sub_file(video) for sub_video in all_sub_video: video_info = subsub_file(sub_video) name = get_name(video_info) index_name = get_pages_index(video_info) save_dirpath = out_path if video_folder: save_dirpath = out_path + '/' + name if not os.path.exists(save_dirpath): os.mkdir(save_dirpath) last_file_path = save_dirpath + '/' +index_name +'.mp4' last_list = last_file(video_info) convert_mp4(last_list,last_file_path) else: # Ditto all_sub_video = sub_file(video) for sub_video in all_sub_video: video_info = subsub_file(sub_video) name = get_name(video_info) last_file_path = out_path + '/' + name + '.mp4' last_list = last_file(video_info) convert_mp4(last_list, last_file_path)
Summary Reflection:
1. It feels like this code does its best to encapsulate a lot of functions, but the main function is still too long and the encapsulation is not so effective. I hope it can be improved in the future.
2. The code is too long to remember names, so more standard naming principles are needed.
3. Some of the functions in the last for loop can continue to be encapsulated, but they are still a bit lazy and have not been improved in the end.
4. Do you want to encapsulate as much functionality as possible and make your code more readable?
Hope will overwhelm you!
A Python budding post just published on CSDN