lcjln commited on
Commit
dcd84ea
Β·
verified Β·
1 Parent(s): 0354116

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +21 -39
app.py CHANGED
@@ -1,13 +1,12 @@
1
  import streamlit as st
2
  import yt_dlp
3
  import os
4
- from moviepy.editor import VideoFileClip, AudioFileClip, concatenate_videoclips
5
 
6
  # Streamlit 제λͺ©
7
  st.title('YouTube Video Downloader')
8
- st.write("<br>", unsafe_allow_html=True) # 1쀄 띄어쓰기
9
  st.write("μ‚¬μš©λ°©λ²•")
10
- st.write("<br>", unsafe_allow_html=True) # 1쀄 띄어쓰기
11
  st.write("1. λ‹€μš΄λ°›κ³ μžν•˜λŠ” 유튜브 μ˜μƒμ˜ 링크λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”")
12
  st.write("2. 링크λ₯Ό μž…λ ₯ν•˜κ³  ν™•μΈλ²„νŠΌμ„ λˆ„λ₯΄λ©΄ ν•΄λ‹Ή μ˜μƒμ˜ 썸넀일이 λ“±μž₯ν•©λ‹ˆλ‹€")
13
  st.write("3. 썸넀일 λ°‘μ˜ μ„ νƒλž€μ„ 톡해 해상도와 μ˜μƒ μš©λŸ‰μ„ ν™•μΈν•œ ν›„ μ›ν•˜λŠ” 해상도λ₯Ό μ„ νƒν•˜κ³  μΆ”μΆœ λ²„νŠΌμ„ λˆŒλŸ¬μ£Όμ„Έμš”")
@@ -25,18 +24,15 @@ def fetch_video_info(youtube_url):
25
  info_dict = ydl.extract_info(youtube_url, download=False)
26
  return info_dict
27
 
28
- def get_specific_formats(info_dict):
29
- target_heights = [1080, 720, 144]
30
- formats = {height: None for height in target_heights}
31
-
32
  for fmt in info_dict['formats']:
33
- if fmt.get('height') in target_heights and fmt.get('ext') == 'mp4':
34
  filesize = fmt.get('filesize', 0)
35
  if filesize:
36
  filesize_mb = round(filesize / (1024 * 1024), 2)
37
- formats[fmt['height']] = f"{fmt['format_id']} - {fmt['height']}p - {filesize_mb} MB"
38
-
39
- return [fmt for fmt in formats.values() if fmt is not None]
40
 
41
  if st.button('확인'):
42
  if youtube_url:
@@ -53,7 +49,7 @@ if st.button('확인'):
53
  info_dict = fetch_video_info(youtube_url)
54
  st.session_state.info_dict = info_dict
55
  st.session_state.thumbnail_url = info_dict.get('thumbnail')
56
- st.session_state.formats = get_specific_formats(info_dict)
57
  st.session_state.confirmed = True
58
  except Exception as e:
59
  st.error(f"An error occurred: {e}")
@@ -66,46 +62,32 @@ if st.session_state.confirmed:
66
  # 해상도 선택
67
  format_selection = st.selectbox('Select resolution', st.session_state.formats)
68
 
69
- def download_video_audio(youtube_url, format_id):
70
- video_opts = {
71
- 'format': format_id,
 
72
  'outtmpl': 'downloaded_video.%(ext)s',
73
- 'nocheckcertificate': True,
74
- }
75
- audio_opts = {
76
- 'format': 'bestaudio',
77
- 'outtmpl': 'downloaded_audio.%(ext)s',
78
- 'nocheckcertificate': True,
79
  }
80
-
81
- with yt_dlp.YoutubeDL(video_opts) as ydl:
82
  ydl.download([youtube_url])
83
-
84
- with yt_dlp.YoutubeDL(audio_opts) as ydl:
85
- ydl.download([youtube_url])
86
-
87
- def combine_video_audio(video_path, audio_path, output_path):
88
- video_clip = VideoFileClip(video_path)
89
- audio_clip = AudioFileClip(audio_path)
90
- final_clip = video_clip.set_audio(audio_clip)
91
- final_clip.write_videofile(output_path, codec="libx264")
92
 
93
  # "μΆ”μΆœ" λ²„νŠΌ μΆ”κ°€
94
  if st.button('μΆ”μΆœ'):
95
- format_id = format_selection.split(' - ')[0]
96
  try:
97
  # μ„Έμ…˜ μƒνƒœμ˜ youtube_url μ‚¬μš©
