# 🎣 단 10분! Youtube 오디오 추출 코드 완성

한국어를 받아쓰기 할 땐 무조건 네이버다. 클로바노트만큼 한국어를 잘 인식하는 경우는 없다. 그래서 나는 모든 작업을 할때 (chatgpt로 요약, 영상 자막 추가 등) 꼭 오디오를 추출해서 클로바 노트를 이용하는 과정을 거친다. 

귀찮아서 그때그때 구글에 _youtube audio download_ 로 검색해서 나오는 웹에서 했었는데, 계속 반복되는 작업이다보니 로컬에서 직접 실행시켜보기로 했다.

이 모든 과정은 10분 만에 끝났다. 

# 1. Coding

![Image](https://upload.cafenono.com/image/slashpageHome/20240418/170321_YTqDso5CcxVJUzc0N9?q=75&s=1280x180&t=outside&f=webp)

요즘 langchain에 빠져있어서 추후에 오디오 추출한 걸 가지고 더 자동화 시스템을 만들 수 있지않을까 생각했지만, chatgpt는 langchain이란 말을 가뿐히 무시하고 그냥 코드를 만들어주었다. 

![Image](https://upload.cafenono.com/image/slashpageHome/20240418/170330_wD0BTeGWb1ovddp2w9?q=75&s=1280x180&t=outside&f=webp)

상세하게 코드 로직까지 설명해주고, 다운로드 받아야하는 패키지까지 설명해준다. sweet gpt..

```javascript
from pytube import YouTube

def download_youtube_audio(url, output_path):
    yt = YouTube(url)
    # YouTube 영상의 제목을 가져옵니다.
    title = yt.title
    # 오디오 스트림 중 최고 품질의 스트림을 선택합니다.
    audio_stream = yt.streams.filter(only_audio=True).first()
    # 오디오 파일을 지정된 경로에 저장합니다.
    audio_stream.download(output_path, filename=title + ".mp3")

# 사용 예제
url = "여기에 YouTube 동영상 URL을 입력하세요"
output_path = "여기에 저장할 경로를 입력하세요"
download_youtube_audio(url, output_path)
```

완성되어버렸다. 

사실 난 대부분 자바스크립트로 웹쪽만 해와서 파이썬은 헷갈릴때가 많다. 그래서 파이썬으로 작업할땐 구글 검색창과 늘 함께 해왔는데, 그럴 필요없이 1분만에 끝나버렸다. 

![Image](https://upload.cafenono.com/image/slashpageHome/20240418/170343_ayXtVppxfyDk52F5fs?q=75&s=1280x180&t=outside&f=webp)

실행하는 커맨드를 수행할때 유튜브 url을 넣어주고싶어서, 이렇게 요청했다. 

![Image](https://upload.cafenono.com/image/slashpageHome/20240418/170349_U3aieSirQuio7GhPEe?q=75&s=1280x180&t=outside&f=webp)

```javascript
import sys
from pytube import YouTube

def download_youtube_audio(url, output_path):
    yt = YouTube(url)
    title = yt.title
    audio_stream = yt.streams.filter(only_audio=True).first()
    audio_stream.download(output_path, filename=title + ".mp3")

if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("사용법: python script.py [YouTube URL] [저장 경로]")
    else:
        url = sys.argv[1]
        output_path = sys.argv[2]
        download_youtube_audio(url, output_path)
```

![Image](https://upload.cafenono.com/image/slashpageHome/20240418/170404_IU3hz2Y2mrfkwh0gon?q=75&s=1280x180&t=outside&f=webp)

이렇게 친절할 수가. 커맨드 입력할때 인자를 어떻게 적어야하는 지 까지 상세하게 안내를 해준다. 

정말 개발이나 컴퓨터에 익숙치 않은 사람들까지 chatgpt로 쉽게 원하는 프로그래밍을 할 수 있다는게 체감된다.

아? 그런데 이자식이 과하게 친절해서 추출된 오디오 저장경로까지 인수로 넘겨버렸다. 나는 오디오 저장경로는 따로 오디오 폴더를 만들어 두었기 때문에 모두 그쪽으로 저장되게 코드에 박아두고, 유튜브 링크만 인자로 받기로 했다. 

생각해보니, 저장하고 클로바노트에 업로드할때 쉽게 찾을 수 있어야 한다. 그래서 시간을 제목에 포함시키기로 했다. 

![Image](https://upload.cafenono.com/image/slashpageHome/20240418/170424_uH0UguAB8Qj985Sq3r?q=75&s=1280x180&t=outside&f=webp)

![Image](https://upload.cafenono.com/image/slashpageHome/20240418/170442_fPmXXlzGX1tassMjUH?q=75&s=1280x180&t=outside&f=webp)

```javascript
import sys
from pytube import YouTube
from datetime import datetime

def download_youtube_audio(url, output_path="."):
    yt = YouTube(url)
    title = yt.title
    # 현재 날짜와 시간을 포맷에 맞추어 문자열로 변환합니다.
    now = datetime.now().strftime("%Y%m%d_%H%M%S")
    filename = f"{now}_{title}.mp3"
    audio_stream = yt.streams.filter(only_audio=True).first()
    audio_stream.download(output_path, filename=filename)

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("사용법: python script.py [YouTube URL]")
    else:
        url = sys.argv[1]
        download_youtube_audio(url)
```

나이스. 

일단 날짜 형식을 내가 자주쓰는 `%Y.%m.%d_%H:%M:%S`로 수정하였다. 

또 드는 생각은 유튜브 제목이 긴 경우엔 어떻게 될 것인가..?

유튜브엔 간결한 제목이외에 검색 유입을 위해 구구절절 여러 키워드들이 붙는 경우가 많다. 파일을 저장할때 제목 길이제한으로 에러나는걸 두고볼 수 없으므로 바로 chatgpt에게 확인을 들어간다. 

![Image](https://upload.cafenono.com/image/slashpageHome/20240418/170459_LJN550ssa87zHEEbtw?q=75&s=1280x180&t=outside&f=webp)

내가 원했던 것 보다 더 많은 정보를 주었다. 고마워. 

![Image](https://upload.cafenono.com/image/slashpageHome/20240418/170507_wOUcHsXWZ903OWNR2n?q=75&s=1280x180&t=outside&f=webp)

한국어 영상이 대부분이기 때문에 한국어라고 명시를 해주면서 제목 길이를 제한하는 코드를 추가해달라고 요청했다. 

![Image](https://upload.cafenono.com/image/slashpageHome/20240418/170513_JMBHuGEr8RoLeVGmVs?q=75&s=1280x180&t=outside&f=webp)

```javascript
import sys
from pytube import YouTube
from datetime import datetime

def shorten_title(title, max_length):
    # 제목을 지정된 최대 길이에 맞추어 자릅니다.
    return title if len(title) <= max_length else title[:max_length-3] + "..."

def download_youtube_audio(url, output_path="."):
    yt = YouTube(url)
    title = yt.title
    # 파일 이름에 사용할 수 있는 최대 길이를 지정합니다.
    max_title_length = 100
    short_title = shorten_title(title, max_title_length)
    now = datetime.now().strftime("%Y%m%d_%H%M%S")
    filename = f"{now}_{short_title}.mp3"
    audio_stream = yt.streams.filter(only_audio=True).first()
    audio_stream.download(output_path, filename=filename)

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("사용법: python script.py [YouTube URL]")
    else:
        url = sys.argv[1]
        download_youtube_audio(url)
```

![Image](https://upload.cafenono.com/image/slashpageHome/20240418/170523_zxcTnPrQYUg4oeWWHn?q=75&s=1280x180&t=outside&f=webp)

기특해라. 마지막으로 시간이 한국시간으로 나오는지 문득 궁금했다. 수많은 에러를 겪어온 사람의 소잃기 전에 외양간 고치기..

![Image](https://upload.cafenono.com/image/slashpageHome/20240418/170534_V7vrUavJdZyewwvAMX?q=75&s=1280x180&t=outside&f=webp)

![Image](https://upload.cafenono.com/image/slashpageHome/20240418/170550_R0oueZBAzS4A3PpM95?q=75&s=1280x180&t=outside&f=webp)

시스템 시간대를 따른다고 한다. 다행히 코드를 변경할 필요는 없겠다. 

# 2. Debuging

자 이제 완성된 코드를 실행 시켜보면서 에러가 나는지 확인해보자. 

> ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1006)

무슨 인증서 검증이 안된다고 떴다. 바로 chatgpt로 복붙해보았다.

![Image](https://upload.cafenono.com/image/slashpageHome/20240418/170645_SXSQvi4YxUIQWc16eU?q=75&s=1280x180&t=outside&f=webp)

일언반구 없이 에러메세지만 복붙해도 chatgpt가 에러메세지 임을 인식하고 그에 대한 이유와 해결방법들을 제시해준다. 시키는 대로 해본다.

난 첫번째 방법을 시도하니 바로 에러가 해결이 되었다. 

# 3. Result

### 완성된 코드

```javascript
import sys
from pytube import YouTube
from datetime import datetime

def shorten_title(title, max_length):
    # 제목을 지정된 최대 길이에 맞추어 자릅니다.
    return title if len(title) <= max_length else title[: max_length - 3] + "..."

def download_youtube_audio(url):
    base_path = "/path"
    path = "/@ Resource/Audio"
    output_path = base_path + path
    # 파일 이름에 사용할 수 있는 최대 길이를 지정합니다.

    yt = YouTube(url)
    title = yt.title

    max_title_length = 100
    short_title = shorten_title(title, max_title_length)
    now = datetime.now().strftime("%Y.%m.%d_%H:%M:%S")
    filename = f"{now} - {short_title}.mp3"

    audio_stream = yt.streams.filter(only_audio=True).first()
    audio_stream.download(output_path, filename=filename)
    print(f"{filename} has downloaded at {path}")

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("사용법: python extract_audio.py [YouTube URL]")
    else:
        url = sys.argv[1]
        download_youtube_audio(url)
```

### 실행결과

![Image](https://upload.cafenono.com/image/slashpageHome/20240418/170702_pbsvSuoLF6ZNGi3BrF?q=75&s=1280x180&t=outside&f=webp)

![Image](https://upload.cafenono.com/image/slashpageHome/20240418/170711_mbCEkIJ21sPWh7C5Gx?q=75&s=1280x180&t=outside&f=webp)

원하는 위치에 원하는 제목으로 mp3파일이 생성되었다. 

# 4. Insight

- 원하는 프로그램의 목적이 있다면 chatgpt와 같이 로직을 만들어가며 코드를 작성할 수 있다.

- 또한 코딩은 개발환경에 따라 다르게 설정해주어야 하는 게 많기 때문에, 나의 개발환경에 대한 구체적인 정보를 말해주면 좋다.

- chatgpt가 프로그램 코드 뿐 아니라 실행코드까지 모두 제공하기 때문에, 무지성으로 따라만해도 실행은 되지만, 그래도 어느정도 컴퓨터에 대한 지식(상식수준?)은 있는게 전체적인 플로우를 이해하면서 할 수 있다.

- 이 게시글의 컨텐츠는 chatgpt없이도 충분히 할 수 있는 수준이지만 개발자로서 굳이 chatgpt를 사용할 이유는 아무래도 **시간절약**과 **무수한 크롬 탭 방지** 일 것이다.

For the site tree, see the [root Markdown](https://slashpage.com/huhsame.md).
