https://bongman.tistory.com/1195
(내가 쓰려고 만드는) 간단한 팟캐스트 웹앱 제작기 #1
이런저런 라디오와 팟캐스트를 즐겨 듣고 있다. 특히 잠자리에서 책이나 영화를 소개하는 팟캐스트를 듣다 잠드는 습관이 있다. 보통 30분에서 1시간 정도 종료 타이머를 맞춰 놓고 놓는다. 애플
bongman.tistory.com
간단한 팟캐스트 웹앱을 계속 갖고 놀고 있다. 지난 포스트 말미에 예고한 대로 종료 타이머 정도만 추가하려고 했는데, 어쩌다 보니 작업 내용이 조금 달라지고 작업 규모는 많이 커졌다. 기존 하드코딩을 걷어내고 아예 백엔드를 구현했다. 이번에도 퀄리티는 모르겠고 잘 동작한다.
const podcastData = {
episodes: [
{
id: 1,
title: "부고니아",
description: "요르고스 란티모스의 신작 '부고니아'에 대한 이야기와 김혜리 기자의 새로운 칼럼 연재 소식",
audioUrl: "http://podcastdown.sbs.co.kr/powerfm/2025/11/podcast-v2000010143-20251118-1763083508347.mp3",
imageUrl: "https://image.cloud.sbs.co.kr/2024/06/05/Yqc1717550363234.jpg",
duration: "01:21:09"
},
{
id: 2,
title: "밀린 수다",
description: "지난 두 달간 쌓인 청취자 사연 공유 에피소드",
audioUrl: "http://podcastdown.sbs.co.kr/powerfm/2025/11/podcast-v2000010143-20251110-1762740994999.mp3",
imageUrl: "https://image.cloud.sbs.co.kr/2024/06/05/Yqc1717550363234.jpg",
duration: "00:53:17"
},
{
id: 3,
title: "세계의 주인 with 윤가은 감독",
description: "윤가은 감독과의 100분을 채운 상세 대화 세션",
audioUrl: "http://podcastdown.sbs.co.kr/powerfm/2025/10/podcast-v2000010143-20251027-1761107893693.mp3",
imageUrl: "https://image.cloud.sbs.co.kr/2024/06/05/Yqc1717550363234.jpg",
duration: "01:38:04"
},
{
id: 4,
title: "원 배틀 애프터 어나더",
description: "영화 이야기로만 82분, 그 중 음악 이야기는 29분",
audioUrl: "http://podcastdown.sbs.co.kr/powerfm/2025/10/podcast-v2000010143-20251017-1760690866827.mp3",
imageUrl: "https://image.cloud.sbs.co.kr/2024/06/05/Yqc1717550363234.jpg",
duration: "01:26:21"
},
{
id: 5,
title: "어쩔수가없다 with 박찬욱 감독",
description: "박찬욱 감독과의 신작 상세 대담, 연기 디렉션 및 음악 선호도 논의",
audioUrl: "http://podcastdown.sbs.co.kr/powerfm/2025/10/podcast-v2000010143-20251001-1759286133458.mp3",
imageUrl: "https://image.cloud.sbs.co.kr/2024/06/05/Yqc1717550363234.jpg",
duration: "01:50:54"
}
]
};
위와 같이 app.js 스크립트에 다섯 개의 에피소드를 하드코딩했던 코드를 걷어내고, 별도의 서버(백엔드)가 RSS feed URL로부터 전체 에피소드 리스트를 얻어오도록 했다. 큰 그림은 ChatGPT에게 물어보고 실제 코드 작업은 이번에도 Claude Code에게 시켰다. 백엔드는 python 기반의 웹 프레임워크인 Flask를 사용해서 구현했다. 참고로 Flask라는 놈도 이번에 처음 알게 됐다. Claude Code가 제안한 몇 가지 안에 node.js, next.js 등도 있었는데 그나마 내가 javascript 코드보다는 python 코드가 보기 편해서 이걸로 결정했다. 뚝딱뚝딱하더니 아래와 같은 메시지를 뱉어내며 백엔드 서버 구현이 완료됐다.
⏺ Done! Internal API Server Built Successfully
I've successfully built a Python Flask API server that fetches podcast data from the external RSS feed. Here's what was
created:
New Files Created:
1. server.py - Flask API server with RSS parsing (162 lines)
2. requirements.txt - Python dependencies (Flask, flask-cors, feedparser)
3. README.md - Complete setup and usage documentation
4. .gitignore - Excludes .venv and Python cache files
Modified Files:
- app.js - Now fetches episodes from API instead of hardcoded data
Architecture Overview:
Backend (Flask API):
- Fetches from: https://wizard2.sbs.co.kr/w3/podcast/V2000010143.xml
- Runs on: http://localhost:5001 (avoiding macOS AirPlay port 5000)
- Features:
- RSS feed parsing with feedparser
- 5-minute caching to reduce external requests
- CORS enabled for frontend access
- Returns 314 episodes successfully
Frontend:
- Fetches episodes from API on page load
- Shows loading state while fetching
- Displays error messages if server is down
아래와 같이 로컬에서 서버를 띄우고, 웹 브라우저에서 index.html을 로딩했다.
python server.py


