From: Piotr Kosko/Native/Web API (PLT) /SRPOL/Engineer/Samsung Electronics
Date: Thu, 26 Nov 2020 08:55:11 +0000 (+0100)
Subject: [Metadata] Add getSyncLyrics to MetadataHandle
X-Git-Tag: submit/tizen/20201209.085808~2
X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fc985e637d1b4f6307e094ded36d41ed6631f0b8;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git
[Metadata] Add getSyncLyrics to MetadataHandle
[ACR] https://code.sec.samsung.net/jira/browse/TWDAPI-271
[Verification] Code compiles withotu errors.
Works well for mp3 file with SYLT data.
// Prectondition - file preparation (with python code)
// important - SYLT need to be UTF-8 or ISO-8859 encoded to be supported on Tizen device
from mutagen.id3 import ID3, SYLT, Encoding
tag = ID3("sample.mp3")
sync_lrc = [("TEST lyrics 1", 100),
("another TEST lyrics - 2", 2000),
("yet another TEST lyrics", 4000)] # [(lrc, millisecond), ]
tag.setall("SYLT", [SYLT(encoding=Encoding.UTF8, lang='eng', format=2, type=1, text=sync_lrc)])
tag.save()
tag.getall("SYLT")
// then push file to device
// then run below code in chrome console
var path = "videos/sample.mp3";
var fileHandle = tizen.metadata.createFileHandle(path);
var lyrics_num = fileHandle.get("SYNCLYRICS_NUM");
for (var i = 0; i < lyrics_num; ++i) {
var lyrics = fileHandle.getSyncLyrics(i);
console.log("Lyrics " + i + " (" + lyrics.timestamp + "ms): " + lyrics.lyrics);
}
// expected return be like
console-via-logger.js:173 Lyrics 0 (100ms): TEST lyrics 1
console-via-logger.js:173 Lyrics 1 (2000ms): another TEST lyrics - 2
console-via-logger.js:173 Lyrics 2 (4000ms): yet another TEST lyrics
Change-Id: I01a502f40655532a37fc4055480e35826bb7a697
---
diff --git a/src/metadata/metadata_api.js b/src/metadata/metadata_api.js
index 236b758e..6126c4a2 100755
--- a/src/metadata/metadata_api.js
+++ b/src/metadata/metadata_api.js
@@ -195,5 +195,30 @@ MetadataFileHandle.prototype.getFrameAtTime = function() {
return new Blob([encodedData]);
};
+MetadataFileHandle.prototype.getSyncLyrics = function() {
+ var args = validator_.validateArgs(arguments, [
+ { name: 'index', type: types_.UNSIGNED_LONG }
+ ]);
+
+ var data = {
+ uri: this.uri,
+ id: this._id,
+ index: args.index
+ };
+
+ var result = native_.callSync('MetadataFileHandleGetSyncLyrics', data);
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+ return new MetadataSyncLyrics(native_.getResultObject(result));
+};
+
+function MetadataSyncLyrics(data) {
+ Object.defineProperties(this, {
+ timestamp: { value: data.timestamp, writable: false, enumerable: true },
+ lyrics: { value: data.lyrics, writable: false, enumerable: true }
+ });
+}
+
// Exports
exports = new MetadataManager();
diff --git a/src/metadata/metadata_file_handle.cc b/src/metadata/metadata_file_handle.cc
index b3d97613..2dfe0020 100644
--- a/src/metadata/metadata_file_handle.cc
+++ b/src/metadata/metadata_file_handle.cc
@@ -107,13 +107,13 @@ std::string convertUriToPath(const std::string& str) {
}
}
-MetadataFileHandle::MetadataFileHandle(int id) : handle_(nullptr), id_(id), width_(0), height_(0) {
+MetadataFileHandle::MetadataFileHandle(int id) : handle_(nullptr), id_(id), width_(0), height_(0), lyrics_num_(0) {
ScopeLogger();
}
// 'this' owns a handle_, and uri_ and invalidates 'o'
MetadataFileHandle::MetadataFileHandle(MetadataFileHandle&& o)
- : handle_(nullptr), id_(o.id_), uri_(std::move(o.uri_)), width_(0), height_(0) {
+ : handle_(nullptr), id_(o.id_), uri_(std::move(o.uri_)), width_(0), height_(0), lyrics_num_(0) {
ScopeLogger();
handle_ = o.handle_;
o.handle_ = nullptr;
@@ -128,6 +128,7 @@ MetadataFileHandle& MetadataFileHandle::operator=(MetadataFileHandle&& o) {
uri_ = std::move(o.uri_);
width_ = o.width_;
height_ = o.height_;
+ lyrics_num_ = o.lyrics_num_;
return *this;
}
@@ -363,5 +364,51 @@ PlatformResult MetadataFileHandle::GetFrame(const unsigned long timestamp, const
return PlatformResult(ErrorCode::NO_ERROR);
}
+PlatformResult MetadataFileHandle::InitSyncLyricsNum() {
+ ScopeLogger();
+ if (0 == lyrics_num_) {
+ char* value = nullptr;
+ int native_res = metadata_extractor_get_metadata(handle_, METADATA_SYNCLYRICS_NUM, &value);
+ if (METADATA_EXTRACTOR_ERROR_NONE != native_res) {
+ LoggerE("Error during getting lyrics number: %d", native_res);
+ return convertErrorCode(native_res);
+ }
+ lyrics_num_ = (unsigned long)atoi(value);
+ free(value);
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult MetadataFileHandle::GetSyncLyrics(const unsigned long index,
+ unsigned long* timestamp,
+ std::string* lyrics_string) {
+ ScopeLogger();
+ char* lyrics = nullptr;
+ SCOPE_EXIT {
+ free(lyrics);
+ };
+
+ auto ret = InitSyncLyricsNum();
+ if (!ret) {
+ return ret;
+ }
+
+ // validation of input index (available values are <0; lyrics_num -1>)
+ if (index >= lyrics_num_) {
+ std::string message = "Invalid lyrics index: " + std::to_string(index);
+ return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, message.c_str());
+ }
+
+ int native_res = metadata_extractor_get_synclyrics(handle_, index, timestamp, &lyrics);
+ if (METADATA_EXTRACTOR_ERROR_NONE != native_res) {
+ LoggerE("Error during getting sync lyrics: %d", native_res);
+ return convertErrorCode(native_res);
+ }
+ if (lyrics) {
+ *lyrics_string = lyrics;
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
} // namespace metadata
} // namespace extension
diff --git a/src/metadata/metadata_file_handle.h b/src/metadata/metadata_file_handle.h
index 2bcd8d03..f0136b04 100644
--- a/src/metadata/metadata_file_handle.h
+++ b/src/metadata/metadata_file_handle.h
@@ -42,9 +42,12 @@ class MetadataFileHandle {
common::PlatformResult GetFrame(std::vector* frame_array);
common::PlatformResult GetFrame(const unsigned long timestamp, const bool is_accurate,
std::vector* frame_array);
+ common::PlatformResult GetSyncLyrics(const unsigned long index, unsigned long* timestamp,
+ std::string* lyrics_string);
private:
common::PlatformResult InitWidthHeight();
+ common::PlatformResult InitSyncLyricsNum();
common::PlatformResult EncodeJPEG(unsigned char* frame, size_t frame_size,
std::uint8_t** uint8_frame, size_t* buffer_size);
@@ -54,6 +57,7 @@ class MetadataFileHandle {
unsigned int width_;
unsigned int height_;
+ unsigned int lyrics_num_;
};
} // namespace metadata
diff --git a/src/metadata/metadata_instance.cc b/src/metadata/metadata_instance.cc
index 49e1cd62..eb8c02eb 100644
--- a/src/metadata/metadata_instance.cc
+++ b/src/metadata/metadata_instance.cc
@@ -37,6 +37,7 @@ MetadataInstance::MetadataInstance() : next_handle_id_(1) {
REGISTER_METHOD(MetadataFileHandleGetArtwork);
REGISTER_METHOD(MetadataFileHandleGetThumbnailFrame);
REGISTER_METHOD(MetadataFileHandleGetFrameAtTime);
+ REGISTER_METHOD(MetadataFileHandleGetSyncLyrics);
REGISTER_METHOD(MetadataFileHandleRelease);
#undef REGISTER_METHOD
}
@@ -242,6 +243,49 @@ void MetadataInstance::MetadataFileHandleGetFrameAtTime(const picojson::value& a
ReportSuccess(picojson::value(result_frame), out);
}
+picojson::value getSyncLyricsJSON(const unsigned long timestamp, const std::string& lyrics) {
+ ScopeLogger();
+ picojson::value result = picojson::value(picojson::object());
+ picojson::object& result_obj = result.get();
+ result_obj.insert(std::make_pair("timestamp", picojson::value((double)timestamp)));
+ result_obj.insert(std::make_pair("lyrics", picojson::value(lyrics)));
+
+ return result;
+}
+
+void MetadataInstance::MetadataFileHandleGetSyncLyrics(const picojson::value& args,
+ picojson::object& out) {
+ ScopeLogger();
+ const std::string& uri = args.get("uri").get();
+ const int id = static_cast(args.get("id").get());
+ const unsigned long index = static_cast(args.get("index").get());
+
+ auto res = InitializeHandleIfNeeded(uri, id);
+ if (!res) {
+ LogAndReportError(res, &out);
+ return;
+ }
+
+ unsigned long timestamp = 0;
+ std::string lyrics;
+ try {
+ MetadataFileHandle& m = handles_map_.at(id);
+
+ auto res = m.GetSyncLyrics(index, ×tamp, &lyrics);
+ if (!res) {
+ LogAndReportError(res, &out);
+ return;
+ }
+ } catch (...) {
+ // this should never happen
+ LogAndReportError(
+ PlatformResult(ErrorCode::ABORT_ERR, "Unknown error during accessing a file."), &out);
+ return;
+ }
+
+ ReportSuccess(getSyncLyricsJSON(timestamp, lyrics), out);
+}
+
void MetadataInstance::MetadataFileHandleRelease(const picojson::value& args,
picojson::object& out) {
ScopeLogger();
diff --git a/src/metadata/metadata_instance.h b/src/metadata/metadata_instance.h
index 26a3f499..61dd760b 100644
--- a/src/metadata/metadata_instance.h
+++ b/src/metadata/metadata_instance.h
@@ -35,6 +35,7 @@ class MetadataInstance : public common::ParsedInstance {
void MetadataFileHandleGetArtwork(const picojson::value& args, picojson::object& out);
void MetadataFileHandleGetThumbnailFrame(const picojson::value& args, picojson::object& out);
void MetadataFileHandleGetFrameAtTime(const picojson::value& args, picojson::object& out);
+ void MetadataFileHandleGetSyncLyrics(const picojson::value& args, picojson::object& out);
void MetadataFileHandleRelease(const picojson::value& args, picojson::object& out);
std::map handles_map_;