본문 바로가기

IT/개발

youtube 컨텐츠 다운로드 하여 일부분만 저장하기(python, pytube, moviepy)

반응형

딥러닝으로 영상을 학습하려고 하다보면 영상 데이터를 유투브에서 수집하는 경우가 많습니다. 

 

이럴때 대부분 영상의 이름과 저장할 시간 정보를 annotation 파일로 만들어 놓고  처리하는 경우가 일반적인데요. 

 

영상 데이터 수집을 위해 간단히 구현해보겠습니다. 

 

1. pytube

 

pytubeYouTube 동영상을 다운로드하기 위한 Python 라이브러리입니다.

YouTube 동영상의 URL을 이용해서 다양한 컨텐츠를 다운로드 할 수 있습니다.

 

YouTube 동영상은 한가지로 구성된 것이 아니고 다양한 스트림(: 오디오만, 비디오만, 비디오 해상도별 등등)으로 구성되어 있습니다.

pytube에서는 포함된 스트림을 조회하고 선택적으로 다운로드할 수 있는 기능을 제공합니다.

 

https://pypi.org/project/pytube/

 

pytube

Python 3 library for downloading YouTube Videos.

pypi.org

 

2. moviepy

 

moviepy는 비디오 편집을 위한 강력한 라이브러리입니다. 동영상과 오디오 파일에 대해서 자르기, 합치기, 제목 추가하기 등 다양한 형태로 처리할 수 있습니다.

 

-비디오 클립 자르기, 병합하기, 속도 조정하기.

-비디오에 텍스트, 이미지, 로고 추가하기.

-배경 음악 추가 및 오디오 처리(볼륨 조절, 오디오 클립 자르기 등).

-전환 효과 및 애니메이션 추가.

 

https://pypi.org/project/moviepy/

 

moviepy

Video editing with Python

pypi.org

 

3. 구현 

 

import os
import sys
from pytube import YouTube
from moviepy.editor import VideoFileClip
 
def download_video_with_range(url, start_time, end_time, output_path):
   
    yt = YouTube(url)
   
    basename = os.path.basename(url)
    #'watch?v=' 제거 -> ZDgnu2kJ6b8
    basename = basename[8:]
   
    #포함된 스트림 확인
    #여러개의 스트림 중에서 720p 해상도를 찾아서 수신
    streams = yt.streams.all()    
    stream = yt.streams.filter(res="720p").first()
   
    #문자열 좌우 공백을 없애고 : 로 분리 하고 초단위 값으로 변환
    start = start_time.strip().split(':')
    start_seconds = int(start[0])*60*60 + int(start[1])*60 + int(start[2])
    end = end_time.strip().split(':')
    end_seconds = int(end[0])*60*60 + int(end[1])*60 + int(end[2])  
 
   #다운로드할 파일 명과 컷팅해서 저장할 파일명 생성 
    downfilename = basename+f".org.{stream.subtype}"
    cutfilename = basename+f".{stream.subtype}"
    stream.download(output_path, downfilename)
   
    org = os.path.join(output_path, downfilename)
    cut = os.path.join(output_path, cutfilename)
   
    # 특정 구간을 추출하여 저장
    clip = VideoFileClip(org).subclip(start_time, end_time)
    clip.write_videofile(cut)
   
   
    #원본 삭제
    os.remove(org)
 

 

아주 간단하게 영상을 받아서 잘라낼 수 있게 되었습니다. ^^

 

위 코드는 주어진 YouTube 동영상 URL에 대해 720p 해상도를 가진 스트림을 찾아 첫 번째 스트림을 선택하고, 그 스트림을 다운로드하도록 한것이지만 filter 함수는 다양한 인자를 받을 수 있으며, 여러 조건을 조합하여 사용할 수도 있습니다.

 

res: 스트림의 해상도를 기준으로 필터링합니다. : "720p", "1080p".

file_extension: 스트림의 파일 확장자를 기준으로 필터링합니다. : "mp4", "webm".

progressive: 오디오와 비디오가 함께 있는 스트림을 필터링합니다. True 또는 False 값을 가집니다.

adaptive: 오디오와 비디오가 분리된 스트림을 필터링합니다. True 또는 False 값을 가집니다.

only_audio: 오디오만 있는 스트림을 필터링합니다. True를 설정하면 오디오 스트림만 반환합니다.

only_video: 비디오만 있는 스트림을 필터링합니다. True를 설정하면 비디오 스트림만 반환합니다.

 

moviepy의 유용한 몇가지 기능을 추가해보면 

 

비디오 클립 로딩 및 컷

from moviepy.editor import VideoFileClip

 

# 비디오 파일 로드

clip = VideoFileClip("my_video.mp4")

# 비디오의 처음 10초를 컷

cut_clip = clip.subclip(0, 10)

 

- 비디오에 텍스트 추가

from moviepy.editor import TextClip, CompositeVideoClip

 

# 텍스트 클립 생성

txt_clip = TextClip("Hello World!", fontsize=70, color='white')

# 텍스트 클립의 위치 조정

txt_clip = txt_clip.set_pos('center').set_duration(10)

# 텍스트를 비디오에 합성

composite_clip = CompositeVideoClip([clip, txt_clip])

 

- 비디오 병합

from moviepy.editor import concatenate_videoclips

 

# 두 비디오 클립 로드

clip1 = VideoFileClip("my_video_1.mp4")

clip2 = VideoFileClip("my_video_2.mp4")

 

# 비디오 클립 병합

final_clip = concatenate_videoclips([clip1, clip2])

 

- 배경 음악 추가

from moviepy.editor import AudioFileClip

 

# 오디오 파일 로드

audio_background = AudioFileClip("background_music.mp3")

 

# 비디오의 오디오를 배경 음악으로 설정

video_with_audio = clip.set_audio(audio_background)

 

moviepy는 이 외에도 비디오 및 오디오 편집과 관련된 다양한 고급 기능을 제공하므로, 사용자의 특정 요구 사항에 맞게 많은 작업을 수행할 수 있습니다.

 

반응형