98
- download_video_audio(st.session_state.youtube_url, format_id)
99
- combine_video_audio('downloaded_video.mp4', 'downloaded_audio.webm', 'final_video.mp4')
100
- st.success('Video downloaded and combined successfully!')
101
- st.video('final_video.mp4')
102
 
103
  # λ‹€μš΄λ‘œλ“œλœ 파일 제곡 (optional)
104
- with open('final_video.mp4', 'rb') as file:
105
  st.download_button(
106
  label="Download Video File",
107
  data=file,
108
- file_name='final_video.mp4',
109
  mime='video/mp4'
110
  )
111
  except Exception as e:
 
1
  import streamlit as st
2
  import yt_dlp
3
  import os
 
4
 
5
  # Streamlit 제λͺ©
6
  st.title('YouTube Video Downloader')
7
+ st.write("<br>", unsafe_allow_html=True) # 1쀄 띄어쓰기
8
  st.write("μ‚¬μš©λ°©λ²•")
9
+ st.write("<br>", unsafe_allow_html=True) # 1쀄 띄어쓰기
10
  st.write("1. λ‹€μš΄λ°›κ³ μžν•˜λŠ” 유튜브 μ˜μƒμ˜ 링크λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”")
11
  st.write("2. 링크λ₯Ό μž…λ ₯ν•˜κ³  ν™•μΈλ²„νŠΌμ„ λˆ„λ₯΄λ©΄ ν•΄λ‹Ή μ˜μƒμ˜ 썸넀일이 λ“±μž₯ν•©λ‹ˆλ‹€")
12
  st.write("3. 썸넀일 λ°‘μ˜ μ„ νƒλž€μ„ 톡해 해상도와 μ˜μƒ μš©λŸ‰μ„ ν™•μΈν•œ ν›„ μ›ν•˜λŠ” 해상도λ₯Ό μ„ νƒν•˜κ³  μΆ”μΆœ λ²„νŠΌμ„ λˆŒλŸ¬μ£Όμ„Έμš”")
 
24
  info_dict = ydl.extract_info(youtube_url, download=False)
25
  return info_dict
26
 
27
+ def get_available_formats(info_dict):
28
+ formats = []
 
 
29
  for fmt in info_dict['formats']:
30
+ if fmt.get('height') and fmt.get('ext') == 'mp4':
31
  filesize = fmt.get('filesize', 0)
32
  if filesize:
33
  filesize_mb = round(filesize / (1024 * 1024), 2)
34
+ formats.append(f"{fmt['height']}p - {filesize_mb} MB")
35
+ return formats
 
36
 
37
  if st.button('확인'):
38
  if youtube_url:
 
49
  info_dict = fetch_video_info(youtube_url)
50
  st.session_state.info_dict = info_dict
51
  st.session_state.thumbnail_url = info_dict.get('thumbnail')
52
+ st.session_state.formats = get_available_formats(info_dict)
53
  st.session_state.confirmed = True
54
  except Exception as e:
55
  st.error(f"An error occurred: {e}")
 
62
  # 해상도 선택
63
  format_selection = st.selectbox('Select resolution', st.session_state.formats)
64
 
65
+ def download_video(youtube_url, format_id):
66
+ ydl_opts = {
67
+ 'format': f"{format_id}+bestaudio/best",
68
+ 'merge_output_format': 'mp4',
69
  'outtmpl': 'downloaded_video.%(ext)s',
70
+ 'nocache': True, # μΊμ‹œ λΉ„ν™œμ„±ν™”
71
+ 'force_generic_extractor': True # 항상 μƒˆλ‘œμš΄ URL μ‚¬μš©
 
 
 
 
72
  }
73
+ with yt_dlp.YoutubeDL(ydl_opts) as ydl:
 
74
  ydl.download([youtube_url])
 
 
 
 
 
 
 
 
 
75
 
76
  # "μΆ”μΆœ" λ²„νŠΌ μΆ”κ°€
77
  if st.button('μΆ”μΆœ'):
78
+ format_id = format_selection.split('p')[0]
79
  try:
80
  # μ„Έμ…˜ μƒνƒœμ˜ youtube_url μ‚¬μš©
81
+ download_video(st.session_state.youtube_url, format_id)
82
+ st.success('Video downloaded successfully!')
83
+ st.video('downloaded_video.mp4')
 
84
 
85
  # λ‹€μš΄λ‘œλ“œλœ 파일 제곡 (optional)
86
+ with open('downloaded_video.mp4', 'rb') as file:
87
  st.download_button(
88
  label="Download Video File",
89
  data=file,
90
+ file_name='downloaded_video.mp4',
91
  mime='video/mp4'
92
  )
93
  except Exception as e: