당신만을 위한 맞춤형 미디어, STA:D
2024.04.08(월) ~ 2024.05.20(월) (30일간 진행)
SSAFY 10기 2학기 자율 프로젝트 - STA:D
FAST(Free Advertising Streaming TV) 서비스는 새로운 차세대 케이블로 불리는 서비스로 구독료를 받지 않고 광고를 시청하여 무료로 컨텐츠를 이용할 수 있는 미디어 서비스입니다.
기존의 FAST 서비스에 추가적인 기능들을 더해 새로운 형태의 FAST 서비스를 개발하고자 했습니다.
-
스마트폰과 IoT
- 스마트폰을 비롯한 모바일 기기들은 IoT 시대에서 모든 사물에 닿을 수 있는 리모컨의 기능을 합니다.
- TV를 스마트폰에 연동하여 사용자가 TV의 정보를 스마트폰에서 확인하고 쉽게 활용할 수 있도록 크로스 디바이스 서비스를 기획했습니다.
-
FAST 서비스와 모바일 연동
- FAST 서비스는 구독료 없이 광고를 시청하여 무료로 콘텐츠를 이용할 수 있는 미디어 서비스로, 시장 규모가 성장할 것으로 예상됩니다.
- FAST(Free Advertising Streaming TV) 서비스와 모바일을 연동함으로써 더욱 편리하고 향상된 고객 경험을 제공하고자 했습니다.
-
맞춤 광고와 시너지
- FAST 서비스의 개인 맞춤 광고를 모바일과 연결했을 때 얻어지는 시너지를 고려했습니다.
- 사용자는 맞춤 광고를 모바일에서 확인하여 정보를 얻고 쉽게 구매로 이어지는 새로운 고객 경험을 얻을 수 있습니다.
- FAST 서비스 제공 기업은 광고비 외에도 쇼핑 서비스를 통한 판매 수수료라는 수입원을 추가하여 BM의 다각화를 이루고 사업의 안정성을 높일 수 있습니다.
- STA:D는 개인 맞춤형 광고와 콘텐츠 스트리밍을 제공하며, 모바일 앱과 웹 플랫폼을 통해 사용자와 기업 간의 상호작용을 최적화하는 통합 미디어 서비스입니다.
STA:D - OTT 이용시 맞춤형 광고 제공부터 결제까지 가능한 All-in-One 플랫폼
- 버퍼링 없는 대용량 파일 스트리밍
- 사용자 맞춤형 광고 제공
- 광고주를 위한 광고 통계 대시보드 제공
- TV와 휴대폰 디바이스 간 정보 공유
- 다양한 PG사, 결제 수단 제공
지금 보는 광고가 궁금하다면? STA:D
- 사용자 맞춤형 광고 제공하고, 버퍼링 없이 대용량 파일을 스트리밍하는 OTT 서비스를 개발합니다.
- 광고주를 위해 광고 통계 대시보드를, 사용자를 위해 다양한 결제 수단을 제공합니다.
- TV와 휴대폰 디바이스 간에 시청중인 광고와 콘텐츠 정보를 공유합니다.
- 역할을 분담하여 서비스를 코드로 구현하고 배포합니다.
- 구현하는 과정에서 Front-end와 Back-end가 협업하는 과정을 이해합니다.
- RESTful API를 직접 설계하고 API를 통한 HTTP 통신을 겪으며 협업 능력을 기릅니다.
- 자신이 맡은 부분을 설명할 수 있는 의사소통 능력을 기릅니다.
- 단순 구현으로 끝나는 것이 아닌 코드 리뷰와 피드백을 통해 함께 성장합니다.
├─domain
│ ├─advert
│ │ ├─controller
│ │ │ ├─request
│ │ │ └─response
│ │ ├─entity
│ │ ├─repository
│ │ └─service
│ │ └─command
│ │ ├─request
│ │ └─response
│ ├─advertVideo
│ │ ├─controller
│ │ │ ├─request
│ │ │ └─response
│ │ ├─entity
│ │ ├─repository
│ │ └─service
│ │ └─command
│ │ ├─request
│ │ └─response
│ ├─cart
│ │ ├─controller
│ │ │ ├─request
│ │ │ └─response
│ │ ├─entity
│ │ ├─repository
│ │ └─service
│ │ └─command
│ ├─classification
│ │ ├─controller
│ │ ├─dto
│ │ └─service
│ ├─contents
│ │ ├─bookmark
│ │ │ ├─controller
│ │ │ │ ├─request
│ │ │ │ └─response
│ │ │ ├─entity
│ │ │ ├─repository
│ │ │ │ ├─custom
│ │ │ │ └─impl
│ │ │ └─service
│ │ │ └─command
│ │ │ └─request
│ │ ├─category
│ │ │ ├─controller
│ │ │ │ └─response
│ │ │ ├─entity
│ │ │ ├─repository
│ │ │ │ ├─custom
│ │ │ │ └─impl
│ │ │ └─service
│ │ │ └─command
│ │ │ └─request
│ │ ├─categoryRelationship
│ │ │ ├─entity
│ │ │ ├─repository
│ │ │ │ ├─custom
│ │ │ │ └─impl
│ │ │ └─service
│ │ ├─concept
│ │ │ ├─controller
│ │ │ │ ├─request
│ │ │ │ └─response
│ │ │ ├─entity
│ │ │ ├─repository
│ │ │ │ ├─custom
│ │ │ │ └─impl
│ │ │ └─service
│ │ │ └─command
│ │ │ ├─request
│ │ │ └─response
│ │ ├─detail
│ │ │ ├─controller
│ │ │ │ ├─request
│ │ │ │ └─response
│ │ │ ├─entity
│ │ │ ├─repository
│ │ │ │ ├─custom
│ │ │ │ └─impl
│ │ │ └─service
│ │ │ └─command
│ │ │ ├─request
│ │ │ └─response
│ │ ├─label
│ │ │ ├─entity
│ │ │ ├─repository
│ │ │ └─service
│ │ │ └─command
│ │ │ └─request
│ │ ├─labelRelationship
│ │ │ ├─entity
│ │ │ └─repository
│ │ └─watched
│ │ ├─controller
│ │ │ ├─request
│ │ │ └─response
│ │ ├─entity
│ │ ├─repository
│ │ │ ├─custom
│ │ │ └─impl
│ │ └─service
│ │ └─command
│ │ └─request
│ ├─image
│ │ ├─product_image
│ │ │ ├─controller
│ │ │ │ ├─request
│ │ │ │ └─response
│ │ │ ├─entity
│ │ │ ├─repository
│ │ │ └─service
│ │ │ └─command
│ │ └─review_image
│ │ └─entity
│ ├─option
│ │ ├─controller
│ │ │ ├─request
│ │ │ └─response
│ │ ├─entity
│ │ ├─repository
│ │ └─service
│ │ └─command
│ ├─orderProduct
│ │ ├─contoller
│ │ ├─entity
│ │ ├─repository
│ │ └─service
│ ├─orders
│ │ ├─controller
│ │ │ ├─request
│ │ │ └─response
│ │ ├─entity
│ │ ├─repository
│ │ └─service
│ │ └─command
│ │ ├─request
│ │ └─response
│ ├─product
│ │ ├─controller
│ │ │ ├─request
│ │ │ └─response
│ │ ├─entity
│ │ ├─repository
│ │ └─service
│ │ └─command
│ ├─productType
│ │ ├─controller
│ │ │ ├─request
│ │ │ └─response
│ │ ├─entity
│ │ ├─repository
│ │ └─service
│ │ └─command
│ ├─product_review
│ │ ├─controller
│ │ │ ├─request
│ │ │ └─response
│ │ ├─entity
│ │ ├─repository
│ │ └─service
│ │ └─command
│ ├─selectedContent
│ │ ├─entity
│ │ ├─repository
│ │ └─service
│ ├─study
│ │ ├─entity
│ │ └─repository
│ └─user
│ ├─controller
│ │ ├─request
│ │ └─response
│ ├─entity
│ ├─repository
│ └─service
│ └─command
├─global
│ ├─api
│ │ ├─response
│ │ └─service
│ │ └─command
│ ├─auth
│ │ ├─controller
│ │ │ ├─request
│ │ │ └─response
│ │ ├─jwt
│ │ └─service
│ ├─config
│ ├─event
│ ├─Interceptor
│ └─response
│ └─exception
└─util
├─domain
│ ├─alert
│ │ └─controller
│ │ └─event
│ ├─connect
│ │ ├─controller
│ │ │ └─request
│ │ ├─entity
│ │ ├─repository
│ │ └─service
│ │ └─command
│ └─user
│ ├─entity
│ └─service
│ └─dto
└─global
├─config
├─entity
├─response
│ └─exception
└─service
└─command
├─common
│ └─__pycache__
├─dto
│ └─__pycache__
├─models
├─router
│ └─__pycache__
├─service
│ └─__pycache__
└─__pycache__
├─domain
│ └─log
│ ├─controller
│ │ ├─event
│ │ ├─request
│ │ └─response
│ ├─entity
│ ├─repository
│ └─service
│ └─command
└─global
├─batch
├─config
└─response
└─exception
├─domain
│ ├─advertVideo
│ │ ├─controller
│ │ ├─entity
│ │ ├─repository
│ │ └─service
│ └─contents
│ └─detail
│ ├─controller
│ │ └─response
│ ├─entity
│ ├─repository
│ └─service
└─global
├─config
├─event
└─response
└─exception
├─assets
├─components
│ ├─AdManagement
│ ├─Arrow
│ ├─Button
│ ├─Calendar
│ ├─Carousel
│ ├─Container
│ ├─Enroll
│ ├─Keyboard
│ ├─Modal
│ ├─Nav
│ ├─Select
│ └─Sidebar
├─pages
│ ├─AdEdit
│ ├─AdEnroll
│ ├─AdManagement
│ │ ├─All
│ │ └─Dots
│ ├─Category
│ ├─Landing
│ ├─Main
│ ├─MyPage
│ │ ├─Enterprise
│ │ └─SalesManagement
│ ├─ProductManagement
│ ├─Review
│ ├─Search
│ ├─Streaming
│ ├─TVLogin
│ └─WebLogin
└─store
├─lib
│ ├─constant
│ │ └─animation
│ ├─model
│ │ └─pg
│ │ ├─danal
│ │ ├─daou
│ │ ├─kcp
│ │ ├─naver
│ │ ├─settle
│ │ └─tosspayments
│ ├─models
│ ├─providers
│ ├─screen
│ │ ├─advert
│ │ ├─cart
│ │ ├─error
│ │ ├─home
│ │ ├─login
│ │ ├─myStad
│ │ │ ├─shop
│ │ │ ├─stad
│ │ │ └─user
│ │ ├─order
│ │ ├─product
│ │ └─review
│ ├─services
│ └─widget
└─test
1. 스트리밍 서비스
버퍼링 없는 대용량 파일 스트리밍을 위해 동영상을 1MB 단위로 나눠 전송
- HttpRange: 클라이언트가 요청한 특정 시점부터 재생할 수 있도록 시작지점에 대한 정보 전달
- ResourceRegion: 버퍼링을 최소화하기 위해 시작지점부터 1MB씩 응답
- Redis: 다운로드할 url 조회 과정에서 DB connection을 Redis의 Cache를 이용하여 속도 최대 2배 단축
- Prefetch: 광고 재생 시간에 백그라운드 다운로드를 통해 콘텐츠 버퍼를 60MB 확보
2. 맞춤형 광고 제공
사용자의 최근 시청 영상을 기반으로 맞춤형 광고 제공
- Word2Vector: 텍스트에서 단어를 벡터로 추출하여 벡터 간 유사도를 반영
- LSTM: 이전 입력 데이터를 기억해 다음 출력값을 결정
- AD Queue: YouTube 구독채널 정보 및 최근 시청 영상을 활용한 추천
3. 대시보드
광고주가 게시한 광고에 대한 신뢰도 높고 효율적인 통계 자료를 빠르게 제공
- Spring Batch: 광고주에게 광고와 판매에 대한 통계 데이터 제공
- 성능 개선: SpringBatch 로그 기록 자동화를 통해 기존 방식보다 160배 성능 향상
4. 크로스 디바이스
SSE connect 정보를 Event 송신 방식으로 TV와 휴대폰 간에 공유
5. 결제 서비스
다양한 PG사와 결제 수단 제공
- PortOne API: 사업자 번호 없이 테스트 환경으로 다양한 PG사와 결제 수단을 도입하고 실제 결제부터 자동 환불까지 가능
이태경 🍪Back-end 💎Team Leader |
최은희 💟Back-end |
이민형 🧗♂️Back-end |
박지운 🍖Back-end |
김은지 🌹Front-end |
이서윤 🍞Front-end |