Content API Guide

Content API Guide

Overview

The Content API provides functionality to discover multimedia contents (such as images, videos, or music) that are available on the device. Filters can be used to search for specific media items (also specific to a folder search). The API also supports setting attributes of specific media items. From a developer's perspective, the tutorial helps understanding the use the Content API to receive information about media content stored on internal and external storages. Also shows how to write a simple media content browser, which will show all directories with media items. Filters can be applied to look for only image, video, or audio files.

When the application is launched, a Content object is instantiated automatically in the tizen object. The tizen.content object is an instance of the ContentManager interface, which provides the multimedia content retrieval features.

Table of Contents

Prerequisites

The Content API provides different levels of access to search for multimedia content. To use this API, add the required permissions to the config.xml file.
You can enable the following permissions in the config.xml file:

Note: It is recommended that you edit config.xml file by using the Tizen IDE interface.

If you want to do it manually, add the following <feature> tag to the config.xml as shown below.

<?xml version="1.0" encoding="UTF-8"?>
<widget xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets" id="http://yourdomain/TizenContentAPI" version="1.0.0" viewmodes="maximized">
    <tizen:application id="UIoRYDQ7wy.TizenContentAPI" package="UIoRYDQ7wy" required_version="2.2"/>
    <content src="index.html"/>
    <icon src="icon.png"/>
    <name>TizenContentAPI</name>
    <tizen:privilege name="http://tizen.org/privilege/content.read"/>
    <tizen:privilege name="http://tizen.org/privilege/content.write"/>
</widget>

Note: Since the application will contain the Exit button, it will need the quitting functionality. To provide it, add the application.read feature.

Retrieve ContentManager Instance

You need have a ContentManager instance to use the Content-related functionalitieses. The method tizen.content retrieves the ContentManager interface instance using the tizen global object.The method returns an object that provides media item management features such as updating and finding media items, getting and browsing directories with media items on the device. For efficiency, it also provides batch operations on media items like Contact,
Calendar, and Messaging APIs.

Note: For accessing all Content API functionalities, you need to use the local ContentManager instance. The method, tizen.content returns the local mediasource object

Retrieving list of all Directories

For using Content capabilities, the platform default ContentManager object is required.The method tizen.content can be called, which returns the ContentManager object. This object provides operations to manipulate the media items. To get the list of all directories, use the method tizen.content.getDirectories(). It takes two callback functions as parameters, the first parameter is onMediaFolderArraySuccess callback function called on success, the second parameter ErrorCallback function.

 // Function to get list of all directories/folders
function getFoldersList() {
	var mediasource = null;
	mediasource = tizen.content;
	output.set('Searching for all directories...');
	try {
		mediasource.getDirectories(onMediaFolderListSuccess, onError);
	} catch (exc) {
		output.append('getDirectories() exception:' + exc.message);
	}
 }

The “mediasource.getDirectories” invokes the callback function onMediaFolderListSuccess on success.The function receives the list of all directories found as its argument, iterates through all the directories and prints the basic information.

 function onMediaFolderListSuccess(folders) {
   output.append(folders.length  + 'folder(s) found:');
   var table;
   for (var i = 0, len = folders.length; i < len; i++) {
	table = '<table>';
	table += '<tr><td> Folder name: </td><td>' + folders[i].title + '</td></tr>';
	table += '<tr><td> Folder URI: </td><td>' + folders[i].folderURI + '</td></tr>';
	table += '<tr><td> Storage type: </td><td>' + folders[i].storageType + '</td></tr>';
	table += '<tr><td> Modification date: </td><td>' + folders[i].modifiedDate + '</td></tr>';
	table += '</table>';
	output.append(table);
    }
}

The callback function “onError” is invoked, when the mediasource.getDirectories function returns with an error.This function can be used to implement the error handling functionality on specific error types. Below function just displays the error message.

function onError(response) {
    alert( "Error : " + response.name);
}

Retrieving list of Directories from Internal/External Storage

A list of directories from certain storage location i.e internal or external, can be retrieved using the content’s “getDirectories“ method. Firstly the ContentManager object need to be obtained using “tizen.content" method and invoke the method “getDirectories” with the ContentManager object as “source.getDirectories”.

// Function to get list of all directories from either internal or external storage
function getStorageSpecificList(){
	var source = null;
	source = tizen.content;
	source.getDirectories(onMediaStorageFilteredSuccess, onError);
}

On Success, the callback function “onMediaStorageFilteredSuccess” is invoked and displays all the directories from a specified storage type i.e internal or external.