스크롤을 쭉쭉 내려보면 전체(314개) 에피소드가 전부 표시된다. 새로 구현한 서버(백엔드)가 RSS(XML)을 얻어오고, 이를 파싱해서 웹앱(프론트엔드)에 전달하면 이를 화면에 뿌려준다. 서버가 떨어지면 아래와 같이 뜨도록 예외처리까지 구현했다.

이어서 맥북을 마냥 켜 놓을 수는 없으니 서버 호스팅을 진행했다. 이 작업은 ChatGPT, Claude Code가 아닌 PyCharm에 추가한 Windsurf 플러그인의 도움을 받았다.

Railway.app 이라는 호스팅 서비스가 가장 간단하고 무료로 사용할 수 있다고 해서 그대로 진행했다. 혹시 PyCharm에 Windsurf 플러그인을 붙이는 방법이 궁금하신 분은 이전에 썼던 아래 포스트를 참고하시기 바란다.
https://bongman.tistory.com/1164
Windsurf Puguins 소개 및 간단한 사용기
요즘 Cursor로 대표되는 AI 코드 에디터가 정말 핫한데요. 일단 제 주변 개발자들은 모두들 사용하고 있는 것 같습니다. 다양한 툴들이 있지만 대부분 Cursor를 사용하시는 것 같고 저도 그랬는데요,
bongman.tistory.com
github 계정과 연동해서 작업 중인 저장소를 선택하면 docker 생성부터 호스팅까지 거의 자동으로 진행된다. Railway.app 라는 서비스 자체를 처음 들어봤고 이번엔 처음 써봤는데 너무 쉽고 간단해서 깜짝 놀랐다.

위 화면에서 Settings 탭을 클릭하고 Generate Domain 버튼을 누르면 도메인 주소를 받을 수 있다. 아래와 같이 로컬 서버로 설정했던 API_BASE_URL 값을 도메인 주소로 변경한다.
// const API_BASE_URL = 'http://localhost:8080';
const API_BASE_URL = 'https://simple-podcast-production.up.railway.app';
Railway.app 호스팅은 30일 무료 trial 기간이 끝나면 유료 결제를 해야 하는데, 계속 사용하게 된다면 제일 저렴한(월 5딸러) hobby 플랜을 사용하면 될 것 같다.
https://hamjoon.github.io/simple-podcast/
김혜리의 필름클럽
김혜리의 필름클럽 영화와 음악에 대한 이야기 에피소드를 선택하세요 Your browser does not support the audio element.
hamjoon.github.io
로컬 index.html이 아닌 github pages로 배포한 웹앱에서도 호스팅한 서버에 정상 접근되고, 동작에 문제없는 것까지 확인했다. 한 가지 걸리는 건 지금 백엔드와 프론트엔드가 하나의 프로젝트에 같이 있는데 나중에 분리하는 것이 좋을 듯하다. 종료 타이머 구현은 다음으로 미룬다. 끝.
'개발 > AI' 카테고리의 다른 글
| 구글 Advent of Agents 2025 따라 하기 - Day 1 (0) | 2025.12.04 |
|---|---|
| (내가 쓰려고 만드는) 간단한 팟캐스트 웹앱 제작기 #3 (0) | 2025.11.24 |
| (내가 쓰려고 만드는) 간단한 팟캐스트 웹앱 제작기 #1 (0) | 2025.11.22 |
| (나도 처음 해 본) GitHub Copilot에게 코드 리뷰 받기 (0) | 2025.11.21 |
| [Day15] LLM 스터디 1기 - vLLM 서빙 (6) | 2025.01.30 |