Phonon 멀티미디어 프레임워크
서론
Qt 는 Phonon 멀티미디어 프레임워크를 사용하여 다양한 멀티미디어 포맷의 데이터를 플레이 하는 기능을 제공한다. 미디어(데이터)는 파일이나 QURL을 이용하여 인터넷에서 스트리밍형태로 읽을 수 있다.
여기에서는 Phonon의 주요 컨셉에 대해서 알아 보도록 하고, 아키텍쳐와 코아 API 클래스, 그리고 이 클래스들을 사용하여 예제를 해 보도록 하자.
아키텍쳐
Phonon은 세가지 기본 개념(media object, sink, path)이 있다. media object는 미디어 소스(데이터)를 관리하고 시작, 중지, 일시중지 같은 간단한 플레이 컨트롤을 제공한다. sink는 Phonon에서 비디오 렌더링을 위젯에 출력하거나, 사운드 카드에 오디오 (데이터)를 전송하는, 미디어 출력을 담당한다. Path는 Phonon object에 접속하는데 사용된다. Phonon의 media object, sink 그래프를 보자.
아래 예는 오디오 출력의 미디어 그래프이다.
[##_1C|2582704748.png|width="347" height="139" alt="사용자 삽입 이미지"|_##]
오디오 출력은 media object에 의해 시작되고 관리된다. 미디어 스트림은 Path를 통해 어떠한 모든 Sink에 접속할 수 있다. 여기서는 데이터가 Sink되면 일반적으로 사운드카드를 통해 소리가 출력된다. 당근... 오디오 출력을 예로 든거니깐... ㅡㅡ;
Media Objects
미디어 오프젝트는 MediaObject 클래스의 인스턴스로서 미디어 스트림을 연주하거나 중지, 일시중지하는 기본적인 컨트롤을 할 수 있게 해준다. 간단한 미디어 플레이어라고 보면 되겠다.
미디어 데이터는 미디어 오브젝트가 갖고 있는 미디어 소스로부터 나온다. 미디어 소스는 MediaSource 클래스의 인스턴스로서 Phonon에 포함된 오브젝트이며, 동시에 Phonon 그래프의 일부이다. 미디어 소스는 RAW 데이터 형태로 미디어 오브젝트에 공급된다. 데이터는 파일에서 읽어 올수도 있고 네트워크를 통해 스트리밍 형태로 읽을 수도 있다. 미디어 소스의 컨텐츠는(표현 하고자 하는 정보... 뭐.. 동영상이나 오디오 데이터겠죠..)를 미디어 오브젝트에 의해 해독된다.
미디어 오브젝트는 항상 기본 생성자로 인스턴스되고, 미디어 소스를 입력한다. 구체적인 예제 코드는 이 문서의 뒷부분에 표시해 놓겠다.
(기본적인 시작, 중지, 일시중지 기능만 있는) 미디어 오브젝트를 좀더 보완해서 미디어에 추가 기능을 제공하기 위해 Phonon에서는 MediaController를 제공한다. 예를 들면 챕터??, 메뉴, DVD 타이틀들은 MediaController에 의해 관리된다.
Sinks
sink는 그래프에서 미디어 를 출력하는 노드이다. sink는 출력을 다른 노드로 하지 않는다.(다른 sink로 출력하지 않는다는 의미로 보인다.) sink는 일반적으로 랜더링 디바이스이다.
Phonon 미디어 그래프에서 sink의 입력은 MediaObject에서 나온다. though it might have been processed through other nodes on the way.(이건 몰것다..)
MediaObject가 플레이를 컨트롤 하는 동안, sink 는 미디어의 조작을 위한 기본 컨트롤 작업을 한다. 예를 들면, 오디오 sink로 볼륨이나 음소거를 컨트롤 할 수 있다. 이는 가상 오디오 디바이스처럼 동작하게 한다. 또 다른 예제는 QWdiget 위에 비디오를 렌더링하고 비디오의 밝기(Brightness), 색상(Hue), 비율(크기.. Scaling)을 변경할 수 있는 VideoWidget이다.
동영상(영상과 오디오가 같이 플레이되는 구조) 플레이 하는 Phonon 그래프는 다음과 같다.
[##_1C|5908905848.png|width="349" height="214" alt="사용자 삽입 이미지"|_##]
Processors
Phonon은 미디어 스트림을 직접 조작하는 것을 허용하지 않는다. 미디어 오브젝트에 미디어 스트림을 입력한 후에는 그 누구도 프로그램적으로 변경할 수 없다. 따라서 이 작업(조작;Processors)을 할 수 있게 Phonon 그래프에서 MediaObject와 Sink 사이에 Path라 불리우는 또다른 노드를 가지고 있다. Phonon에서 Processors는 Effect 클래스이다.(데이터의 형태를 변환 시키는 클래스라고 보면 된다..)
렌더링 프로세스에 추가될때, processor는 미디어 스트림을 변경 하고, Phonon 그래프의 한 부분으로 활성화 된다. 미디어 스트림의 변형을 중지하려면 processor를 삭제해야 한다.
Effect 클래스는 미디어 스트림을 조작하는 방법에 영향을 미치는 컨트롤을 가지고 있다. 한 예로, processor 오디오에 depth effect를 적용하고 depth의 양을 컨트롤 할 수 있다. Effect 는 언제든지 설정될 수 있다.
Playback
Phonon은 편리한 함수를 가지고 있다. 오디오 파일을 플레이 하기 위해서는createPlayer() 함수를 이용할 수 있다. 이 함수는 필요한 그래프를 설정하고 미디어 오브젝트 노드를 리턴한다. 그다음 play() 함수를 호출함으로 사운드가 출력되기 시작한다.
위와 비슷하게 VideoPlayer 클래스를 사용하여 비디오 파일들을 플레이 할 수 있다.
VideoPlayer는 비디오가 그려질 위젯이다.
.pro 파일에 다음과 같이 추가해 줘야 한다.
Phonon은 미디어 플레이에 필요한 몇몇 위젯도 포함된다. - 탑색을 위해서는 SeekSlider, 볼륨 컨트롤은 VolumeSlider, 효과 파라미터를 조정하기 위한 EffectWidget들이다. API 도큐먼트를 찾아보면 이 위젯들에 대해 공부할 수 있다...(찾아보란 소리.... ㅡㅡ;)
Building Graphs
위에서 이야기한 간단한 함수들보다 보다 자유롭게 미디어들에 대해 프로그래밍을 하고 싶다면, 자기만의 방법을 만들 수 있다. 우리는 이제 미디어 출력하는 방법을 어떻게 구성하는지 알아보려고 한다. 미디어 오브젝트의 play() 함수를 호출하는 것이 미디어 출력 방법의 시작이다.
만일 미디어 소스에 여러가지 형태(예를 들면 비디오와 오디오가 한 파일이 동시에 있는 경우)의 미디어가 같이 포함되어 있다면, 미디어를 표현하려면 두개의 출력 노드가 있어야하며 하나는 비디오, 다른 하나는 오디오를 출력하는데 사용된다.
자.. 이제 아키텍쳐 섹션에서 소개된 오디오 출력 방법에 주목해 보자.
Audio
오디오를 출력할때, 미디어 오브젝트를 생성하고, 이것을 AbstractAudioOutput 클래스를 상속한 오디오 출력 노드에 연결한다. 그러면 사운드카드로 오디오가 출력된다.
입력되는 소스의 미디어 타입은 Phonon이 찾아주기때문에 거기에 신경쓸 필요는 없다. 만일 소스가 여러가지 미디어 포맷을 가지고 있다하더라도 자동으로 핸들링된다.
미디어 오브젝트는 항상 기본 생성자로 생성되서 모든 종류의 미디어 포맷을 핸들링한다.
여기서는 Phonon::MusicCategory 설정은아무런 영향을 미치지 못한다. 카테고리는 KDE에서 컨트롤 판넬에서 사용되는 플레이 컨트롤이다.
AudioOutput 클래스는 오디오 미디어를 사운드카드에 출력한다. 이것(사운드 카드)은 OS의 오디오 디바이스중의 하나이다. 오디오 디바이스는 사운드 카드 혹은 윈도우즈의 DirectShow같은 것일 수 있다. setOutputDevice()로 하나의 디바이스가 설정되지 않은 상태에 2개 이상의 디바이스(실제 사운드 카드나 DirectShow)가 존재할 경우 기본 디바이스로 선택된다.
AudioOutput 노드는 back end에 의해 지원되는 모든 오디오 포맷이 잘 작동하므로 미디어 소스가 가지고 있는 포맷에 대해 (프로그래머가) 알 필요가 없다.
오디오를 출력하기 위한 고급 예제는 Phonon Music Player http://doc.trolltech.com/4.7/phonon-qmusicplayer.html 를 참고하기 바란다.
Autio Effects
미디어 스트림은 직접적으로 조작할 수 없기 때문에 미디어 스트림을 처리할 수 있는 노드를 만들었다. 이 노드들은 미디어 오브젝트와 출력 노드의 사이에 표시된다.
미디어 스트림을 처리하는 노드는 Effect 클래스를 상속받는다. 이 효과들은 하위 시스템에 의존적이다. 이 효과들 대부분은 Phonon에 의해 제공된다. Querying Backends for Support 섹션을 보면 각각의 시스템이 제공하는 효과 정보를 찾을 수 있다.
위에서 Path를 사용해서 예를 보였던 것을 계속 사용하겠다.
시스템에서 첫번째로 지원하는 효과를 간단하게 찾아보았다.
만일 미디어 오브젝트가 플레이 중이라면, 이 효과는 추가(insertEffect)되는 즉시 시작될 것이다. 효과를 중지하려면 Path클래스의 removeEffect() 함수를 사용하면 된다.
비디오를 플레이하기 위해서 VideoWidget이 제공된다. 이 클래스는 비디오 스트림을 위젯위에 그리는 기능을 한다. 위젯은 비디오를 출력할 수 있는 사용가능한 디바이스를 자동으로 찾는다. 이것은 윈도우즈의 다이렉트쇼 같이 Qt 어플리케이션과 그래픽 카드 사이의 일반적인 기능이다.
비디오 위젯은 미디어 스트림에 있는 오디오를 출력하지 않는다.(당연... 화면이 소리내는거 봤나... 화면이 소리를 내면 A/S를 받아야 할 일이죵!!) 만일 오디오도 플레이 하기 위해서는 AudioOutput node가 필요하다. 앞의 섹션에 그림에서 보여준 것처럼 생성하고 연결해주면 된다.
다음과 같이 생성해주고 play() 함수만 호출해주면 된다.