function onMediaStorageFilteredSuccess(folders) {
    var type = document.getElementById('StorageType').value;
    output.set(folders.length + 'folder(s) found:');
    var table;
    for (var i = 0, len = folders.length; i < len; i++) {
    if (folders[i].storageType == type) {
       table = '<table>';
       table += '<tr><td> Folder name: </td><td>' + folders[i].title + '</td></tr>';
       table += '<tr><td> Folder URI: </td><td>' + folders[i].folderURI + '</td></tr>';
       table += '<tr><td> Storage type: </td><td>' + folders[i].storageType + '</td></tr>';
       table += '<tr><td> Modification date: </td><td>' + folders[i].modifiedDate + '</td></tr>';
       table += '</table>';
       output.append(table);
      }
    }
}

Retrieving list of all Media Items

The list all media items can be retrieved using ContentManager's “find()” method. Firstly the ContentManager object need to be obtained using “tizen.content and invoke the method “find()” with the ContentManager object as “mediasource.find()” .

// Function to get list of all media files
 function getAllMediaList(){
    var mediasource = null;
    mediasource = tizen.content;
    try {
	mediasource.find(onMediaListSuccess, onError);
	} catch (exc) {
  	console.log("findItems exception:" + exc.message);
	}
}

On Success, the callback function “onMediaListSuccess” is invoked and the function displays all the items i.e all image/Audio/Video files.The function receives a collection of all the media items as its argument.It iterates through all the media items and prints the basic information.

function onMediaListSuccess(items) {
    output.set('Items found...');
    for ( var i in items) {
    output.append('Item title: ' + items[i].title);
    output.append('Item URI: ' + items[i].itemURI);
    output.append('Item type: ' + items[i].type);
   }
}

Retrieving list for specific type of Item: Image, Audio, Video

List of all media items of a certain media type can be retrieved using ContentManager's “find()”method in conjunction with the filters. The type of media item can be be image,audio or video.

Firstly, the ContentManager's object need to be obtained using “tizen.content and invoke the method “find()” with
the ContentManager object as “mediasource.find()” with the filter parameter for type of item ("IMAGE", "VIDEO", "AUDIO") to be filtered

// Function to get list of all certain media files
 function getSelectedMediaList() {
    var mediasource = null;
    mediasource = tizen.content;
    var type = document.getElementById('MediaType').value;
    output.set('Searching for items of a type ' + type);
    var filter = new tizen.AttributeFilter ("type", "EXACTLY", type);
    try {
	mediasource.find(onMediaListSuccess, onError, null, filter);
    } catch (exc) {
	console.log("findItems exception:" + exc.message);
	return;
    }
}

This method uses the same Success callback function “onMediaListSuccess” as mentioned earlier to displays all the items i.e all image/Audio/Video files.
The above example uses “AttributeFilter” filter to find the specific media type, using the ”itemType field. Note: The third parameter in “find” method, directory ID is set to null.

Thus, the find operation will search media contents for all directories on the device. You can limit a search under a specific dierctory by passing the directory ID.

Retrieving list of items in a given Directory

The below function retrieves all the directory information (in an array to success callback function) using the “getDirectories” method on the ContentManager object (in this case, it’s mSource ).

// Function to get list of all directories
function getMediaFromFolder(){
try {
	mSource = tizen.content;
	output.set('Searching for media from folder...');
	mSource.getDirectories(onMediaFolderSearchSuccess, onError);
    } catch (e) {
	onError(e);
    }
}

The callback function onMediaFolderSearchSuccess() gets all media directories. The function iterates through all the array of directories. To identify the specific folder, the title attribute of each folder is compared to the user entered directory name. If the name matches, the method tizen.content.find() is
called with the directory ID to browse all items in that specified folder. For each of the items from the directory, print() method is called to display the name of the item

// Function for finding certain folder and print its content
function onMediaFolderSearchSuccess(folders) {
    var name = document.getElementById('FolderNameText').value;
    if (!name) {
	output.set('Error: Incorrect folder name');
	return;
     }
    for ( var i in folders) {
	if (folders[i].title == name) {
	output.append('Folder name: ' + folders[i].title + '');
        try {
		mSource.findItems(browseMediaInFolder, onError, folders[i].id);
		} catch(error) {
			alert('error: ' + error.message);
		}
	                return;
		}
	}
}

function print(item) {
	output.append("Title: " + item.title);
}

function browseMediaInFolder(items) {
	output.append('Looking for media in a folder');
	items.forEach(print);
}

Retrieving Details of a given Media Item

A similar approach to find the items can be followed here. The below function retrieves all the items (in an array to success callback function) using the “find” method on the ContentManager object (in this case, it’s mSource).

// Function to get all media files
function getRequiredMediaDetails() {
	try {
		mSource = tizen.content;
		output.append('Searching for item...');
		mSource.find(onMediaFileListSuccess, onError);
	} catch (e) {
		onError(e);
	}
}

