Affiliate Video Generator
🎬 Affiliate Video Generator
Generate Video from Affiliate Link
"""
# =============================
# PRODUCT SCRAPER
# =============================
def scrape_product(url):
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
soup = BeautifulSoup(response.text, 'html.parser')
if 'amazon' in url:
return scrape_amazon(soup, url)
elif 'aliexpress' in url:
return scrape_aliexpress(soup, url)
else:
return None
except Exception as e:
print(f"Scraping error: {e}")
return None
def scrape_amazon(soup, url):
title = soup.select_one('span#productTitle')
title = title.text.strip() if title else "Amazon Product"
price = soup.select_one('span.a-price-whole')
price = price.text.strip() if price else "Price not found"
images = []
for img in soup.select('img.src'):
src = img.get('src')
if src and src.startswith('http'):
images.append(src)
if len(images) >= 5:
break
description = soup.select_one('div#productDescription')
description = description.text.strip()[:500] if description else "No description available."
return {
'title': title,
'price': price,
'images': images,
'description': description,
'url': url
}
def scrape_aliexpress(soup, url):
title = soup.select_one('h1.product-title')
title = title.text.strip() if title else "AliExpress Product"
price = soup.select_one('span.product-price-value')
price = price.text.strip() if price else "Price not found"
images = []
for img in soup.select('img#image-thumb'):
src = img.get('data-original')
if src:
images.append(src)
if len(images) >= 5:
break
description = soup.select_one('div#product-description')
description = description.text.strip()[:500] if description else "No description available."
return {
'title': title,
'price': price,
'images': images,
'description': description,
'url': url
}
# =============================
# VIDEO GENERATOR
# =============================
def download_file(url, save_path):
try:
response = requests.get(url, timeout=10)
response.raise_for_status()
with open(save_path, 'wb') as f:
f.write(response.content)
return True
except:
return False
def create_video(product, output_path):
# 1. Generate Voice-over
script = generate_script(product)
tts = gTTS(text=script, lang='en', slow=False)
audio_path = os.path.join(OUTPUT_FOLDER, "voiceover.mp3")
tts.save(audio_path)
# 2. Download images
image_paths = []
for i, img_url in enumerate(product['images'][:5]):
img_path = os.path.join(OUTPUT_FOLDER, f"img_{i}.jpg")
if download_file(img_url, img_path):
image_paths.append(img_path)
# 3. Download background music
music_path = os.path.join(OUTPUT_FOLDER, "bg_music.mp3")
if not os.path.exists(music_path):
download_file(BACKGROUND_MUSIC_URL, music_path)
# 4. Generate video with FFmpeg
generate_ffmpeg_video(image_paths, audio_path, music_path, output_path)
def generate_script(product):
script = f"Check out this amazing product! {product['title']}. "
script += f"It is priced at {product['price']}. "
script += f"Here’s what it offers: {product['description'][:300]}... "
script += f"Click the link below to grab yours now! {product['url']}"
return script
def generate_ffmpeg_video(images, voiceover, music, output_path):
# Create FFmpeg command
cmd = [
'ffmpeg',
'-f', 'concat',
'-safe', '0',
'-i', create_image_list(images),
'-i', voiceover,
'-i', music,
'-filter_complex',
f"[0:v]scale=1280:720,setdar=16/9[v]; "
f"[1:a]atrim=0:{len(images)*3+10}[voice]; "
f"[2:a]atrim=0:{len(images)*3+10}[music]; "
f"[voice][music]amix=inputs=2:duration=first[audio]; "
f"[v][audio]concat=n=1:v=1:a=1[out]",
'-map', '[out]',
'-c:v', 'libx264',
'-c:a', 'aac',
'-b:a', '192k',
'-y', output_path
]
# Run FFmpeg
subprocess.run(cmd, check=True)
def create_image_list(image_paths):
list_path = os.path.join(OUTPUT_FOLDER, "image_list.txt")
with open(list_path, 'w') as f:
for img in image_paths:
f.write(f"file '{img}'\nduration 3\n") # Each image for 3 seconds
return list_path
# =============================
# FLASK ROUTES
# =============================
@app.route('/')
def home():
return render_template_string(HTML_TEMPLATE)
@app.route('/generate', methods=['POST'])
def generate():
url = request.form.get('url')
if not url:
return jsonify({'error': 'URL is required!'}), 400
# Scrape product
product = scrape_product(url)
if not product:
return jsonify({'error': 'Could not fetch product details!'}), 400
# Generate unique filename
video_filename = f"{uuid.uuid4()}.mp4"
output_path = os.path.join(OUTPUT_FOLDER, video_filename)
try:
create_video(product, output_path)
video_url = f"/static/{video_filename}"
return jsonify({
'video_url': video_url,
'title': product['title']
})
except Exception as e:
return jsonify({'error': str(e)}), 500
@app.route(f'/static/{os.path.basename(OUTPUT_FOLDER)}/
')
def serve_video(filename):
return send_file(os.path.join(OUTPUT_FOLDER, filename))
# =============================
# RUN THE APP
# =============================
if __name__ == '__main__':
# Create folders if missing
os.makedirs(OUTPUT_FOLDER, exist_ok=True)
print("🚀 Affiliate Video Generator is running!")
print("🔗 Open http://localhost:5000 in your browser")
app.run(host='0.0.0.0', port=5000, debug=True)