ayloll commited on
Commit
230bcec
·
verified ·
1 Parent(s): 2d2cc6d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +148 -74
app.py CHANGED
@@ -1,96 +1,170 @@
1
  import gradio as gr
2
- from fastapi import FastAPI, HTTPException
3
  import yt_dlp
4
  import whisper
5
- import requests
6
  import os
7
  import re
8
- import asyncio
9
- from urllib.parse import urlparse
10
 
11
- app = FastAPI()
 
 
 
12
 
13
- # دالة لتحويل الروابط القصيرة
14
- def expand_tiktok_url(url):
15
- try:
16
- if not re.match(r'^https?://(www\.)?tiktok\.com', url):
17
- session = requests.Session()
18
- resp = session.head(url, allow_redirects=True, timeout=10)
19
- return resp.url
20
- return url
21
- except:
22
- return url
23
 
24
- # دالة لاستخراج ID الفيديو
25
- def get_video_id(url):
26
- parsed = urlparse(url)
27
- if 'tiktok.com' not in parsed.netloc:
28
- return None
 
29
 
30
- path_parts = parsed.path.split('/')
31
- if 'video' in path_parts:
32
- return path_parts[path_parts.index('video') + 1]
33
- return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
- # دالة المعالجة الرئيسية
36
- async def process_video(url):
 
 
 
 
 
 
 
 
37
  try:
38
- # 1. تحويل الروابط القصيرة
39
- final_url = expand_tiktok_url(url)
40
-
41
- # 2. التحقق من صحة الرابط
42
- video_id = get_video_id(final_url)
43
- if not video_id:
44
- raise HTTPException(status_code=400, detail="Invalid TikTok URL")
45
-
46
- # 3. تنزيل الفيديو
47
  ydl_opts = {
48
  'format': 'best[ext=mp4]',
49
- 'outtmpl': f'{video_id}.mp4',
50
  'quiet': True,
51
- 'extractor_args': {'tiktok': {'skip_watermark': True}}
 
 
 
52
  }
53
 
54
  with yt_dlp.YoutubeDL(ydl_opts) as ydl:
55
- info = ydl.extract_info(final_url, download=True)
56
- video_path = ydl.prepare_filename(info)
57
-
58
- # 4. استخراج الصوت
59
- audio_path = f'{video_id}.mp3'
60
- os.system(f'ffmpeg -i "{video_path}" -vn -ar 16000 -ac 1 "{audio_path}"')
61
-
62
- # 5. تحويل الصوت لنص
63
- model = whisper.load_model("base")
64
- result = model.transcribe(audio_path)
65
-
66
- # 6. تنظيف الملفات المؤقتة
67
- os.remove(video_path)
68
- os.remove(audio_path)
69
-
70
- return {
71
- "transcription": result["text"],
72
- "video_id": video_id
73
- }
74
-
75
- except Exception as e:
76
- raise HTTPException(status_code=500, detail=str(e))
77
 
78
- # واجهة API
79
- @app.get("/analyze")
80
- async def analyze(url: str):
81
- return await process_video(url)
 
 
 
 
 
 
82
 
83
- # واجهة Gradio (اختيارية)
84
- with gr.Blocks() as demo:
85
- gr.Markdown("## TikTok Analyzer")
86
- url_input = gr.Textbox(label="TikTok URL")
87
- output_text = gr.Textbox(label="Transcription")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
- def analyze_gradio(url):
90
- result = process_video(url)
91
- return result["transcription"]
 
 
 
 
 
 
92
 
93
- demo.launch(server_name="0.0.0.0", server_port=7860)
 
 
 
 
94
 
95
- # للدمج مع FastAPI
96
- app = gr.mount_gradio_app(app, demo, path="/")
 
 
 
 
 
 
1
  import gradio as gr
2
+ from transformers import pipeline
3
  import yt_dlp
4
  import whisper
 
5
  import os
6
  import re
7
+ import tempfile
8
+ import traceback
9
 
10
+ # تهيئة النموذج مسبقاً لتحسين الأداء
11
+ whisper_model = whisper.load_model("base")
12
+ classifier = pipeline("zero-shot-classification",
13
+ model="facebook/bart-large-mnli")
14
 
15
+ # تصنيفات المحتوى
16
+ CONTENT_LABELS = [
17
+ "educational", "entertainment", "news", "political",
18
+ "religious", "technical", "advertisement", "social"
19
+ ]
 
 
 
 
 
20
 
21
+ def process_video(video_url):
22
+ """الدالة الرئيسية لمعالجة الفيديو"""
23
+ try:
24
+ # التحقق من صحة الرابط
25
+ if not is_valid_tiktok_url(video_url):
26
+ return "Invalid TikTok URL", ""
27
 
