jonathanjordan21 commited on
Commit
dfbf35f
1 Parent(s): 45dfa70

Initial commit

Browse files
app.py ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain.llms import HuggingFacePipeline
2
+ import torch
3
+ from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline, AutoModelForSeq2SeqLM
4
+
5
+ from components import caption_chain, tag_chain
6
+ from components import pexels, utils
7
+ import os, gc
8
+ import gradio as gr
9
+
10
+ model = AutoModelForSeq2SeqLM.from_pretrained("declare-lab/flan-alpaca-gpt4-xl")
11
+ tokenizer = AutoTokenizer.from_pretrained("declare-lab/flan-alpaca-gpt4-xl")
12
+
13
+ pipe = pipeline(
14
+ 'text2text-generation',
15
+ model=model,
16
+ tokenizer= tokenizer,
17
+ max_length=120
18
+ )
19
+
20
+ local_llm = HuggingFacePipeline(pipeline=pipe)
21
+
22
+ llm_chain = caption_chain.chain(llm=local_llm)
23
+ sum_llm_chain = tag_chain.chain(llm=local_llm)
24
+
25
+ pexels_api_key = os.getenv('pexels_api_key')
26
+
27
+ def pred(product_name, orientation):
28
+ if orientation == "Shorts/Reels/TikTok (1080 x 1920)":
29
+ orientation = "potrait"
30
+ height = 1920
31
+ width = 1080
32
+ elif orientation == "Youtube Videos (1920 x 1080)":
33
+ orientation = "landscape"
34
+ height = 1080
35
+ width = 1920
36
+ else :
37
+ orientation = "square"
38
+ height = 1080
39
+ width = 1080
40
+ folder_name, sentences = pexels.generate_videos(product_name, pexels_api_key, orientation, height, width, llm_chain, sum_llm_chain)
41
+ gc.collect()
42
+ utils.combine_videos(folder_name)
43
+ return ["\n".join(sentences), os.path.join(folder_name, "Final_Ad_Video.mp4")]
44
+ #{'video':os.path.join(folder_name, "Final_Ad_Video.mp4"),
45
+ # 'captions':"\n".join(sentences)}
46
+
47
+
48
+ with gr.Blocks() as demo:
49
+ gr.Markdown(
50
+ """
51
+ # Ads Generator
52
+ Create video ads based on your product name using AI
53
+ ### Note : the video generation takes about 2-4 minutes
54
+ """
55
+ )
56
+ dimension = gr.Dropdown(
57
+ ["Shorts/Reels/TikTok (1080 x 1920)", "Facebook/Youtube Videos (1920 x 1080)", "Square (1080 x 1080)"],
58
+ label="Video Dimension", info="Choose dimension"
59
+ )
60
+ product_name = gr.Textbox(label="product name")
61
+ captions = gr.Textbox(label="captions")
62
+ video = gr.Video()
63
+ btn = gr.Button("Submit")
64
+ btn.click(pred, inputs=[product_name, dimension], outputs=[captions,video])
65
+
66
+
67
+
68
+ demo.launch()
components/__init__.py ADDED
File without changes
components/caption_chain.py ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain import PromptTemplate
2
+ from langchain.chains import LLMChain
3
+
4
+ def chain(llm):
5
+ template = """Make 5 different advertisement captions about this product.
6
+ {product}
7
+ """
8
+
9
+ prompt = PromptTemplate(template=template, input_variables=["product"])
10
+
11
+ llm_chain = LLMChain(prompt=prompt, llm=llm)
12
+ return llm_chain
components/pexels.py ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import shutil,os,re
3
+
4
+ # Searching for the videos
5
+ def search_pexels(keyword, api_key, orientation='potrait', size='medium', endpoint='videos', num_pages=50):
6
+
7
+ if orientation not in ['potrait', 'landscape', 'square']:
8
+ raise Exception("Error! orientation must be one of {'square', 'landscape', 'potrait'}")
9
+
10
+ if size not in ['medium', 'small', 'large']:
11
+ raise Exception("Error! size must be one of ['medium', 'small', 'large']")
12
+
13
+ base_url = 'https://api.pexels.com/'
14
+
15
+ headers = {
16
+ 'Authorization': f'{api_key}'
17
+ }
18
+
19
+ url = f'{base_url}{endpoint}/search?query={keyword}&per_page={num_pages}&orientation={orientation}&size={size}'
20
+
21
+
22
+ response = requests.get(url, headers=headers)
23
+
24
+ # Check if request was successful (status code 200)
25
+ if response.status_code == 200:
26
+ data = response.json()
27
+ return data
28
+ else:
29
+ print(f'Error: {response.status_code}')
30
+
31
+
32
+ # Video download function
33
+ def download_video(data, parent_path, height, width, links, i):
34
+ for x in data['videos'] :
35
+ if x['id'] in links:
36
+ continue
37
+
38
+ vid = x['video_files']
39
+ for v in vid:
40
+ if v['height'] == height and v['width'] == width :
41
+ with open(f"{os.path.join(parent_path,str(i) + '_' + str(v['id']))}.mp4", 'bw') as f:
42
+ f.write(requests.get(v['link']).content)
43
+ print("Sucessfully saved video in", os.path.join(parent_path,str(i) + '_' + str(v['id'])) + '.mp4')
44
+ return x['id']
45
+
46
+
47
+ # Utilizing the LLMs to find the relevant videos
48
+ def generate_videos(product, api_key, orientation, height, width, llm_chain=None, sum_llm_chain=None):
49
+ prod = product.strip().replace(" ", "_")
50
+ links = []
51
+ try :
52
+ # Split the paragraph by sentences
53
+
54
+ sentences = llm_chain.run(product.strip())
55
+ print('Sentence :', sentences)
56
+
57
+ # sentences = sentences.split(".")[:-1]
58
+ sentences = [x.strip() for x in re.split(r'\d+\.', sentences) if len(x) > 6]
59
+
60
+
61
+ # Create directory with the product's name
62
+ if os.path.exists(prod):
63
+ shutil.rmtree(prod)
64
+ os.mkdir(prod)
65
+
66
+ # Generate video for every sentence
67
+ print("Keyword :")
68
+ for i,s in enumerate(sentences):
69
+ keyword = sum_llm_chain.run(s)
70
+ print(i+1, ":", keyword)
71
+ data = search_pexels(keyword, api_key, orientation.lower())
72
+ link = download_video(data, prod, height, width, links,i)
73
+ links.append(link)
74
+
75
+ print("Success! videos has been generated")
76
+ except Exception as e :
77
+ print("Error! Failed generating videos")
78
+ print(e)
79
+
80
+ return prod, sentences
81
+
components/tag_chain.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain.prompts import PromptTemplate
2
+ from langchain.chains import LLMChain
3
+
4
+ def chain(llm):
5
+ sum_template = """what is the most significant actions or places or things, say it in at most 5 words :
6
+
7
+ {sentence}
8
+
9
+
10
+ """
11
+
12
+ sum_prompt = PromptTemplate(template=sum_template, input_variables=["sentence"])
13
+
14
+ sum_llm_chain = LLMChain(prompt=sum_prompt, llm=llm)
15
+
16
+ return sum_llm_chain
components/utils.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from moviepy.editor import VideoFileClip, concatenate_videoclips,vfx
2
+ import os
3
+
4
+ def combine_videos(folder_name):
5
+
6
+ length = len(os.listdir(folder_name))
7
+
8
+ vids = [VideoFileClip(os.path.join(folder_name,x)) for x in sorted(os.listdir(folder_name))]
9
+
10
+ combined = concatenate_videoclips(
11
+ [vid.subclip(0,7).fx(vfx.fadein,0.5).fx(vfx.fadeout,0.5) if vid.duration > 7 else vid.fx(vfx.fadein,0.5).fx(vfx.fadeout,0.5) for vid in vids],
12
+ # [VideoFileClip(os.path.join(folder_name,x)).subclip(0,7).fx(vfx.fadein,0.5).fx(vfx.fadeout,0.5) for x in sorted(os.listdir(folder_name))],
13
+ "compose",bg_color=None, padding=0
14
+ )
15
+ combined.write_videofile(os.path.join(folder_name, "Final_Ad_Video.mp4"))
16
+
17
+ # if length <= 6:
18
+ # combined = concatenate_videoclips([VideoFileClip(os.path.join(folder_name,x)).subclip(0,10) for x in os.listdir(folder_name)])
19
+ # combined.write_videofile(os.path.join(folder_name, "Ad_Video.mp4"))
20
+ # else :
21
+ # combined = concatenate_videoclips([VideoFileClip(os.path.join(folder_name,x)).subclip(0,60//length) for x in os.listdir(folder_name)])
22
+ # combined.write_videofile(os.path.join(folder_name, "Ad_Video.mp4"))
23
+ print("Done! Your ads video has been created")
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ langchain
2
+ moviepy
3
+ transformers
4
+ torch