On success (“mSource.find” method ), the callback function “onMediaItemArraySuccess()” is invoked with the array of items (“Files” here). The function prints the details of the media file and creates the button to update the media file later. Copy the “Files” object to newly created FilesForUpdate global variable.
This variable will be used to update the file. Create one button per file, which is displayed using HTML code. On a update button click, “update()” function is called, with id as the argument. The argument (id) will be used to distinguish the correct item from the FilesForUpdate object.

// Function to display details of the media file
var FilesForUpdate = null;

function onMediaFileListSuccess(Files) {
	var name = document.getElementById('MediaNameText').value;

    if (!name) {
		console.log('Error: Incorrect media file name');
		return;
	}
    //make a copy of "Files" to update one of selected
    FilesForUpdate = Files;
    console.log('Files found...');
    for ( var i in Files) {
	var File = Files[i];
	if (File.title == name) {
		output.append('File name: ' + File.title);
		output.append('File type: ' + File.type);
		output.append('File identifier: ' + File.id);
		output.append('File mimeType: ' + File.mimeType);
		output.append('File releaseDate: ' + File.releaseDate);
		output.append('File modifiedDate: ' + File.modifiedDate);
		output.append('File description: ' + File.description);
		output.append('File rating: ' + File.rating);
		for ( var j in File.thumbnailURIs) {
			output.append('File thumbnailURI: ' + File.thumbnailURIs[j]);
		}
		switch (File.type) {
       		   case 'IMAGE':
 			RetrieveImageInfo(File);
			break;
		   case 'VIDEO':
			RetrieveVideoInfo(File);
			break;
		   case 'AUDIO':
			RetrieveAudioInfo(File);
			break;
		 }

	// create Update buttons
           output.append("<button onclick=\"updateFile(" + i
                    + ")\">Update File " + File.title + "</button>");
			return;
		}
	}
	console.log("File " + name + " not found...");
}

Below functions have been implemented to print rest of the “File” specific properties. Each function displays file details depending on its media format (Image/Audio/Video).

// Function to display Image attribute details
function RetrieveImageInfo(item) {
	try {
		output.append('Item width: ' + item.width);
		output.append('Item height: ' + item.height);
		output.append('Item location, latitude: ' + item.geolocation.latitude);
		output.append('Item location, longitude: ' + item.geolocation.longitude);
	} catch (e) {
		onError(e);
	}
}

// Function to display Video attribute details
function RetrieveVideoInfo(item) {
	try {
		output.append('Item album: ' + item.album);
		for ( var i in item.artists) {
			output.append('Item artist: ' + item.artists[i]);
		}
		output.append('Item duration: ' + item.duration);
		output.append('Item width: ' + item.width);
		output.append('Item height: ' + item.height);
		output.append('Item playedTime: ' + item.playedTime);
		output.append('Item playCount: ' + item.playCount);
	} catch (e) {
		onError(e);
	}
}

// Function to display audio attribute details
function RetrieveAudioInfo(item) {
	try {
		output.append('Item album: ' + item.album);
		for ( var i in item.artists)
			output.append('Item artist: ' + item.artists[i]);
		for ( var i in item.composers)
			output.append('Item composer: ' + item.composers[i]);
		for ( var i in item.genres)
			output.append('Item genre: ' + item.genres[i]);

		output.append('Item lyrics type: ' + item.lyrics.type);
		output.append('Item lyrics timeStamps: ' + item.lyrics.timeStamps);
		output.append('Item lyrics texts: ' + item.lyrics.texts);

		output.append('Item copyright: ' + item.copyright);
		output.append('Item bitrate: ' + item.bitrate);

		output.append('Item trackNumber: ' + item.trackNumber);
		output.append('Item duration: ' + item.duration);
		output.append('Item size: ' + item.size);
		output.append('Item playedTime: ' + item.playedTime);
		output.append('Item playCount: ' + item.playCount);

	} catch (e) {
		onError(e);
	}
}

Updating an item

The metadata attributes of the media items can be updated with the MediaSource.update method. The example illustrates how to check whether a specific attribute is editable or not and update an attribute.

// Function to update a file attribute
function updateFile(id) {
	try {
		if (FilesForUpdate[id].type == 'IMAGE') {
			FilesForUpdate[id].rating += 1;
			output.set('Increased rating attribute');
		} else {
			FilesForUpdate[id].playCount++;
			output.set('Increased playCount attribute');
		}

	    try {
	    	mSource.update(FilesForUpdate[id]);
	    } catch(error) {
	    	onError(error);
	    }
	} catch (e) {
		onError(e);
	}
}

function onUpdateSuccess() {
	output.append("Item updated");
}

Screenshot(s):

When queried for the directories.

Development Environment:

Tizen SDK

Version : 2.2.0
Build id : 20130708-1957

Note:
The Content API sample application is available for reference (See under File Information section for attachment).

File attachments: