Commit 0037157e authored by tommycli@chromium.org's avatar tommycli@chromium.org

Media Metadata API: Extract raw tags for audio/video.

This is the really simple implementation that can be refined if consumer wants it.

BUG=318450

Review URL: https://codereview.chromium.org/220303002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@261442 0039d316-1c4b-4281-b951-d872f2087c98
parent b9dc739e
...@@ -120,6 +120,10 @@ namespace mediaGalleries { ...@@ -120,6 +120,10 @@ namespace mediaGalleries {
DOMString? language; DOMString? language;
DOMString? title; DOMString? title;
long? track; long? track;
// A dictionary of all the metadata in the media file. This metadata is in
// string form, and neither the key nor value is normalized.
object rawTags;
}; };
callback MediaMetadataCallback = void (MediaMetadata metadata); callback MediaMetadataCallback = void (MediaMetadata metadata);
......
...@@ -51,6 +51,15 @@ function MP3TagsTest() { ...@@ -51,6 +51,15 @@ function MP3TagsTest() {
chrome.test.assertEq("OK Computer", metadata.album); chrome.test.assertEq("OK Computer", metadata.album);
chrome.test.assertEq(1, metadata.track); chrome.test.assertEq(1, metadata.track);
chrome.test.assertEq("Alternative", metadata.genre); chrome.test.assertEq("Alternative", metadata.genre);
chrome.test.assertEq("OK Computer", metadata.rawTags["album"]);
chrome.test.assertEq("Radiohead", metadata.rawTags["artist"]);
chrome.test.assertEq("1997", metadata.rawTags["date"]);
chrome.test.assertEq("Lavf54.4.100", metadata.rawTags["encoder"]);
chrome.test.assertEq("Alternative", metadata.rawTags["genre"]);
chrome.test.assertEq("Airbag", metadata.rawTags["title"]);
chrome.test.assertEq("1", metadata.rawTags["track"]);
chrome.test.succeed(); chrome.test.succeed();
} }
...@@ -61,6 +70,16 @@ function RotatedVideoTest() { ...@@ -61,6 +70,16 @@ function RotatedVideoTest() {
function verifyMetadata(metadata) { function verifyMetadata(metadata) {
chrome.test.assertEq("video/mp4", metadata.mimeType); chrome.test.assertEq("video/mp4", metadata.mimeType);
chrome.test.assertEq(90, metadata.rotation); chrome.test.assertEq(90, metadata.rotation);
chrome.test.assertEq("isom3gp4", metadata.rawTags["compatible_brands"]);
chrome.test.assertEq("2014-02-11 00:39:25",
metadata.rawTags["creation_time"]);
chrome.test.assertEq("VideoHandle", metadata.rawTags["handler_name"]);
chrome.test.assertEq("eng", metadata.rawTags["language"]);
chrome.test.assertEq("isom", metadata.rawTags["major_brand"]);
chrome.test.assertEq("0", metadata.rawTags["minor_version"]);
chrome.test.assertEq("90", metadata.rawTags["rotate"]);
chrome.test.succeed(); chrome.test.succeed();
} }
......
...@@ -61,6 +61,12 @@ scoped_ptr<MediaMetadataParser::MediaMetadata> ParseAudioVideoMetadata( ...@@ -61,6 +61,12 @@ scoped_ptr<MediaMetadataParser::MediaMetadata> ParseAudioVideoMetadata(
SetStringScopedPtr(extractor.title(), &metadata->title); SetStringScopedPtr(extractor.title(), &metadata->title);
SetIntScopedPtr(extractor.track(), &metadata->track); SetIntScopedPtr(extractor.track(), &metadata->track);
for (std::map<std::string, std::string>::const_iterator it =
extractor.raw_tags().begin();
it != extractor.raw_tags().end(); ++it) {
metadata->raw_tags.additional_properties.SetString(it->first, it->second);
}
return metadata.Pass(); return metadata.Pass();
} }
......
...@@ -195,12 +195,21 @@ int AudioVideoMetadataExtractor::track() const { ...@@ -195,12 +195,21 @@ int AudioVideoMetadataExtractor::track() const {
return track_; return track_;
} }
const std::map<std::string, std::string>&
AudioVideoMetadataExtractor::raw_tags() const {
DCHECK(extracted_);
return raw_tags_;
}
void AudioVideoMetadataExtractor::ExtractDictionary(AVDictionary* metadata) { void AudioVideoMetadataExtractor::ExtractDictionary(AVDictionary* metadata) {
if (!metadata) if (!metadata)
return; return;
AVDictionaryEntry* tag = NULL; AVDictionaryEntry* tag = NULL;
while ((tag = av_dict_get(metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { while ((tag = av_dict_get(metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
if (raw_tags_.find(tag->key) == raw_tags_.end())
raw_tags_[tag->key] = tag->value;
if (ExtractInt(tag, "rotate", &rotation_)) continue; if (ExtractInt(tag, "rotate", &rotation_)) continue;
if (ExtractString(tag, "album", &album_)) continue; if (ExtractString(tag, "album", &album_)) continue;
if (ExtractString(tag, "artist", &artist_)) continue; if (ExtractString(tag, "artist", &artist_)) continue;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef MEDIA_BASE_AUDIO_VIDEO_METADATA_EXTRACTOR_H_ #ifndef MEDIA_BASE_AUDIO_VIDEO_METADATA_EXTRACTOR_H_
#define MEDIA_BASE_AUDIO_VIDEO_METADATA_EXTRACTOR_H_ #define MEDIA_BASE_AUDIO_VIDEO_METADATA_EXTRACTOR_H_
#include <map>
#include <string> #include <string>
#include "base/basictypes.h" #include "base/basictypes.h"
...@@ -51,6 +52,8 @@ class MEDIA_EXPORT AudioVideoMetadataExtractor { ...@@ -51,6 +52,8 @@ class MEDIA_EXPORT AudioVideoMetadataExtractor {
const std::string& title() const; const std::string& title() const;
int track() const; int track() const;
const std::map<std::string, std::string>& raw_tags() const;
private: private:
void ExtractDictionary(AVDictionary* metadata); void ExtractDictionary(AVDictionary* metadata);
...@@ -74,6 +77,8 @@ class MEDIA_EXPORT AudioVideoMetadataExtractor { ...@@ -74,6 +77,8 @@ class MEDIA_EXPORT AudioVideoMetadataExtractor {
std::string title_; std::string title_;
int track_; int track_;
std::map<std::string, std::string> raw_tags_;
DISALLOW_COPY_AND_ASSIGN(AudioVideoMetadataExtractor); DISALLOW_COPY_AND_ASSIGN(AudioVideoMetadataExtractor);
}; };
......
...@@ -45,6 +45,9 @@ TEST(AudioVideoMetadataExtractorTest, AudioOGG) { ...@@ -45,6 +45,9 @@ TEST(AudioVideoMetadataExtractorTest, AudioOGG) {
scoped_ptr<AudioVideoMetadataExtractor> extractor = scoped_ptr<AudioVideoMetadataExtractor> extractor =
GetExtractor("9ch.ogg", true, 0, -1, -1); GetExtractor("9ch.ogg", true, 0, -1, -1);
EXPECT_EQ("Processed by SoX", extractor->comment()); EXPECT_EQ("Processed by SoX", extractor->comment());
EXPECT_EQ(1u, extractor->raw_tags().size());
EXPECT_EQ("Processed by SoX", extractor->raw_tags().find("COMMENT")->second);
} }
TEST(AudioVideoMetadataExtractorTest, AudioWAV) { TEST(AudioVideoMetadataExtractorTest, AudioWAV) {
...@@ -52,12 +55,19 @@ TEST(AudioVideoMetadataExtractorTest, AudioWAV) { ...@@ -52,12 +55,19 @@ TEST(AudioVideoMetadataExtractorTest, AudioWAV) {
GetExtractor("sfx_u8.wav", true, 0, -1, -1); GetExtractor("sfx_u8.wav", true, 0, -1, -1);
EXPECT_EQ("Lavf54.37.100", extractor->encoder()); EXPECT_EQ("Lavf54.37.100", extractor->encoder());
EXPECT_EQ("Amadeus Pro", extractor->encoded_by()); EXPECT_EQ("Amadeus Pro", extractor->encoded_by());
EXPECT_EQ(2u, extractor->raw_tags().size());
EXPECT_EQ("Lavf54.37.100", extractor->raw_tags().find("encoder")->second);
EXPECT_EQ("Amadeus Pro", extractor->raw_tags().find("encoded_by")->second);
} }
TEST(AudioVideoMetadataExtractorTest, VideoWebM) { TEST(AudioVideoMetadataExtractorTest, VideoWebM) {
scoped_ptr<AudioVideoMetadataExtractor> extractor = scoped_ptr<AudioVideoMetadataExtractor> extractor =
GetExtractor("bear-320x240-multitrack.webm", true, 2, 320, 240); GetExtractor("bear-320x240-multitrack.webm", true, 2, 320, 240);
EXPECT_EQ("Lavf53.9.0", extractor->encoder()); EXPECT_EQ("Lavf53.9.0", extractor->encoder());
EXPECT_EQ(1u, extractor->raw_tags().size());
EXPECT_EQ("Lavf53.9.0", extractor->raw_tags().find("ENCODER")->second);
} }
#if defined(USE_PROPRIETARY_CODECS) #if defined(USE_PROPRIETARY_CODECS)
...@@ -66,6 +76,17 @@ TEST(AudioVideoMetadataExtractorTest, AndroidRotatedMP4Video) { ...@@ -66,6 +76,17 @@ TEST(AudioVideoMetadataExtractorTest, AndroidRotatedMP4Video) {
GetExtractor("90rotation.mp4", true, 0, 1920, 1080); GetExtractor("90rotation.mp4", true, 0, 1920, 1080);
EXPECT_EQ(90, extractor->rotation()); EXPECT_EQ(90, extractor->rotation());
EXPECT_EQ(7u, extractor->raw_tags().size());
EXPECT_EQ("isom3gp4",
extractor->raw_tags().find("compatible_brands")->second);
EXPECT_EQ("2014-02-11 00:39:25",
extractor->raw_tags().find("creation_time")->second);
EXPECT_EQ("VideoHandle", extractor->raw_tags().find("handler_name")->second);
EXPECT_EQ("eng", extractor->raw_tags().find("language")->second);
EXPECT_EQ("isom", extractor->raw_tags().find("major_brand")->second);
EXPECT_EQ("0", extractor->raw_tags().find("minor_version")->second);
EXPECT_EQ("90", extractor->raw_tags().find("rotate")->second);
} }
TEST(AudioVideoMetadataExtractorTest, AudioMP3) { TEST(AudioVideoMetadataExtractorTest, AudioMP3) {
...@@ -79,6 +100,15 @@ TEST(AudioVideoMetadataExtractorTest, AudioMP3) { ...@@ -79,6 +100,15 @@ TEST(AudioVideoMetadataExtractorTest, AudioMP3) {
EXPECT_EQ("Alternative", extractor->genre()); EXPECT_EQ("Alternative", extractor->genre());
EXPECT_EQ("1997", extractor->date()); EXPECT_EQ("1997", extractor->date());
EXPECT_EQ("Lavf54.4.100", extractor->encoder()); EXPECT_EQ("Lavf54.4.100", extractor->encoder());
EXPECT_EQ(7u, extractor->raw_tags().size());
EXPECT_EQ("OK Computer", extractor->raw_tags().find("album")->second);
EXPECT_EQ("Radiohead", extractor->raw_tags().find("artist")->second);
EXPECT_EQ("1997", extractor->raw_tags().find("date")->second);
EXPECT_EQ("Lavf54.4.100", extractor->raw_tags().find("encoder")->second);
EXPECT_EQ("Alternative", extractor->raw_tags().find("genre")->second);
EXPECT_EQ("Airbag", extractor->raw_tags().find("title")->second);
EXPECT_EQ("1", extractor->raw_tags().find("track")->second);
} }
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment