Tizen 멀티미디어 프레임워크는 GStreamer 오픈 소스 프로젝트를 기반으로 합니다. 미디어 프레임워크를 사용하면 이미지, 비디오, 오디오 및 VoIP를 재생하고 조작할 수 있습니다. Tizen 플랫폼은 웹 브라우저에서 html5 비디오/오디오 태그와 임베디드 재생을 지원합니다. 또한 이미지 캡처와 비디오 녹화 및 오디오/비디오 재생 서비스도 제공합니다.
The Content API는 장치에서 사용할 수 있는 멀티미디어 콘텐츠(예: 오디오, 비디오, 음악 파일) 검색 방법을 제공합니다. 필터는 특정 미디어 항목을 검색(그리고 특정 폴더를 검색)하는 데 사용할 수 있습니다. API는 또한 특정 미디어 항목 특성에 대한 설정도 지원합니다. 애플리케이션이 시작될 때 콘텐츠 개체는 Tizen 개체에서 자동으로 인스턴스화됩니다. The Tizen.content 는 미디어 콘텐츠 검색 기능을 제공하는 ContentManager인터페이스 인스턴스를 검색하는 데 사용할 수 있습니다.
The ContentManager 인터페이스는 getDirectories 및 find 메서드가 있는 항목 및 미디어 폴더 검색 기능을 제공합니다. 발견된 폴더 또는 항목 목록이 성공 콜백에서 반환되었습니다.
장치에 있는 모든 미디어 폴더를 찾으려면 먼저 ContentManager 인터페이스 인스턴스를 가져오고 manager.getDirectories() 메서드를 호출합니다(아래와 같이 filter 매개 변수 없이).
// Define the error callback for all the asynchronous calls
function onError(response) {
console.log( "The following error occurred: " + response.name);
}
// got the folder list as asynchronous calls
function DirectoryArray(directories) {
console.log("Found directories " + ", directories.length: " + directories.length);
for (var i = 0; i < directories.length; i++) {
console.log(i + ":" + " title: " + Directories[i].title);
console.log("path : " + Directories[i].folderURI);
}
}
// Get a local media source.
var manager = Tizen.Content;
// Let's try to retrieve the folder list.
manager.getDirectories(DirectoryArray,onError);
검색에 성공하면 성공 콜백이 호출되고 모든 폴더 목록이 ContentDirectories 개체 배열 형태로 반환됩니다.
스크립트를 추가하지 않고 애플리케이션에 오디오 플레이어를 추가하려면 audio 태그를 사용합니다. 오디오 요소에 컨트롤 특성이 설정된 경우에는 오디오 플레이어가 기본 오디오 컨트롤 집합을 표시합니다. 기본 플레이어를 사용하는 대신 JavaScript와 CSS를 통해 오디오 플레이어를 사용자 지정할 수도 있습니다.
사용 중인 브라우저가 HTML5 오디오 요소를 지원하지 않을 경우에는 오디오 태그를 사용하여 오류 메시지 또는 다른 재생 기술을 대체할 수 있습니다. 오디오 태그들 사이에 오류 메시지를 넣거나 외부 플레이어 컨트롤을 실행하는 코드를 삽입할 수 있습니다.
다음 코드 예제에서는 HTML5 코드에 오디오 재생 지원 기능을 임베딩하는 방법을 보여줍니다.
Your device or browser cannot play this audio file
오디오 요소의 특성
Tizen은 모든 HTML5 오디오 특성을 지원합니다. 오디오 파일을 지정하려면 src 특성을 사용하고 내장 플레이어 컨트롤이 사용되도록 하려면 controls 특성을 사용합니다.
HTML 링크와 마찬가지로 상대 경로 또는 전체 URI 형태로 오디오 경로를 지정할 수 있습니다. 예를 들어 상대 경로는 "media/audiofile.mp3"과 같은 형태고, 전체 URI는 "http:\\www.example.com\media\audiofile.mp3"과 같은 형태입니다.
controls
이 특성을 사용하여 오디오에 기본 컨트롤을 추가할 수 있습니다. The controls특성은 boolean 값입니다. 이 특성을 사용하여 오디오 컨트롤을 표시해 볼륨, 검색, 일시 중지/다시 시작 등을 포함한 오디오 파일 재생을 제어할 수 있습니다.
loop
이 특성을 사용할 경우, 파일의 끝에 도달하면 자동으로 플레이어가 시작 부분으로 돌아갑니다.
autoplay
이 특성을 사용하면 페이지 로드 후 곧바로 재생이 시작되도록 플레이어를 설정할 수 있습니다.
autobuffer
이 특성을 사용하면 자동 실행으로 설정되어 있지 않더라도 자동으로 버퍼링이 시작되도록 오디오를 설정할 수 있습니다.
preload
이 특성을 사용하면 오디오가 페이지 로딩 시 로드되고 실행 준비가 되도록 지정할 수 있습니다. 이 특성은 autoplay 이 사용된 경우 무시할 수 있습니다.
이 특성을 사용하면 큰 파일의 버퍼링에 적합하도록 오디오 요소를 설정할 수 있습니다. 세 가지 가능한 값 중에서 하나를 설정할 수 있습니다.
"none" - 버퍼링 안 함
"auto" - 미디어 파일 버퍼링
"metadata" - 미디어 파일의 메타 데이터만 버퍼링
소스 요소를 사용하여 복수 오디오 형식 지정
여러 개의 소스 파일을 source 요소를 사용해서 지정해 서로 다른 브라우저에 대해 다른 형식으로 인코딩된 오디오를 제공할 수 있습니다. 요소 소스는 src 특성( audio 태그)를 대체합니다. Unlike the src 특성과 달리 여러 개의 source 요소를 audio 태그 안에 사용할 수 있습니다. 브라우저는 실제 작업 가능하다고 인식된 첫 번째 소스 요소에 의해 참조되는 파일을 로드합니다. 첫 번째 예를 다시 살펴보겠습니다. 이번은 소스 특성을 보십시오.
오디오 요소는 여러 소스 요소를 포함할 수 있으며, 각 요소는 오디오 파일에 대한 URL을 지정합니다. 브라우저는 문서 순서대로 각 소스 요소를 평가하며 파일을 재생할 수 있는지 여부를 결정합니다. 첫 번째 소스 요소가 브라우저가 재생할 수 없는 오디오 형식을 참조하는 경우에는 다음 번 소스 요소를 평가합니다. HTML5 브라우저는 지원되는 코덱을 하나 찾을 때까지 각 소스 요소를 확인합니다. 브라우저가 모든 소스 요소를 평가하고 재생 가능한 요소를 찾을 수 없는 경우, 오디오 요소 내에 포함되는 텍스트(보통 오류 메시지)를 표시합니다.
사용 Type 특성
여러 가지 형식의 오디오 소스가 있을 때는 type 특성을 사용하여 더 구체적으로 지정할 수 있습니다. The type 특성은 파일을 로드할지 여부를 브라우저에 알립니다.
브라우저는 "type"에 언급된 파일 형식을 지원할 수 있는지 여부를 결정합니다. 재생할 수 없는 형식이면 로드를 시도하지 않습니다. 특성이 없을 경우 브라우저는 지원되는 것을 찾을 때까지 지정된 모든 오디오 형식을 로드합니다. type 특성은 선택적입니다.type 특성의 값은 유효한 MIME 형식이어야 합니다.
HTML5 audio not supported
사용 Codec 특성
때때로 동일한 유형과 다른 코덱이 지원될 경우, type 특성과 함께 코덱을 지정하면 브라우저가 지원되는 코덱만 액세스할 수 있습니다. type 특성과 함께 codec 특성을 사용하면 브라우저가 파일을 로드할지 여부를 결정하고 불필요한 로드 프로세스를 없앤 후 나중에 필요할 때 지원되는 형식의 유효성을 검사하는 데 도움이 됩니다.
오디오 항목은 find메서드(ContentManager 인터페이스)를 사용하고 AttributeFilter 개체를 인수로 사용해서 검색할 수 있습니다.
find - 모든 미디어(오디오/비디오/이미지) 항목을 검색합니다.
// Define the error callback for all the asynchronous calls
function onError(response) {
console.log( "The following error occurred: " + response.name);
}
//List of audio items on the phone.
function mediaItemArray (contents) {
console.log("Successfully retrieved the list of Audio items");
for (var i=0; i < contents.length; i++) {
console.log(i + ":" + contents[i].type + ":" + contents[i].title + ":" +contents[i].mimeType);
console.log("album:" + contents[i].album);
console.log("artists:" + contents[i].artists[0]);
console.log("duration:" + contents[i].duration);
console.log("playedTime :" + contents[i].playedTime);
console.log("playCount :" + contents[i].playCount);
console.log("Item copyright: " + contents[i].copyright);
console.log("Item bitrate: " + contents[i].bitrate);
console.log("Item trackNumber: " + contents[i].trackNumber);
console.log("Item size: " + contents[i].size);
}
}
// Retrieve the ContentManager interface instance using the tizen global object
var manager = tizen.content;
// Let's try to retrieve the Audio list.
var contentType = "AUDIO";
var filter = new Tizen.AttributeFilter("type", "EXACTLY", ContentType);
console.log("Getting the list of audio files on the phone");
manager.find(MediaItemArray, onError, null, filter);
시스템이 사용자 필요에 따라 Tizen 기본 오디오 플레이어 애플리케이션을 시작하도록 요청할 수 있습니다. 사용 tizen.application.launch() 메서드를 사용하여,
서비스를 제공하는 오디오 플레이어 애플리케이션을 시작하도록 시스템에 요청할 수 있습니다. 이 메서드는 다음 인수를 사용합니다:
id - 시작할 애플리케이션의 식별자
successCallback - 호출이 성공적으로 종료될 때 호출되는 함수
errorCallback - 오류 발생 시 호출되는 함수
// function called on successful launch of music player application
function onsuccess() {
console.log("The application has launched successfully");
}
tizen.application.launch("org.tizen.music-player", onsuccess);
컨트롤과 함께 음악 플레이어 서비스 시작
필요에 따라, 애플리케이션 컨트롤과 함께 기본 미디어 플레이어 애플리케이션를 시작할 수 있습니다. 가령 특정 기능을 제공하기 위해 음악 플레이어가 필요한데, 요청된 서비스를 수행한 후 컨트롤을 애플리케이션으로 다시 되돌리기 원하는 경우를 들 수 있습니다.
아래와 같이 수행할 수 있습니다.
//Create an ApplicationControl object and define the desired functionality required from the application to be launched. The application needs to have an operation type suitable for selecting files, with URI as null, and the MIME type as "audio/*" .
var appControl = new tizen.ApplicationControl("http://tizen.org/appcontrol/operation/view", null, "audio/*");
//Define the format of the reply you want to receive from the application control
var appControlReplyCB =
{
// Reply is sent if the requested operation is successfully delivered
onsuccess: function(reply)
{
for (var num = 0; num < reply.data.length; num++)
{
console.log("reply.data["+num+"].key = "+ reply.data[num].key);
console.log("reply.data["+num+"].value = "+ reply.data[num].value);
}
}
}
// Call the launchAppControl() method to find a suitable application to select the audio files
tizen.application.launchAppControl(appControl, null,
function(){console.log("launch appControl succeeded");},
function(e){console.log("launch appControl failed. Reason: " + e.name);},
appControlReplyCB);
비디오 항목을 찾으려면 find메서드(ContentManager 인터페이스)를 AttributeFilter 개체(인수로써)와 함께 호출합니다.
getLocalMediaSource - 항목 검색에 사용해야 하는 로컬 미디어 소스를 가져옵니다.
getFolders - 미디어 콘텐츠를 비동기적으로 폴더로 가져옵니다.
findItems - 비동기적으로 휴대 전화의 모든 비디오를 검색합니다.
// Define the error callback for all the asynchronous calls
function onError(response) {
console.log( "The following error occurred: " + response.name);
}
//List of videos in the phone.
function mediaItems (media) {
console.log("Successfully retrieved the list of videos");
for(var i in media) {
console.log(i + ":" + media[i].type + ":" + media[i].title + ":" +media[i].mimeType);
console.log("geolocatoin-latitude:" + media[i].geolocation.latitude + " longitude:" + media[i].geolocation.longitude);
console.log("album:" + media[i].album);
console.log("artists:" + media[i].artists[0]);
console.log("duration:" + media[i].duration);
console.log("width:" + media[i].width);
console.log("height:" + media[i].height);
console.log("playedTime :" + media[i].playedTime);
console.log("playCount :" + media[i].playCount);
}
}
// Retrieve the ContentManager interface instance using the tizen global object.
var manager = tizen.content;
// Let's try to retrieve the videos list.
var contentType = "VIDEO";
var filter = new Tizen.AttributeFilter("type", "EXACTLY", contentType);
manager.find(MediaItems, onError, null, filter);
우선, 특정 스토리지 유형에서 폴더를 찾은 후 find메서드(ContentManager 인터페이스)를 사용하여( AttributeFilter 개체를 인수로써 전달) 비디오 목록을 쿼리해야 합니다.
아래 예제는 내부 메모리의 모든 비디오 항목을 나열합니다.
var mediaSource;
var index = 0;
var len = 0;
var folderArray = [];
var typeFilter = new Tizen.AttributeFilter("type", "EXACTLY", "VIDEO");
// Define the error callback for all the asynchronous calls
function onError(response) {
console.log( "The following error occurred: " + response.name);
}
//List of videos in the phone.
function MediaItems (media) {
console.log("Successfully retrieved the list of videos");
for(var i in media) {
console.log(i + ":" + media[i].type + ":" + media[i].title + ":" +media[i].mimeType);
console.log("geolocatoin-latitude:" + media[i].geolocation.latitude + " longitude:" + media[i].geolocation.longitude);
console.log("album:" + media[i].album);
console.log("artists:" + media[i].artists[0]);
console.log("duration:" + media[i].duration);
console.log("width:" + media[i].width);
console.log("height:" + media[i].height);
console.log("playedTime :" + media[i].playedTime);
console.log("playCount :" + media[i].playCount);
}
if(index < len) {
console.log("Start getting the list of videos from folder with id: "+ folderArray[index].id);
mediaSource.find(MediaItems, onError, folderArray[index++].id, typeFilter);
}
}
// get the folder list as asynchronous calls
function MediaFolders (folders){
console.log(folders.length + " folder(s) found");
len = folders.length
for (var i = 0; i < len; i++) {
if (folders[i].storageType == "INTERNAL") {
folderArray.push(folders[i]);
console.log(i + ":" + " title: " + folders[i].title);
console.log("id: " + folders[i].id);
console.log("path : " + folders[i].folderURI);
console.log("storageType : " + folders[i].storageType);
console.log("modifiedDate : " + folders[i].modifiedDate);
}
}
console.log(folders.length + " internal folder(s) found");
if(index < len) {
console.log("Start getting the list of videos from folder with id: "+ folderArray[index].id);
mediaSource.find(MediaItems, onError, folderArray[index++].id, typeFilter);
}
}
// Retrieve the ContentManager interface instance using the tizen global object.
mediaSource = = tizen.content;
console.log("Start getting the list of folders in internal memory");
// Let's try to retrieve the folder list.
mediaSource.getDirectories(MediaFolders,onError);
현재 애플리케이션에서 video 태그를 사용해서 비디오를 재생하지 않으려면, 필요에 따라 Tizen 기본 비디오 플레이어 애플리케이션을 시작하도록 시스템에 요청할 수 있습니다.
사용 Tizen.application.launchAppControl() 메서드를 사용하여, 서비스를 제공하는 오디오 플레이어 애플리케이션을 시작하도록 시스템에 요청할 수 있습니다. 이 메서드는 다음 인수를 사용합니다:
appControl - 애플리케이션 컨트롤 세부 정보를 설명하는 데이터 구조.
id - 시작할 애플리케이션의 식별자. ID가 null이거나 지정되지 않은 경우 시스템은
요청된 애플리케이션 컨트롤에 대해 시작할 애플리케이션을 찾으려고 합니다. [null 허용]
successCallback - 호출 성공적으로 끝날 때 호출할 메서드. [선택 사항] [null 허용]
errorCallback - 오류가 발생할 때 호출할 메서드. [선택 사항] [null 허용]
replyCallback - 애플리케이션이 실행된 애플리케이션에서 결과를 다시 가져올 때 호출할 메서드. [선택 사항] [null 허용]
//Create an ApplicationControl object and define the desired functionality required from the application to be launched. The application needs to have an operation type suitable for selecting files, with URI as null, and the MIME type as "video/*" .
var appControl = new tizen.ApplicationControl("http://tizen.org/appcontrol/operation/view", null, "video/*");
Define the format of the reply you want to receive from the application control:
var appControlReplyCB =
{
// Reply is sent if the requested operation is successfully delivered
onsuccess: function(reply)
{
for (var num = 0; num < reply.data.length; num++)
{
console.log("reply.data["+num+"].key = "+ reply.data[num].key);
console.log("reply.data["+num+"].value = "+ reply.data[num].value);
}
}
}
// Call the launchAppControl() method to find a suitable application to select the video files:
tizen.application.launchAppControl(appControl, null,
function(){console.log("launch appControl succeeded");},
function(e){console.log("launch appControl failed. Reason: " + e.name);},
appControlReplyCB);
후방 카메라로 비디오를 녹화하려면 Tizen의 기기 API 애플리케이션 시작 프로그램을 통해 기본 카메라 애플리케이션을 사용해야 할 수 있습니다. 현재 웹 애플리케이션이 기기의 후방 카메라와 직접 통신하는 것은 지원되지 않거나 노출된 API가 없습니다. 반면, 기본 애플리케이션은 Tizen::Media::Camera: 인터페이스를 사용하여 직접 후방 카메라에 액세스할 수 있습니다.
An ApplicationControl 인터페이스는 작업, URI, MIME 유형으로 구성됩니다.The ApplicationControl 는 카메라 애플리케이션에서 수행하는 작업에 대해 설명하고 ApplicationControlData인터페이스를 통해 후속 애플리케이션에서 결과를 가져올 수 있습니다. 여기서 ApplicationControl 인터페이스를 통해 애플리케이션 간에 데이터를 전달하는 데 사용된 키/값 쌍을 정의합니다.
var appControl = new tizen.ApplicationControl("http://tizen.org/appcontrol/operation/create_content", null, "video/*");
var appControlReplyCB = {
// callee now sends a reply
onsuccess: function(reply) {
for (var num = 0; num < reply.data.length; num++) {
console.log("reply.data["+num+"].key = "+ reply.data[num].key);
console.log("reply.data["+num+"].value = "+ reply.data[num].value);
}
},
// Something went wrong
onfail: function() {
console.log('Launch service failed');
}
};
//Launch the service with control
tizen.application.launchAppControl(appControl, null,
function(){console.log("launch appControl succeeded");},
function(e){console.log("launch appControl failed. Reason: " + e.name);},
appControlReplyCB);
전면 카메라를 사용하여 비디오를 녹화하려는 경우 W3C의 API "getusermedia"를 사용하십시오. 다음은 사용 방법을 보여주는 간단한 예입니다.
참고: 전면 카메라는 개발자 장치에서 사용할 수 없으므로 이 API는 장치에서 작동하지 않습니다. 웹캠을 포함한 에뮬레이터에서 제대로 작동합니다.
HTML 코드:
Javascript 코드:
function getVideoStream()
{
navigator.webkitGetUserMedia({video : true}, SuccessCallBack, errorCallBack);
}
function SuccessCallBack(stream)
{
var URL = window.webkitURL;
document.getElementById("videoPlay").src = URL.createObjectURL(stream);
}
function errorCallBack(error)
{
alert('No support for webkitGetUserMedia()');
}