스트리밍 영상을 텍스트로 바꾸기 위해서는 많은 밑작업이 필요한데.
가장 먼저 대상이 되는 스트리밍을 골라야한다.
대표적으로 Youtbue, Netflix, Watcha 등 수많은 스트리밍이 있지만, 네이버 스트리밍 플랫폼인 치지직의 영상을 받아와 스트리머의 목소리를 텍스트로 표현하는 간단한 태스크를 진행해보려고 한다.
네이버의 경우 스트리밍을 HLS 프로토콜을 사용하여 주고받고 있다.
여기서 HLS란게 무엇인지 알아야 효율적으로 원하는 오디오를 추출해올 수 있다.
그래서 HLS가 뭔데?
HLS는 HTTP LIVE STREAMING의 약자로서 Adaptive Bitrate Streaming을 지원하는 기술이다.
현대에 들어서 가장 많이 사용하는 비디오 스트리밍 프로토콜로서 라이브 환경에서의 최적화가 되어있는 프로토콜이다.
과거에 이 프로토콜이 없을 시절은 Progressive Download 방식을 사용했다.
이 방식은 이름 그대로 동영상 파일 전체를 통으로 받아서 다운로드가 완료되면 시청이 가능한 방식이다. 가장 쉬운 예로는 토렌트, 토렌트는 다운로드 받는 중에는 동영상을 시청 할 수 없다. 가장 원시적인 형태의 다운로드 방식으로 이러한 방식은 전체 파일을 다운로드하기 때문에, 네트워크 트래픽을 많이 발생시키는 문제와 실시간으로 영상을 시청하기에는 무리한 구조로서 HLS라는 방식을 사용하게 되었다. (그 와 비슷한 구조로 RTSP, RTMP 등의 프로토콜이 있으나 현재 기술적 한계와 보안 등 이슈로 HLS는 가장 널리 사용되고 있다)
HLS의 구조와 방식
HLS 파일의 구조는 크게 primary playlist(index file)와 media playlist(alternate index file), 그리고 segmented file로 나눈다.
세가지 구조에 대해 아주 간단히 설명하자면
privary playlist에는 Adaptive의 핵심이 되는 대역폭에 따른 media playlist url을 가지고 있다.
media playlist에는 특정 대역폭의 실행되어야하는 영상 URL과 영상을 실행하기 위한 주요 정보를 가지고 있다.
segmented file은 전체 미디어파일을 시간 간격으로 쪼개놓은 것으로 S3나 미디어 서버에 저장되어 있다.
결국 여기서 필요한건 경로를 통해 segemented file을 추출, 그리고 영상을 AI를 통해 텍스트화하면 끝이다.
아래는 참조를 위해 파일 구조를 첨부한다.
Primary Playlist
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=150000,RESOLUTION=416x234,CODECS="avc1.42e00a,mp4a.40.2"
http://example.com/low/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=240000,RESOLUTION=416x234,CODECS="avc1.42e00a,mp4a.40.2"
http://example.com/lo_mid/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=440000,RESOLUTION=416x234,CODECS="avc1.42e00a,mp4a.40.2"
http://example.com/hi_mid/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=640000,RESOLUTION=640x360,CODECS="avc1.42e00a,mp4a.40.2"
http://example.com/high/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=64000,CODECS="mp4a.40.5"
http://example.com/audio/index.m3u8
Plain Text
복사
태그 | 파라미터 | 역할 |
EXTM3U | 재생 목록이 확장 M3U 파일임을 나타냅니다. 이 파일 형식은 첫 번째 줄의 태그를 EXTM3U로 변경하여 기본 M3U 파일과 구별됩니다. 모든 HLS 재생 목록은 이 태그로 시작해야 합니다. | |
EXT-X-STREAM-INF | 다음에 나오는 URL이 또다른 playlist 파일임을 식별한다는 것을 나타냅니다. EXT-X-STREAM-INF 태그에는 다음과 같은 매개 변수가 있습니다. | |
AVERAGE-BANDWIDTH | (선택 사항이지만 권장됨) 변형 스트림의 평균 비트 전송률을 나타내는 정수입니다. | |
BANDWIDTH | (필수) 각 미디어 파일에 대한 전체 비트 전송률의 상한값(초당 비트 수)인 정수입니다. 상한 값은 재생 목록에 나타나거나 나타날 모든 컨테이너 오버헤드를 포함하도록 계산됩니다. | |
FRAME-RATE | (선택 사항이지만 권장됨) 변형 스트림의 최대 프레임률을 설명하는 부동 소수점 값입니다. | |
HDCP-LEVEL | (선택사항) 사용되는 암호화 유형을 나타냅니다. 유효한 값은 TYPE-0 및 NONE입니다. HDCP로 출력이 보호되지 않는 한 스트림이 재생되지 않을 수 있으면 TYPE-0을 사용합니다. | |
RESOLUTION | (선택 사항이지만 권장됨) 재생 목록의 모든 비디오를 표시할 선택적 표시 크기(픽셀)입니다. 이 매개 변수는 비디오를 포함하는 모든 스트림에 포함되어야 합니다. | |
VIDEO-RANGE | (인코딩에 따라 필수) SDR 또는 PQ의 유효한 값을 가진 문자열입니다. 전송 특성 코드 1, 16 또는 18을 지정하지 않은 경우 이 매개변수를 생략해야 합니다. | |
CODECS | (선택 사항이지만 권장됨) 쉼표로 구분된 형식의 목록을 포함하는 따옴표로 묶인 문자열입니다. 여기서 각 형식은 재생 목록 파일의 미디어 세그먼트에 있는 미디어 샘플 유형을 지정합니다. 유효한 형식 식별자는 RFC 6381 [RFC6381]에 의해 정의된 ISO 파일 형식 이름 공간에 있는 식별자입니다. |
Media Playlist
#EXTM3U
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-TARGETDURATION:10
#EXT-X-VERSION:4
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
http://example.com/sq00001.ts
#EXTINF:10.0,
http://example.com/sq00002.ts
#EXTINF:10.0,
http://example.com/sq00003.ts
#EXTINF:9.0,
http://example.com/sq00004.ts
#EXT-X-ENDLIST
Plain Text
복사
태그 | 역할 |
EXTM3U | 재생 목록이 확장 M3U 파일임을 나타냅니다. 이 파일 형식은 첫 번째 줄의 태그를 EXTM3U로 변경하여 기본 M3U 파일과 구별됩니다. 모든 HLS 재생 목록은 이 태그로 시작해야 합니다. |
EXT-X-PLAYLIST-TYPE | 전체 재생 목록 파일이 변경 가능성이 있는지에 대한 정보를 제공합니다. 이 태그는 EVENT 또는 VOD 값을 포함할 수 있습니다. EVENT의 경우에는 #EXT-X-ENDLIST가 없어 미디어 파일 리스트가 끝에 추가될 수 있습니다. VOD의 경우에는 이미 완성된 파일로서 모든 재생 목록 파일이 들어있고 #EXT-X-ENDLIST가 명시되어 있습니다. |
EXT-X-TARGETDURATION | 최대 미디어 파일 재생 시간을 지정합니다. |
EXT-X-VERSION | 재생 목록 파일의 호환성 버전을 나타냅니다. 재생 목록 미디어와 서버는 프로토콜 버전을 정의하는 HTTP Live Streaming 사양의 최신 버전의 IETF 인터넷 초안의 모든 조항을 준수해야 합니다. |
EXT-X-MEDIA-SEQUENCE | 재생 목록 파일에 나타나는 첫 번째 URL의 일련 번호를 나타냅니다. 재생 목록의 각 미디어 파일 URL에는 고유한 정수 시퀀스 번호가 있습니다. URL의 시퀀스 번호가 앞의 URL의 시퀀스 번호보다 1 높습니다. 미디어 시퀀스 번호는 파일 이름과 관련이 없습니다. |
EXTINF | 뒤에 오는 URL로 식별되는 미디어 파일을 설명하는 레코드 마커입니다. 각 미디어 파일 URL 앞에는 EXTINF 태그가 있어야 합니다. 이 태그에는 미디어 세그먼트의 지속 시간(초)을 지정하는 정수 또는 부동 소수점 표기법의 지속 재생시간 특성이 포함되어 있습니다. 이 값은 목표 재생시간(전체 미디어 재생시간)보다 작거나 같아야 합니다. |
EXT-X-ENDLIST | 재생 목록 파일에 미디어 파일을 더 이상 추가하지 않음을 나타냅니다. |
사실 이 모든걸 알 필욘 없다.
스트리밍을 텍스트로 라는 소기의 목적에 달성하기 위해 필요한 것은 결국 3가지다
1.
원하는 스트리밍 사이트에서 .m3u8 파일을 받아오는 것
2.
받아온 index playlist(.m3u8)를 통해 청크를 받아 서버 내의 영상으로(mp4)로 다운로드 하는 것
3.
변환된 미디어파일을 LLM을 통해 텍스트화 하는 것
글쓴이는 네이버 스트리밍 중계 플랫폼인 치지직 의 영상을 가져와 텍스트로 변환하려고 한다.
그러나 네이버는 치지직 관련된 API를 전혀 제공하고 있지않아. 개발자 도구를 통해 분석을 할 수 밖에 없다. 현재 비공식이지만 API를 다른 개발자들이 만들어서 제공하고 있으니 그걸 유용하게 사용하면 된다.
글쓴이의 경우 직접 커스텀해야 할 일이 생길 것 같아 오픈소스를 참조하여 작성한 네이버연동 API을 npm에 업로드 해두었다.
해당 라이브러리를 통해 치지직 채널의 .m3u8을 추출 할 수 있다.
음성 변환에 활용할 Whisper는 미리 서버에 설치해둔다.