Adding Video Metadata

As we discussed in Chapter 9, Android's MediaStore content provider has a portion, MediaStore.Video, dedicated to video in addition to the portions for image and audio files and metadata that we have previously looked at.

When triggering the Camera application via an intent, the Uri to the newly recorded video file that is returned is a content:// style Uri, which is used in combination with a content provider—in this case, the MediaStore. In order to add additional metadata, we can use the Uri returned to update the video's record in the MediaStore.

As with any content provider, we use the update method on a ContentResolver object obtained from our Context. We pass in the content:// style Uri and the new data in the form of a ContentValues object. Since we have a Uri to a specific record, we don't need to specify anything for the final two arguments, the SQL-style WHERE clause and WHERE clause arguments.

The ContentValues object contains name value pairs, with the names being MediaStore.Video specific column names. The possible names are listed as constants in MediaStore.Video.Media, with most of them being inherited from android.provider.BaseColumns, MediaStore.MediaColumns, and MediaStore.Video.VideoColumns.

ContentValues values = new ContentValues(1);

values.put(MediaStore.MediaColumns.TITLE, titleEditText.getText().toString());

int numRecordsUpdated = getContentResolver().update(videoFileUri, values, null, null);

Here is an update to the foregoing VideoCaptureIntent example that presents the user with the opportunity to associate a title with the newly captured video.

package com.apress.proandroidmedia.ch11.videocaptureintent;

import android.app.Activity;

import android.content.ContentValues;

import android.content.Intent;

import android.net.Uri;

import android.os.Bundle;

import android.provider.MediaStore;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.EditText;

import android.widget.Toast;

public class VideoCaptureIntent extends Activity implements OnClickListener {

public static int VIDEO_CAPTURED = 1;

Button captureVideoButton; Button playVideoButton; Button saveVideoButton;

In this version, we'll have an EditText object, which will be used by the user to enter in the title for the video.

EditText titleEditText;

Uri videoFileUri; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main);

captureVideoButton = (Button) this.findViewById(R.id.CaptureVideoButton); playVideoButton = (Button) this.findViewById(R.id.PlayVideoButton);

We'll also have a saveVideoButton, which, when pressed, will trigger the update of the record in the MediaStore.

saveVideoButton = (Button) this.findViewById(R.id.SaveVideoButton);

titleEditText = (EditText) this.findViewById(R.id.TitleEditText);

captureVideoButton.setOnClickListener(this);

playVideoButton.setOnClickListener(this);

saveVideoButton.setOnClickListener(this);

playVideoButton.setEnabled(false); saveVideoButton.setEnabled(false); titleEditText.setEnabled(false);

The onClick method, triggered when any of the Buttons are pressed, performs most of the work. When the captureVideoButton is pressed, we trigger the built-in Camera application via an intent. When the playVideoButton is pressed, we trigger the built-in Media Player application via an intent (instead of using a VideoView as we did previously). Finally when we click the saveVideoButton, we update the MediaStore record for the video file.

public void onClick(View v) {

if (v == captureVideoButton) {

Intent captureVideoIntent = new Intent(android.provider.^ MediaStore.ACTION_VIDEO_CAPTURE);

startActivityForResult(captureVideoIntent, VIDEO_CAPTURED); } else if (v == playVideoButton) {

Intent playVideoIntent = new Intent(Intent.ACTION_VIEW,^

videoFileUri);

startActivity(playVideoIntent); } else if (v == saveVideoButton) {

First, we create a ContentValues object and populate it with the text the user has specified in the EditText object.

ContentValues values = new ContentValues(1); values.put(MediaStore.MediaColumns.TITLE,^

titleEditText.getText().toString());

Then we call the update method on the ContentResolver object, passing in the Uri to the captured video and the ContentValues object.

if (getContentResolver().update(videoFileUri, values, null,^ null) == 1) {

If the result of the update method is 1, then we were successful; one row was updated, and we'll tell the user.

Toast t = Toast.makeText(this, "Updated " titleEditText.getTextQ.toStringQ, Toast.LENGTH_SHORT); t.show();

If the result was anything other than 1, we'll tell the user that an error occurred.

Toast t = Toast.makeText(this, "Error",^ Toast.LENGTH_SHORT);

protected void onActivityResult (int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK && requestCode == VIDEO_CAPTURED) { videoFileUri = data.getData(); playVideoButton.setEnabled(true); saveVideoButton.setEnabled(true);

titleEditText.setEnabled(true); }

Here is the layout XML contained in res/layout/main.xml referenced by the foregoing activity.

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent"

android:layout_height="fill_parent" >

<Button android:text="Capture Video" android:id="@+id/CaptureVideoButton"^ android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>

<Button android:text="Play Video" android:id="@+id/PlayVideoButton"^ android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>

<TextView android:text="Title:" android:id="@+id/TitleTextView"^ android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>

<EditText android:text="" android:id="@+id/TitleEditText"^ android:layout_width="wrap_content" android:layout_height="wrap_content"></EditText>

<Button android:text="Save Metadata" android:id="@+id/SaveVideoButton"^ android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> </LinearLayout>

The preceding example shows how straightforward many aspects of using video within Android can be, especially so when using an intent to do the video capture and relying upon the MediaStore to handle metadata.

It should be noted that when updating the metadata in the MediaStore, the data is not updated within the video file itself; rather, it is stored only in the MediaStore record that pertains to the video. The Android SDK does not offer built-in classes to alter the media file's metadata directly.

+1 0

Average user rating: 5 stars out of 1 votes

Responses

Post a comment