본문 바로가기
개발(Development)/Media(오디오&비디오 개발)

스트리밍(Streaming)이란: 스트림(Stream), 버퍼(Buffer) 원리

by 카레유 2021. 11. 27.

# 스트림(Stream)이란?

"스트림이란 시간의 흐름에 따라 발생하는 연속적인 데이터의 흐름이다."

 

스트리밍의 원리 (출처: 직접 그림)

이게 무슨 말인지 이해하기 위해

먼저 스트림과 파일의 기본적인 차이부터 집고 넘어가자.

(이해하기 쉽게 단순화해서!)

 

파일은 mp3 처럼 4분 30초짜리 음원 데이터 전체가 기록되어 있다.

따라서 고정되어 있는 크기의 데이터를 처음부터 끝까지 읽어서 처리할 수 있다.

하지만 스트림은 파일과는 다르다.

스트림이란 계속해서 흘러 들어오는 데이터를 의미한다.

 

즉, 마이크에 대고 하는 이야기나, 비디오 카메라로 찍는 동영상 처럼 

입력장치를 통해 계속해서 들어오는 데이터의 흐름을 의미한다.

 

따라서 실제 데이터가 입력되기 전에는 어떤 데이터가 들어올지 알 수 없으며,

실시간으로 들어오는 데이터를 그때 그때 읽고 처리해야 한다.

 

혹은 유튜브 처럼 대용량의 데이터를 서버를 통해 받아서 재생하는 동영상의 경우,

데이터를 모두 다운로드 받아서 재생하려면 긴 딜레이가 발생하게 된다.

 

이를 막기 위해서는 

먼저 들어오는 데이터부터 조금씩 메모리의 임시공간에 저장하여 재생시켜 주어야 한다.

 

Stream (출처: 직접 그림)

구체적으로 프로그래밍 세계에서의 "스트림(stream)"은

마이크와 같은 입력장치나 서버로 부터 들어오는 일련의 데이터 흐름을 읽어 들이면서,

스피커와 같은 출력장치나 동영상플레이어로 데이터의 흐름을 내보내는 역할을 하는 "객체"라고 볼 수 있다.

 

스트림이 있기 전까지는 데이터 전체가 다운로드 되어야만 처리가 가능했다.

스트림이 가능해지면서 동영상 스트리밍, 오디오 스트리밍 등의 서비스가 가능해진 것이다.

 

그런데 컴퓨터는 계속해서 흘러 들어오는 데이터들을 정확히 어떤 방식으로 처리할까?

여기서 바로 버퍼(Buffer)가 출현한다.


# 버퍼(Buffer)란?

버퍼는 일반적으로는 스트림 데이터를 조금씩 읽고, 저장하고, 처리하고, 비우기를 반복하는 메모리 공간이다.

이런 행위를 버퍼링이라고 하며, 임시로 데이터를 저장하는 메모리 공간 혹은 데이터 자체를 버퍼라고 한다.

(일반적으로 RAM메모리의 일부공간이 버퍼를 위해 사용된다.)

 

Buffer (출처: 직접 그림)

 

즉, Buffer란 특정 용도로 활용하기 위해 임시로 저장하는 Binary 형태의 데이터 저장 객체이다.


# 스트림과 버퍼의 관계

예를 들어 "0 1 2 3 ... 99"라는 동영상 데이터가 스트리밍 된다면,

0부터 1, 2, 3 의 순서로 데이터들이 흘러 들어올 것이다.

 

컴퓨터가 데이터를 처리하려면 일단 메모리에 올려두어야 한다.

메모리에 올라온 데이터만 CPU가 읽어서 처리할 수 있기 때문이다.

(책상에 부품들을 올려놔야 조립할 수 있는 것과 같다.)

 

컴퓨터는 이 데이터들을 chunk(데이터를 처리하는 임의의 크기) 단위로 쪼개서 임시 공간(메모리: RAM의 일부 영역)에 저장해두고 처리를 시작한다.

그리고 처리가 완료되면 임시 공간을 비우고, 다음 데이터가 들어오길 기다린다.

 

즉, 한번에 10개씩(=chunk) 처리하기로 정했다면, 

먼저 0~9까지를 10개를 입력받아 메모리에 저장하고, 동영상 형식으로 변환시켜 비디오 플레이어로 재생하고 메모리를 비운다.

0~9의 데이터가 동영상으로 재생되고 있는 동안 그 다음 10~19 까지를 입력 받아 메모리에 저장하고 처리하고 또 비운다.

 

스트림은 이런 식으로 데이터를 chunk 단위로 임시공간(메모리)에 저장하고, 처리하고, 비우기를 반복한다.

이렇게 하면 어머어마하게 큰 데이터도 조금씩 조금씩 처리할 수 있는 매커니즘이 완성된다.

이게 바로 컴퓨터가 스트림을 처리하는 방식이다.

 

유튜브와 같은 동영상 스트리밍 서비스가 이런 원리로 작동한다고 볼 수 있다.

 

이미 눈치 챘겠지만,

스트림을 위해 데이터를 저장해두는 임시공간이 바로 버퍼(buffer)이고, 버퍼가 작동하는 방식을 버퍼링(buffering)이라고 한다.

따라서 버퍼의 크기는 chunk(데이터 처리 단위)와 같은 수준으로 설정되는게 일반적이다.


정리하면,

1. 스트림은 버퍼를 이용해 흘러 들어오는 데이터를 처리(입력&출력)하는 객체이고,

2. 버퍼는 스트림을 위해 데이터를 chunk단위로 쪼개어 임시로 저장해 두는 객체이다.

 

개인적으로는 스트림은 물레방아가 돌아가는 원리와 비슷하다고 생각한다.

 

물(입력데이터)이 계속해서 통(버퍼)에 담기다가, 

특정 수위가 되면 통이 엎어지면서 물(출력데이터)이 떨어져 물레방아를 돌리고,

떨어진 물(출력)이 물레방아를 돌리고 있는 동안, 새로운 물(입력)이 통(버퍼)에 또 채워지길 반복하는 것이다.

 

너무 올드한 비유였나.

클래식하다고 해두자.

 

프로그래밍 언어들(Java, 자바스크립트 등)은 각자의 방식으로 스트림과 버퍼를 처리한다.

 

▼Javascript에서 Buffer 다루는 방식은 아래글 참고

자바스크립트 버퍼(Buffer): ArrayBuffer, TypedArray 파헤치기!

 

▼Javascript에서 미디어 스트림을 다루는 방법은 아래글 참고▼

자바스크립트 Media Capture and Streams API: MediaStream, MediaStreamTrack

 

 

 

댓글