• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "napi_meta_data.h"
17 #include "avsession_log.h"
18 #include "avsession_pixel_map_adapter.h"
19 #include "napi_utils.h"
20 #include "pixel_map_napi.h"
21 
22 namespace OHOS::AVSession {
23 std::map<std::string, NapiMetaData::GetterType> NapiMetaData::getterMap_ = {
24     { "assetId", GetAssetId },
25     { "title", GetTitle },
26     { "artist", GetArtist },
27     { "author", GetAuthor },
28     { "album",  GetAlbum },
29     { "writer", GetWriter },
30     { "composer", GetComposer },
31     { "duration", GetDuration },
32     { "mediaImage", GetMediaImage },
33     { "publishDate", GetPublishDate },
34     { "subtitle", GetSubtitle },
35     { "description", GetDescription },
36     { "lyric", GetLyric },
37     { "previousAssetId", GetPreviousAssetId },
38     { "nextAssetId", GetNextAssetId }
39 };
40 
41 std::map<int32_t, NapiMetaData::SetterType> NapiMetaData::setterMap_ = {
42     { AVMetaData::META_KEY_ASSET_ID, SetAssetId },
43     { AVMetaData::META_KEY_TITLE, SetTitle },
44     { AVMetaData::META_KEY_ARTIST, SetArtist },
45     { AVMetaData::META_KEY_AUTHOR, SetAuthor },
46     { AVMetaData::META_KEY_ALBUM, SetAlbum },
47     { AVMetaData::META_KEY_WRITER, SetWriter },
48     { AVMetaData::META_KEY_COMPOSER, SetComposer },
49     { AVMetaData::META_KEY_DURATION, SetDuration },
50     { AVMetaData::META_KEY_MEDIA_IMAGE, SetMediaImage },
51     { AVMetaData::META_KEY_MEDIA_IMAGE_URI, SetMediaImageUri },
52     { AVMetaData::META_KEY_PUBLISH_DATE, SetPublishDate },
53     { AVMetaData::META_KEY_SUBTITLE, SetSubtitle },
54     { AVMetaData::META_KEY_DESCRIPTION, SetDescription },
55     { AVMetaData::META_KEY_LYRIC, SetLyric },
56     { AVMetaData::META_KEY_PREVIOUS_ASSET_ID, SetPreviousAssetId },
57     { AVMetaData::META_KEY_NEXT_ASSET_ID, SetNextAssetId },
58 };
59 
60 std::pair<std::string, int32_t> NapiMetaData::filterMap_[] = {
61     { "assetId", AVMetaData::META_KEY_ASSET_ID },
62     { "title", AVMetaData::META_KEY_TITLE },
63     { "artist", AVMetaData::META_KEY_ARTIST },
64     { "author", AVMetaData::META_KEY_AUTHOR },
65     { "album",  AVMetaData::META_KEY_ALBUM },
66     { "writer", AVMetaData::META_KEY_WRITER },
67     { "composer", AVMetaData::META_KEY_COMPOSER },
68     { "duration", AVMetaData::META_KEY_DURATION },
69     { "mediaImage", AVMetaData::META_KEY_MEDIA_IMAGE },
70     { "mediaImage", AVMetaData::META_KEY_MEDIA_IMAGE_URI },
71     { "publishDate", AVMetaData::META_KEY_PUBLISH_DATE },
72     { "subtitle", AVMetaData::META_KEY_SUBTITLE },
73     { "description", AVMetaData::META_KEY_DESCRIPTION },
74     { "lyric", AVMetaData::META_KEY_LYRIC },
75     { "previousAssetId", AVMetaData::META_KEY_PREVIOUS_ASSET_ID },
76     { "nextAssetId", AVMetaData::META_KEY_NEXT_ASSET_ID }
77 };
78 
ConvertFilter(napi_env env,napi_value filter,AVMetaData::MetaMaskType & mask)79 napi_status NapiMetaData::ConvertFilter(napi_env env, napi_value filter, AVMetaData::MetaMaskType& mask)
80 {
81     napi_valuetype type = napi_undefined;
82     auto status = napi_typeof(env, filter, &type);
83     CHECK_RETURN(status == napi_ok, "napi_typeof failed", status);
84 
85     if (type == napi_string) {
86         std::string stringFilter;
87         status = NapiUtils::GetValue(env, filter, stringFilter);
88         CHECK_RETURN(status == napi_ok, "get string filter failed", status);
89         if (stringFilter != "all") {
90             SLOGE("string filter only support all") ;
91             return napi_invalid_arg;
92         }
93         mask.set();
94         return napi_ok;
95     }
96 
97     uint32_t count = 0;
98     status = napi_get_array_length(env, filter, &count);
99     CHECK_RETURN(status == napi_ok, "get array length failed", status);
100     for (uint32_t i = 0; i < count; i++) {
101         napi_value value {};
102         status = napi_get_element(env, filter, i, &value);
103         CHECK_RETURN(status == napi_ok, "get element failed", status);
104         std::string metaKey;
105         status = NapiUtils::GetValue(env, value, metaKey);
106         CHECK_RETURN(status == napi_ok, "get string value failed", status);
107         for (const auto& pair : filterMap_) {
108             if (pair.first == metaKey) {
109                 mask.set(pair.second);
110             }
111         }
112     }
113 
114     return napi_ok;
115 }
116 
GetValue(napi_env env,napi_value in,AVMetaData & out)117 napi_status NapiMetaData::GetValue(napi_env env, napi_value in, AVMetaData& out)
118 {
119     std::vector<std::string> propertyNames;
120     auto status = NapiUtils::GetPropertyNames(env, in, propertyNames);
121     CHECK_RETURN(status == napi_ok, "get property name failed", status);
122 
123     for (const auto& name : propertyNames) {
124         auto it = getterMap_.find(name);
125         if (it == getterMap_.end()) {
126             SLOGE("property %{public}s is not of metadata", name.c_str());
127             return napi_invalid_arg;
128         }
129         auto getter = it->second;
130         if (getter(env, in, out) != napi_ok) {
131             SLOGE("get property %{public}s failed", name.c_str());
132             return napi_generic_failure;
133         }
134     }
135 
136     return napi_ok;
137 }
138 
SetValue(napi_env env,const AVMetaData & in,napi_value & out)139 napi_status NapiMetaData::SetValue(napi_env env, const AVMetaData& in, napi_value& out)
140 {
141     napi_status status = napi_create_object(env, &out);
142     CHECK_RETURN((status == napi_ok) && (out != nullptr), "create object failed", status);
143 
144     auto mask = in.GetMetaMask();
145     if (mask.none()) {
146         SLOGI("undefined meta");
147         return SetUndefinedMeta(env, out);
148     }
149 
150     for (int i = 0; i < AVMetaData::META_KEY_MAX; ++i) {
151         if (!mask.test(i)) {
152             continue;
153         }
154         auto setter = setterMap_[i];
155         if (setter(env, in, out) != napi_ok) {
156             SLOGE("set property %{public}d failed", i);
157             return napi_generic_failure;
158         }
159     }
160 
161     return napi_ok;
162 }
163 
SetUndefinedMeta(napi_env env,napi_value & meta)164 napi_status NapiMetaData::SetUndefinedMeta(napi_env env, napi_value& meta)
165 {
166     auto status = napi_set_named_property(env, meta, "assetId", NapiUtils::GetUndefinedValue(env));
167     CHECK_RETURN(status == napi_ok, "set assetId to undefined failed", status);
168     return napi_ok;
169 }
170 
GetAssetId(napi_env env,napi_value in,AVMetaData & out)171 napi_status NapiMetaData::GetAssetId(napi_env env, napi_value in, AVMetaData& out)
172 {
173     std::string property;
174     auto status = NapiUtils::GetNamedProperty(env, in, "assetId", property);
175     CHECK_RETURN(status == napi_ok, "get property failed", status);
176     out.SetAssetId(property);
177     return status;
178 }
179 
SetAssetId(napi_env env,const AVMetaData & in,napi_value & out)180 napi_status NapiMetaData::SetAssetId(napi_env env, const AVMetaData& in, napi_value& out)
181 {
182     napi_value property {};
183     auto status = NapiUtils::SetValue(env, in.GetAssetId(), property);
184     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create property failed", status);
185     status = napi_set_named_property(env, out, "assetId", property);
186     CHECK_RETURN(status == napi_ok, "set property failed", status);
187     return status;
188 }
189 
GetTitle(napi_env env,napi_value in,AVMetaData & out)190 napi_status NapiMetaData::GetTitle(napi_env env, napi_value in, AVMetaData& out)
191 {
192     std::string property;
193     auto status = NapiUtils::GetNamedProperty(env, in, "title", property);
194     CHECK_RETURN(status == napi_ok, "get property failed", status);
195     out.SetTitle(property);
196     return status;
197 }
198 
SetTitle(napi_env env,const AVMetaData & in,napi_value & out)199 napi_status NapiMetaData::SetTitle(napi_env env, const AVMetaData& in, napi_value& out)
200 {
201     napi_value property {};
202     auto status = NapiUtils::SetValue(env, in.GetTitle(), property);
203     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create property failed", status);
204     status = napi_set_named_property(env, out, "title", property);
205     CHECK_RETURN(status == napi_ok, "set property failed", status);
206     return status;
207 }
208 
GetArtist(napi_env env,napi_value in,AVMetaData & out)209 napi_status NapiMetaData::GetArtist(napi_env env, napi_value in, AVMetaData& out)
210 {
211     std::string property;
212     auto status = NapiUtils::GetNamedProperty(env, in, "artist", property);
213     CHECK_RETURN(status == napi_ok, "get property failed", status);
214     out.SetArtist(property);
215     return status;
216 }
217 
SetArtist(napi_env env,const AVMetaData & in,napi_value & out)218 napi_status NapiMetaData::SetArtist(napi_env env, const AVMetaData& in, napi_value& out)
219 {
220     napi_value property {};
221     auto status = NapiUtils::SetValue(env, in.GetArtist(), property);
222     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create property failed", status);
223     status = napi_set_named_property(env, out, "artist", property);
224     CHECK_RETURN(status == napi_ok, "set property failed", status);
225     return status;
226 }
227 
GetAuthor(napi_env env,napi_value in,AVMetaData & out)228 napi_status NapiMetaData::GetAuthor(napi_env env, napi_value in, AVMetaData& out)
229 {
230     std::string property;
231     auto status = NapiUtils::GetNamedProperty(env, in, "author", property);
232     CHECK_RETURN(status == napi_ok, "get property failed", status);
233     out.SetAuthor(property);
234     return status;
235 }
236 
SetAuthor(napi_env env,const AVMetaData & in,napi_value & out)237 napi_status NapiMetaData::SetAuthor(napi_env env, const AVMetaData& in, napi_value& out)
238 {
239     napi_value property {};
240     auto status = NapiUtils::SetValue(env, in.GetAuthor(), property);
241     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create property failed", status);
242     status = napi_set_named_property(env, out, "author", property);
243     CHECK_RETURN(status == napi_ok, "set property failed", status);
244     return status;
245 }
246 
GetAlbum(napi_env env,napi_value in,AVMetaData & out)247 napi_status NapiMetaData::GetAlbum(napi_env env, napi_value in, AVMetaData& out)
248 {
249     std::string property;
250     auto status = NapiUtils::GetNamedProperty(env, in, "album", property);
251     CHECK_RETURN(status == napi_ok, "get property failed", status);
252     out.SetAlbum(property);
253     return status;
254 }
255 
SetAlbum(napi_env env,const AVMetaData & in,napi_value & out)256 napi_status NapiMetaData::SetAlbum(napi_env env, const AVMetaData& in, napi_value& out)
257 {
258     napi_value property {};
259     auto status = NapiUtils::SetValue(env, in.GetAlbum(), property);
260     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create property failed", status);
261     status = napi_set_named_property(env, out, "album", property);
262     CHECK_RETURN(status == napi_ok, "set property failed", status);
263     return status;
264 }
265 
GetWriter(napi_env env,napi_value in,AVMetaData & out)266 napi_status NapiMetaData::GetWriter(napi_env env, napi_value in, AVMetaData& out)
267 {
268     std::string property;
269     auto status = NapiUtils::GetNamedProperty(env, in, "writer", property);
270     CHECK_RETURN(status == napi_ok, "get property failed", status);
271     out.SetWriter(property);
272     return status;
273 }
274 
SetWriter(napi_env env,const AVMetaData & in,napi_value & out)275 napi_status NapiMetaData::SetWriter(napi_env env, const AVMetaData& in, napi_value& out)
276 {
277     napi_value property {};
278     auto status = NapiUtils::SetValue(env, in.GetWriter(), property);
279     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create property failed", status);
280     status = napi_set_named_property(env, out, "writer", property);
281     CHECK_RETURN(status == napi_ok, "set property failed", status);
282     return status;
283 }
284 
GetComposer(napi_env env,napi_value in,AVMetaData & out)285 napi_status NapiMetaData::GetComposer(napi_env env, napi_value in, AVMetaData& out)
286 {
287     std::string property;
288     auto status = NapiUtils::GetNamedProperty(env, in, "composer", property);
289     CHECK_RETURN(status == napi_ok, "get property failed", status);
290     out.SetComposer(property);
291     return status;
292 }
293 
SetComposer(napi_env env,const AVMetaData & in,napi_value & out)294 napi_status NapiMetaData::SetComposer(napi_env env, const AVMetaData& in, napi_value& out)
295 {
296     napi_value property {};
297     auto status = NapiUtils::SetValue(env, in.GetComposer(), property);
298     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create property failed", status);
299     status = napi_set_named_property(env, out, "composer", property);
300     CHECK_RETURN(status == napi_ok, "set property failed", status);
301     return status;
302 }
303 
GetDuration(napi_env env,napi_value in,AVMetaData & out)304 napi_status NapiMetaData::GetDuration(napi_env env, napi_value in, AVMetaData& out)
305 {
306     int64_t property;
307     auto status = NapiUtils::GetNamedProperty(env, in, "duration", property);
308     CHECK_RETURN(status == napi_ok, "get property failed", status);
309     out.SetDuration(property);
310     return status;
311 }
312 
SetDuration(napi_env env,const AVMetaData & in,napi_value & out)313 napi_status NapiMetaData::SetDuration(napi_env env, const AVMetaData& in, napi_value& out)
314 {
315     napi_value property {};
316     auto status = NapiUtils::SetValue(env, in.GetDuration(), property);
317     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create property failed", status);
318     status = napi_set_named_property(env, out, "duration", property);
319     CHECK_RETURN(status == napi_ok, "set property failed", status);
320     return status;
321 }
322 
GetMediaImage(napi_env env,napi_value in,AVMetaData & out)323 napi_status NapiMetaData::GetMediaImage(napi_env env, napi_value in, AVMetaData& out)
324 {
325     napi_value property {};
326     auto status = napi_get_named_property(env, in, "mediaImage", &property);
327     CHECK_RETURN((status == napi_ok) && (property != nullptr), "get property failed", status);
328     napi_valuetype type = napi_undefined;
329     status = napi_typeof(env, property, &type);
330     CHECK_RETURN(status == napi_ok, "get napi_value type failed", status);
331     if (type == napi_string) {
332         std::string uri;
333         status = NapiUtils::GetValue(env, property, uri);
334         CHECK_RETURN(status == napi_ok, "get property failed", status);
335         out.SetMediaImageUri(uri);
336     } else if (type == napi_object) {
337         auto pixelMap = Media::PixelMapNapi::GetPixelMap(env, property);
338         if (pixelMap == nullptr) {
339             SLOGE("unwrap failed");
340             return napi_invalid_arg;
341         }
342         out.SetMediaImage(AVSessionPixelMapAdapter::ConvertToInner(pixelMap));
343     } else {
344         SLOGE("mediaImage property value type invalid");
345         return napi_invalid_arg;
346     }
347 
348     return status;
349 }
350 
SetMediaImage(napi_env env,const AVMetaData & in,napi_value & out)351 napi_status NapiMetaData::SetMediaImage(napi_env env, const AVMetaData& in, napi_value& out)
352 {
353     auto pixelMap = in.GetMediaImage();
354     if (pixelMap == nullptr) {
355         SLOGI("media image is none");
356         return napi_ok;
357     }
358 
359     napi_value property = Media::PixelMapNapi::CreatePixelMap(env,
360         AVSessionPixelMapAdapter::ConvertFromInner(pixelMap));
361     auto status = napi_set_named_property(env, out, "mediaImage", property);
362     CHECK_RETURN(status == napi_ok, "set property failed", status);
363     return status;
364 }
365 
SetMediaImageUri(napi_env env,const AVMetaData & in,napi_value & out)366 napi_status NapiMetaData::SetMediaImageUri(napi_env env, const AVMetaData& in, napi_value& out)
367 {
368     auto uri = in.GetMediaImageUri();
369     if (uri.empty()) {
370         SLOGI("media image uri empty");
371         return napi_ok;
372     }
373 
374     napi_value property {};
375     auto status = NapiUtils::SetValue(env, uri, property);
376     CHECK_RETURN(status == napi_ok, "create property failed", status);
377     status = napi_set_named_property(env, out, "mediaImage", property);
378     CHECK_RETURN(status == napi_ok, "set property failed", status);
379     return status;
380 }
381 
GetPublishDate(napi_env env,napi_value in,AVMetaData & out)382 napi_status NapiMetaData::GetPublishDate(napi_env env, napi_value in, AVMetaData& out)
383 {
384     napi_value property;
385     auto status = napi_get_named_property(env, in, "publishDate", &property);
386     CHECK_RETURN(status == napi_ok, "get property failed", status);
387     double date {};
388     status = NapiUtils::GetDateValue(env, property, date);
389     CHECK_RETURN(status == napi_ok, "get date value failed", status);
390     out.SetPublishDate(date);
391     return status;
392 }
393 
SetPublishDate(napi_env env,const AVMetaData & in,napi_value & out)394 napi_status NapiMetaData::SetPublishDate(napi_env env, const AVMetaData& in, napi_value& out)
395 {
396     napi_value property {};
397     auto status = NapiUtils::SetDateValue(env, in.GetPublishDate(), property);
398     CHECK_RETURN(status == napi_ok, "create date object failed", status);
399     status = napi_set_named_property(env, out, "publishDate", property);
400     CHECK_RETURN(status == napi_ok, "set property failed", status);
401     return status;
402 }
403 
GetSubtitle(napi_env env,napi_value in,AVMetaData & out)404 napi_status NapiMetaData::GetSubtitle(napi_env env, napi_value in, AVMetaData& out)
405 {
406     std::string property;
407     auto status = NapiUtils::GetNamedProperty(env, in, "subtitle", property);
408     CHECK_RETURN(status == napi_ok, "get property failed", status);
409     out.SetSubTitle(property);
410     return status;
411 }
412 
SetSubtitle(napi_env env,const AVMetaData & in,napi_value & out)413 napi_status NapiMetaData::SetSubtitle(napi_env env, const AVMetaData& in, napi_value& out)
414 {
415     napi_value property {};
416     auto status = NapiUtils::SetValue(env, in.GetSubTitle(), property);
417     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create property failed", status);
418     status = napi_set_named_property(env, out, "subtitle", property);
419     CHECK_RETURN(status == napi_ok, "set property failed", status);
420     return status;
421 }
422 
GetDescription(napi_env env,napi_value in,AVMetaData & out)423 napi_status NapiMetaData::GetDescription(napi_env env, napi_value in, AVMetaData& out)
424 {
425     std::string property;
426     auto status = NapiUtils::GetNamedProperty(env, in, "description", property);
427     CHECK_RETURN(status == napi_ok, "get property failed", status);
428     out.SetDescription(property);
429     return status;
430 }
431 
SetDescription(napi_env env,const AVMetaData & in,napi_value & out)432 napi_status NapiMetaData::SetDescription(napi_env env, const AVMetaData& in, napi_value& out)
433 {
434     napi_value property {};
435     auto status = NapiUtils::SetValue(env, in.GetDescription(), property);
436     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create property failed", status);
437     status = napi_set_named_property(env, out, "description", property);
438     CHECK_RETURN(status == napi_ok, "set property failed", status);
439     return status;
440 }
441 
GetLyric(napi_env env,napi_value in,AVMetaData & out)442 napi_status NapiMetaData::GetLyric(napi_env env, napi_value in, AVMetaData& out)
443 {
444     std::string property;
445     auto status = NapiUtils::GetNamedProperty(env, in, "lyric", property);
446     CHECK_RETURN(status == napi_ok, "get property failed", status);
447     out.SetLyric(property);
448     return status;
449 }
450 
SetLyric(napi_env env,const AVMetaData & in,napi_value & out)451 napi_status NapiMetaData::SetLyric(napi_env env, const AVMetaData& in, napi_value& out)
452 {
453     napi_value property {};
454     auto status = NapiUtils::SetValue(env, in.GetLyric(), property);
455     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create property failed", status);
456     status = napi_set_named_property(env, out, "lyric", property);
457     CHECK_RETURN(status == napi_ok, "set property failed", status);
458     return status;
459 }
460 
GetPreviousAssetId(napi_env env,napi_value in,AVMetaData & out)461 napi_status NapiMetaData::GetPreviousAssetId(napi_env env, napi_value in, AVMetaData& out)
462 {
463     std::string property;
464     auto status = NapiUtils::GetNamedProperty(env, in, "previousAssetId", property);
465     CHECK_RETURN(status == napi_ok, "get property failed", status);
466     out.SetPreviousAssetId(property);
467     return status;
468 }
469 
SetPreviousAssetId(napi_env env,const AVMetaData & in,napi_value & out)470 napi_status NapiMetaData::SetPreviousAssetId(napi_env env, const AVMetaData& in, napi_value& out)
471 {
472     napi_value property {};
473     auto status = NapiUtils::SetValue(env, in.GetPreviousAssetId(), property);
474     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create property failed", status);
475     status = napi_set_named_property(env, out, "previousAssetId", property);
476     CHECK_RETURN(status == napi_ok, "set property failed", status);
477     return status;
478 }
479 
GetNextAssetId(napi_env env,napi_value in,AVMetaData & out)480 napi_status NapiMetaData::GetNextAssetId(napi_env env, napi_value in, AVMetaData& out)
481 {
482     std::string property;
483     auto status = NapiUtils::GetNamedProperty(env, in, "nextAssetId", property);
484     CHECK_RETURN(status == napi_ok, "get property failed", status);
485     out.SetNextAssetId(property);
486     return status;
487 }
488 
SetNextAssetId(napi_env env,const AVMetaData & in,napi_value & out)489 napi_status NapiMetaData::SetNextAssetId(napi_env env, const AVMetaData& in, napi_value& out)
490 {
491     napi_value property {};
492     auto status = NapiUtils::SetValue(env, in.GetNextAssetId(), property);
493     CHECK_RETURN((status == napi_ok) && (property != nullptr), "create property failed", status);
494     status = napi_set_named_property(env, out, "nextAssetId", property);
495     CHECK_RETURN(status == napi_ok, "set property failed", status);
496     return status;
497 }
498 }