28
+ # إنشاء ملفات مؤقتة
29
+ with tempfile.NamedTemporaryFile(suffix='.mp4') as video_file, \
30
+ tempfile.NamedTemporaryFile(suffix='.mp3') as audio_file:
31
+
32
+ # تنزيل الفيديو
33
+ if not download_video(video_url, video_file.name):
34
+ return "Failed to download video", ""
35
+
36
+ # استخراج الصوت
37
+ if not extract_audio(video_file.name, audio_file.name):
38
+ return "Failed to extract audio", ""
39
+
40
+ # تحويل الصوت إلى نص
41
+ transcription = transcribe_audio(audio_file.name)
42
+ if not transcription:
43
+ return "Failed to transcribe audio", ""
44
+
45
+ # تصنيف المحتوى
46
+ category, confidence = classify_content(transcription)
47
+
48
+ # إرجاع النتائج
49
+ if category:
50
+ return transcription, f"{category} (confidence: {confidence:.2f})"
51
+ return transcription, "Classification failed"
52
+
53
+ except Exception as e:
54
+ print(f"Error: {str(e)}\n{traceback.format_exc()}")
55
+ return f"Processing error: {str(e)}", ""
56
 
57
+ def is_valid_tiktok_url(url):
58
+ """التحقق من صحة رابط تيك توك"""
59
+ return bool(re.match(
60
+ r'^https?://(www\.|vm\.)?tiktok\.com/.+',
61
+ url,
62
+ re.IGNORECASE
63
+ ))
64
+
65
+ def download_video(url, output_path):
66
+ """تنزيل فيديو تيك توك"""
67
  try:
 
 
 
 
 
 
 
 
 
68
  ydl_opts = {
69
  'format': 'best[ext=mp4]',
70
+ 'outtmpl': output_path,
71
  'quiet': True,
72
+ 'no_warnings': True,
73
+ 'extractor_args': {'tiktok': {'skip_watermark': True}},
74
+ 'socket_timeout': 10,
75
+ 'retries': 3
76
  }
77
 
78
  with yt_dlp.YoutubeDL(ydl_opts) as ydl:
79
+ ydl.download([url])
80
+ return os.path.exists(output_path)
81
+ except:
82
+ return False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
 
84
+ def extract_audio(video_path, audio_path):
85
+ """استخراج الصوت من الفيديو"""
86
+ try:
87
+ os.system(
88
+ f"ffmpeg -i \"{video_path}\" "
89
+ f"-vn -acodec libmp3lame -q:a 2 \"{audio_path}\" -y"
90
+ )
91
+ return os.path.exists(audio_path)
92
+ except:
93
+ return False
94
 
95
+ def transcribe_audio(audio_path):
96
+ """تحويل الصوت إلى نص"""
97
+ try:
98
+ result = whisper_model.transcribe(audio_path)
99
+ return result.get('text', '')
100
+ except:
101
+ return ""
102
+
103
+ def classify_content(text):
104
+ """تصنيف المحتوى"""
105
+ try:
106
+ if not text.strip():
107
+ return None, None
108
+
109
+ result = classifier(
110
+ text,
111
+ candidate_labels=CONTENT_LABELS,
112
+ hypothesis_template="This text is about {}."
113
+ )
114
+ return result['labels'][0], result['scores'][0]
115
+ except:
116
+ return None, None
117
+
118
+ # واجهة Gradio
119
+ with gr.Blocks(title="TikTok Content Analyzer") as demo:
120
+ gr.Markdown("""
121
+ # 🎬 TikTok Content Analyzer
122
+ Analyze any TikTok video to get transcription and content classification
123
+ """)
124
+
125
+ with gr.Row():
126
+ url_input = gr.Textbox(
127
+ label="TikTok Video URL",
128
+ placeholder="Paste TikTok link here...",
129
+ max_lines=1
130
+ )
131
+
132
+ with gr.Row():
133
+ transcription_output = gr.Textbox(
134
+ label="Transcription",
135
+ interactive=True,
136
+ lines=10,
137
+ max_lines=20
138
+ )
139
+
140
+ with gr.Row():
141
+ category_output = gr.Textbox(
142
+ label="Content Category",
143
+ interactive=False
144
+ )
145
+
146
+ submit_btn = gr.Button("Analyze", variant="primary")
147
 
148
+ # أمثلة
149
+ gr.Examples(
150
+ examples=[
151
+ ["https://www.tiktok.com/@example/video/123456789"],
152
+ ["https://vm.tiktok.com/ZMexample/"]
153
+ ],
154
+ inputs=url_input,
155
+ label="Example TikTok URLs"
156
+ )
157
 
158
+ submit_btn.click(
159
+ fn=process_video,
160
+ inputs=url_input,
161
+ outputs=[transcription_output, category_output]
162
+ )
163
 
164
+ # تشغيل التطبيق
165
+ if __name__ == "__main__":
166
+ demo.launch(
167
+ server_name="0.0.0.0",
168
+ server_port=7860,
169
+ show_error=True
170
+ )