55import random
66import shutil
77from collections import defaultdict
8+ import json
89
910VideoFileClip .resize = resize
1011
@@ -16,84 +17,102 @@ def extractAcc(filepath):
1617 except :
1718 return ""
1819
19- # generateTimeRange converts float seconds to a range of form @MM:SS
20- def generateTimeRange (duration , clipDuration ):
21- preHour = int (duration / 60 )
22- preMin = int (duration % 60 )
23- preTime = str (preHour // 10 ) + str (preHour % 10 ) + ":" + str (preMin // 10 ) + str (preMin % 10 )
2420
25- duration += clipDuration
26- postHour = int (duration / 60 )
27- postMin = int (duration % 60 )
28- postTime = str (postHour // 10 ) + str (postHour % 10 ) + ":" + str (postMin // 10 ) + str (postMin % 10 )
29-
30- #return "@" + preTime + " - " + "@" + postTime
31- return "@" + preTime
32-
3321# makeCompilation takes videos in a folder and creates a compilation with max length totalVidLength
3422def makeCompilation (path = "./" ,
3523 introName = '' ,
3624 outroName = '' ,
3725 totalVidLength = 10 * 60 ,
3826 maxClipLength = 20 ,
3927 minClipLength = 5 ,
40- outputFile = "output.mp4" ):
28+ outputFile = "output.mp4" ,
29+ video_source_meta = {},
30+ videoDirectory = "" ,
31+ description_meta = "" ,
32+ modeAM = "A" ):
4133
4234 allVideos = []
4335 seenLengths = defaultdict (list )
4436 totalLength = 0
37+ duration = 0
38+ videos = []
39+
40+ # Add intro video if included
41+ if introName != '' :
42+ introVid = VideoFileClip ("./" + introName )
43+ videos .append (introVid )
44+ duration += introVid .duration
45+
46+
4547 for fileName in os .listdir (path ):
4648
47- filePath = join (path , fileName );
49+ filePath = join (path , fileName )
4850 if isfile (filePath ) and fileName .endswith (".mp4" ):
49- print ( fileName )
51+
5052 if os .stat (filePath ).st_size < 5000 :
5153 continue
5254
53- # Destination path
55+ # Destination path
5456 clip = VideoFileClip (filePath )
5557 clip = clip .resize (width = 1920 )
5658 clip = clip .resize (height = 1080 )
5759 duration = clip .duration
58- print (duration )
59-
60- # Commit
61- if duration <= maxClipLength and duration >= minClipLength :
60+ print (fileName + " " + str ( duration ) + " Added" )
61+
62+ # add_video in min&max range or ignore errors
63+ def add_video () :
6264 allVideos .append (clip )
6365 seenLengths [duration ].append (fileName )
6466 totalLength += duration
65- else :
66- ignore_error = input ("Do You want to ignore errors on max & min Clip Length (Y/n):" )
67- if ignore_error == "n" :
68- print ("Stopping Script Due to errors" )
69- Break
67+
68+ if modeAM == "A" :
69+ add_video ()
70+ elif modeAM == "M" :
71+ if duration <= maxClipLength and duration >= minClipLength :
72+ add_video ()
7073 else :
71- print ("Continue with errors. RegardLess of Clip Length" )
72- allVideos .append (clip )
73- seenLengths [duration ].append (fileName )
74- totalLength += duration
75-
76- print ("Total Length: " + str (totalLength ))
74+ ignore_error = input ("Do you want to ignore Errors in min max Total Video Length?(Y/n)" ).strip ()
75+ if ignore_error != "n" :
76+ pass
77+ else :
78+ add_video ()
7779
78- random .shuffle (allVideos )
80+ #Add automated description
81+
82+ for k in range (len (os .listdir (path ))):
83+
84+ fileNameJ = fileName .split (".mp4" )
85+ fileNameJSON = '' .join (fileNameJ ) + ".json"
86+
87+ acc = extractAcc (clip .filename )
88+
89+ # Fix error in TimeStamps
90+ duration_in_min = str (duration ).split ("." )
91+ duration_in_min .pop ()
92+ video_source_meta [f"TimeStamps{ k } " ] = "00:" + str (duration_in_min [0 ]) + " : @" + acc + "\n "
93+
94+ video_source_meta [f"profile{ k } " ] = "Instagram profile:" + " instagram.com/" + acc + '\n '
95+
96+ #extract url & other information about video
97+
98+ f = open (f"{ videoDirectory } { fileNameJSON } " , "r" )
99+ json_d = json .loads (f .read ())
100+ f .close ()
101+
102+ video_source_meta [f"vido_url{ k } " ] = "Video URL:" + "instagram.com/tv/" + json_d ["shortcode" ] + '\n '
103+ video_source_meta [f"Caption{ k } " ] = json_d ["edge_media_to_caption" ]["edges" ][0 ]["node" ]["text" ] + '\n '
104+
105+ description_meta = video_source_meta [f"TimeStamps{ k } " ] + video_source_meta [f"profile{ k } " ] + video_source_meta [f"vido_url{ k } " ] + video_source_meta [f"Caption{ k } " ]
106+
107+ print (description_meta )
108+
109+ print ("Total Length: " + str (totalLength ))
79110
80- duration = 0
81- # Add intro vid
82- videos = []
83- if introName != '' :
84- introVid = VideoFileClip ("./" + introName )
85- videos .append (introVid )
86- duration += introVid .duration
87-
88- description = ""
89111 # Create videos
90112 for clip in allVideos :
91- timeRange = generateTimeRange (duration , clip .duration )
92- acc = extractAcc (clip .filename )
93- description += timeRange + " : @" + acc + "\n "
94113 duration += clip .duration
95114 videos .append (clip )
96- print ( duration )
115+
97116 if duration >= totalVidLength :
98117 # Just make one video
99118 break
@@ -107,16 +126,19 @@ def makeCompilation(path = "./",
107126
108127 audio_path = "/tmp/temoaudiofile.m4a"
109128
110- #print(description)
111129 # Create compilation
112130 finalClip .write_videofile (outputFile , threads = 8 , temp_audiofile = audio_path , remove_temp = True , codec = "libx264" , audio_codec = "aac" )
113-
114- return description
131+
132+ return description_meta
115133
116134if __name__ == "__main__" :
117- makeCompilation (path = "/Users/nathanan /Documents/YOUTUBE/AutomatedChannel/Videos/Memes/" ,
135+ makeCompilation (path = "/home/kali /Documents/YOUTUBE/AutomatedChannel/Videos/Memes/" ,
118136 introName = "intro_vid.mp4" ,
119137 outroName = '' ,
120138 totalVidLength = 10 * 60 ,
121139 maxClipLength = 20 ,
122- outputFile = "outputseq.mp4" )
140+ outputFile = "outputseq.mp4" ,
141+ video_source_meta = {},
142+ videoDirectory = "" ,
143+ description_meta = "" ,
144+ modeAM = "A" )
0 commit comments