1 /*
2 * Copyright (c) 2024 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 #include "OHAVMetadataBuilder.h"
16 #include "avsession_log.h"
17
18 using namespace OHOS::AVSession;
19
SetTitle(const std::string & title)20 AVMetadata_Result OHAVMetadataBuilder::SetTitle(const std::string &title)
21 {
22 title_ = title;
23 return AVMETADATA_SUCCESS;
24 }
25
SetArtist(const std::string & artist)26 AVMetadata_Result OHAVMetadataBuilder::SetArtist(const std::string &artist)
27 {
28 artist_ = artist;
29 return AVMETADATA_SUCCESS;
30 }
31
SetAuthor(const std::string & author)32 AVMetadata_Result OHAVMetadataBuilder::SetAuthor(const std::string &author)
33 {
34 author_ = author;
35 return AVMETADATA_SUCCESS;
36 }
37
SetAlbum(const std::string & album)38 AVMetadata_Result OHAVMetadataBuilder::SetAlbum(const std::string &album)
39 {
40 album_ = album;
41 return AVMETADATA_SUCCESS;
42 }
43
SetWriter(const std::string & writer)44 AVMetadata_Result OHAVMetadataBuilder::SetWriter(const std::string &writer)
45 {
46 writer_ = writer;
47 return AVMETADATA_SUCCESS;
48 }
49
SetComposer(const std::string & composer)50 AVMetadata_Result OHAVMetadataBuilder::SetComposer(const std::string &composer)
51 {
52 composer_ = composer;
53 return AVMETADATA_SUCCESS;
54 }
55
SetDuration(int64_t duration)56 AVMetadata_Result OHAVMetadataBuilder::SetDuration(int64_t duration)
57 {
58 duration_ = duration;
59 return AVMETADATA_SUCCESS;
60 }
61
SetMediaImageUri(const std::string & mediaImageUri)62 AVMetadata_Result OHAVMetadataBuilder::SetMediaImageUri(const std::string &mediaImageUri)
63 {
64 mediaImageUri_ = mediaImageUri;
65 return AVMETADATA_SUCCESS;
66 }
67
SetSubtitle(const std::string & subtitle)68 AVMetadata_Result OHAVMetadataBuilder::SetSubtitle(const std::string &subtitle)
69 {
70 subtitle_ = subtitle;
71 return AVMETADATA_SUCCESS;
72 }
73
SetDescription(const std::string & description)74 AVMetadata_Result OHAVMetadataBuilder::SetDescription(const std::string &description)
75 {
76 description_ = description;
77 return AVMETADATA_SUCCESS;
78 }
79
SetLyric(const std::string & lyric)80 AVMetadata_Result OHAVMetadataBuilder::SetLyric(const std::string &lyric)
81 {
82 lyric_ = lyric;
83 return AVMETADATA_SUCCESS;
84 }
85
SetAssetId(const std::string & assetId)86 AVMetadata_Result OHAVMetadataBuilder::SetAssetId(const std::string &assetId)
87 {
88 assetId_ = assetId;
89 return AVMETADATA_SUCCESS;
90 }
91
SetSkipIntervals(AVMetadata_SkipIntervals intervals)92 AVMetadata_Result OHAVMetadataBuilder::SetSkipIntervals(AVMetadata_SkipIntervals intervals)
93 {
94 switch (intervals) {
95 case SECONDS_10:
96 case SECONDS_15:
97 case SECONDS_30:
98 intervals_ = intervals;
99 return AVMETADATA_SUCCESS;
100 default:
101 SLOGE("Failed to set skip intervals: Invalid skip intervals value: %d", intervals);
102 return AVMETADATA_ERROR_INVALID_PARAM;
103 }
104 }
105
SetDisplayTags(int32_t tags)106 AVMetadata_Result OHAVMetadataBuilder::SetDisplayTags(int32_t tags)
107 {
108 tags_ = tags;
109 return AVMETADATA_SUCCESS;
110 }
111
WriteCallback(std::uint8_t * ptr,size_t size,size_t nmemb,std::vector<std::uint8_t> * imgBuffer)112 size_t OHAVMetadataBuilder::WriteCallback(std::uint8_t *ptr, size_t size, size_t nmemb,
113 std::vector<std::uint8_t> *imgBuffer)
114 {
115 size_t realsize = size * nmemb;
116 imgBuffer->reserve(realsize + imgBuffer->capacity());
117 for (size_t i = 0; i < realsize; i++) {
118 imgBuffer->push_back(ptr[i]);
119 }
120 return realsize;
121 }
122
CurlSetRequestOptions(std::vector<std::uint8_t> & imgBuffer,const std::string uri)123 bool OHAVMetadataBuilder::CurlSetRequestOptions(std::vector<std::uint8_t>& imgBuffer, const std::string uri)
124 {
125 CURL *easyHandle_ = curl_easy_init();
126 if (easyHandle_) {
127 // set request options
128 curl_easy_setopt(easyHandle_, CURLOPT_URL, uri.c_str());
129 curl_easy_setopt(easyHandle_, CURLOPT_CONNECTTIMEOUT, OHAVMetadataBuilder::TIME_OUT_SECOND);
130 curl_easy_setopt(easyHandle_, CURLOPT_SSL_VERIFYPEER, 0L);
131 curl_easy_setopt(easyHandle_, CURLOPT_SSL_VERIFYHOST, 0L);
132 curl_easy_setopt(easyHandle_, CURLOPT_CAINFO, "/etc/ssl/certs/" "cacert.pem");
133 curl_easy_setopt(easyHandle_, CURLOPT_HTTPGET, 1L);
134 curl_easy_setopt(easyHandle_, CURLOPT_WRITEFUNCTION, OHAVMetadataBuilder::WriteCallback);
135 curl_easy_setopt(easyHandle_, CURLOPT_WRITEDATA, &imgBuffer);
136
137 // perform request
138 CURLcode res = curl_easy_perform(easyHandle_);
139 if (res != CURLE_OK) {
140 SLOGI("DoDownload curl easy_perform failure: %{public}s\n", curl_easy_strerror(res));
141 curl_easy_cleanup(easyHandle_);
142 easyHandle_ = nullptr;
143 return false;
144 } else {
145 int64_t httpCode = 0;
146 curl_easy_getinfo(easyHandle_, CURLINFO_RESPONSE_CODE, &httpCode);
147 SLOGI("DoDownload Http result " "%{public}" PRId64, httpCode);
148 CHECK_AND_RETURN_RET_LOG(httpCode < OHAVMetadataBuilder::HTTP_ERROR_CODE, false, "recv Http ERROR");
149 curl_easy_cleanup(easyHandle_);
150 easyHandle_ = nullptr;
151 return true;
152 }
153 }
154 return false;
155 }
156
DoDownloadInCommon(std::shared_ptr<Media::PixelMap> & pixelMap,const std::string uri)157 bool OHAVMetadataBuilder::DoDownloadInCommon(std::shared_ptr<Media::PixelMap>& pixelMap, const std::string uri)
158 {
159 std::vector<std::uint8_t> imgBuffer(0);
160 if (CurlSetRequestOptions(imgBuffer, uri) == true) {
161 std::uint8_t* buffer = (std::uint8_t*) calloc(imgBuffer.size(), sizeof(uint8_t));
162 if (buffer == nullptr) {
163 SLOGE("buffer malloc fail");
164 free(buffer);
165 return false;
166 }
167 std::copy(imgBuffer.begin(), imgBuffer.end(), buffer);
168 uint32_t errorCode = 0;
169 Media::SourceOptions opts;
170 SLOGD("DoDownload get size %{public}d", static_cast<int>(imgBuffer.size()));
171 auto imageSource = Media::ImageSource::CreateImageSource(buffer, imgBuffer.size(), opts, errorCode);
172 free(buffer);
173 if (errorCode || !imageSource) {
174 SLOGE("DoDownload create imageSource fail: %{public}u", errorCode);
175 return false;
176 }
177 Media::DecodeOptions decodeOpts;
178 pixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode);
179 if (errorCode || pixelMap == nullptr) {
180 SLOGE("DoDownload creatPix fail: %{public}u, %{public}d", errorCode, static_cast<int>(pixelMap != nullptr));
181 return false;
182 }
183 return true;
184 }
185 return false;
186 }
187
DoDownload(AVMetaData & metadata,const std::string uri)188 int32_t OHAVMetadataBuilder::DoDownload(AVMetaData& metadata, const std::string uri)
189 {
190 std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
191 bool ret = OHAVMetadataBuilder::DoDownloadInCommon(pixelMap, uri);
192 if (ret && pixelMap != nullptr) {
193 SLOGI("DoDownload success");
194 metadata.SetMediaImage(AVSessionPixelMapAdapter::ConvertToInner(pixelMap));
195 return AV_SESSION_ERR_SUCCESS;
196 }
197
198 return AV_SESSION_ERR_SERVICE_EXCEPTION;
199 }
200
GenerateAVMetadata(OH_AVMetadata ** avMetadata)201 AVMetadata_Result OHAVMetadataBuilder::GenerateAVMetadata(OH_AVMetadata** avMetadata)
202 {
203 CHECK_AND_RETURN_RET_LOG(avMetadata != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "avMetadata is null");
204
205 AVMetaData* metadata = new AVMetaData();
206 if (metadata == nullptr) {
207 SLOGE("Failed to allocate memory for AVMetaData");
208 *avMetadata = nullptr;
209 return AVMETADATA_ERROR_NO_MEMORY;
210 }
211
212 switch (intervals_) {
213 case SECONDS_10:
214 metadata->SetSkipIntervals(AVMetaData::SECONDS_10);
215 break;
216 case SECONDS_15:
217 metadata->SetSkipIntervals(AVMetaData::SECONDS_15);
218 break;
219 case SECONDS_30:
220 metadata->SetSkipIntervals(AVMetaData::SECONDS_30);
221 break;
222 default:
223 SLOGE("Failed to generate avMetadata: Unsupported skip intervals: %d", intervals_);
224 delete metadata;
225 *avMetadata = nullptr;
226 return AVMETADATA_ERROR_INVALID_PARAM;
227 }
228
229 metadata->SetTitle(title_);
230 metadata->SetArtist(artist_);
231 metadata->SetAuthor(author_);
232 metadata->SetAlbum(album_);
233 metadata->SetWriter(writer_);
234 metadata->SetComposer(composer_);
235 metadata->SetDuration(duration_);
236 metadata->SetMediaImageUri(mediaImageUri_);
237 metadata->SetSubTitle(subtitle_);
238 metadata->SetDescription(description_);
239 metadata->SetLyric(lyric_);
240 metadata->SetAssetId(assetId_);
241 metadata->SetDisplayTags(tags_);
242
243 DoDownload(*metadata, mediaImageUri_);
244
245 *avMetadata = reinterpret_cast<OH_AVMetadata*>(metadata);
246
247 return AVMETADATA_SUCCESS;
248 }
249
OH_AVMetadataBuilder_Create(OH_AVMetadataBuilder ** builder)250 AVMetadata_Result OH_AVMetadataBuilder_Create(OH_AVMetadataBuilder** builder)
251 {
252 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null");
253
254 OHAVMetadataBuilder* metadata = new OHAVMetadataBuilder();
255 if (metadata == nullptr) {
256 SLOGE("Failed to allocate memory for OHAVMetadataBuilder");
257 return AVMETADATA_ERROR_NO_MEMORY;
258 }
259
260 *builder = reinterpret_cast<OH_AVMetadataBuilder*>(metadata);
261 return AVMETADATA_SUCCESS;
262 }
263
OH_AVMetadataBuilder_Destroy(OH_AVMetadataBuilder * builder)264 AVMetadata_Result OH_AVMetadataBuilder_Destroy(OH_AVMetadataBuilder* builder)
265 {
266 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null");
267 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder);
268 delete metadata;
269 return AVMETADATA_SUCCESS;
270 }
271
OH_AVMetadataBuilder_SetTitle(OH_AVMetadataBuilder * builder,const char * title)272 AVMetadata_Result OH_AVMetadataBuilder_SetTitle(OH_AVMetadataBuilder* builder, const char* title)
273 {
274 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null");
275 CHECK_AND_RETURN_RET_LOG(title != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "title is null");
276 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder);
277 return metadata->SetTitle(title);
278 }
279
OH_AVMetadataBuilder_SetArtist(OH_AVMetadataBuilder * builder,const char * artist)280 AVMetadata_Result OH_AVMetadataBuilder_SetArtist(OH_AVMetadataBuilder* builder, const char* artist)
281 {
282 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null");
283 CHECK_AND_RETURN_RET_LOG(artist != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "artist is null");
284 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder);
285 return metadata->SetArtist(artist);
286 }
287
OH_AVMetadataBuilder_SetAuthor(OH_AVMetadataBuilder * builder,const char * author)288 AVMetadata_Result OH_AVMetadataBuilder_SetAuthor(OH_AVMetadataBuilder* builder, const char* author)
289 {
290 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null");
291 CHECK_AND_RETURN_RET_LOG(author != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "author is null");
292 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder);
293 return metadata->SetAuthor(author);
294 }
295
OH_AVMetadataBuilder_SetAlbum(OH_AVMetadataBuilder * builder,const char * album)296 AVMetadata_Result OH_AVMetadataBuilder_SetAlbum(OH_AVMetadataBuilder* builder, const char* album)
297 {
298 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null");
299 CHECK_AND_RETURN_RET_LOG(album != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "album is null");
300 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder);
301 return metadata->SetAlbum(album);
302 }
303
OH_AVMetadataBuilder_SetWriter(OH_AVMetadataBuilder * builder,const char * writer)304 AVMetadata_Result OH_AVMetadataBuilder_SetWriter(OH_AVMetadataBuilder* builder, const char* writer)
305 {
306 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null");
307 CHECK_AND_RETURN_RET_LOG(writer != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "writer is null");
308 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder);
309 return metadata->SetWriter(writer);
310 }
311
OH_AVMetadataBuilder_SetComposer(OH_AVMetadataBuilder * builder,const char * composer)312 AVMetadata_Result OH_AVMetadataBuilder_SetComposer(OH_AVMetadataBuilder* builder, const char* composer)
313 {
314 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null");
315 CHECK_AND_RETURN_RET_LOG(composer != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "composer is null");
316 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder);
317 return metadata->SetComposer(composer);
318 }
319
OH_AVMetadataBuilder_SetDuration(OH_AVMetadataBuilder * builder,int64_t duration)320 AVMetadata_Result OH_AVMetadataBuilder_SetDuration(OH_AVMetadataBuilder* builder, int64_t duration)
321 {
322 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null");
323 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder);
324 return metadata->SetDuration(duration);
325 }
326
OH_AVMetadataBuilder_SetMediaImageUri(OH_AVMetadataBuilder * builder,const char * mediaImageUri)327 AVMetadata_Result OH_AVMetadataBuilder_SetMediaImageUri(OH_AVMetadataBuilder* builder, const char* mediaImageUri)
328 {
329 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null");
330 CHECK_AND_RETURN_RET_LOG(mediaImageUri != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "mediaImageUri is null");
331 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder);
332 return metadata->SetMediaImageUri(mediaImageUri);
333 }
334
OH_AVMetadataBuilder_SetSubtitle(OH_AVMetadataBuilder * builder,const char * subtitle)335 AVMetadata_Result OH_AVMetadataBuilder_SetSubtitle(OH_AVMetadataBuilder* builder, const char* subtitle)
336 {
337 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null");
338 CHECK_AND_RETURN_RET_LOG(subtitle != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "subtitle is null");
339 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder);
340 return metadata->SetSubtitle(subtitle);
341 }
342
OH_AVMetadataBuilder_SetDescription(OH_AVMetadataBuilder * builder,const char * description)343 AVMetadata_Result OH_AVMetadataBuilder_SetDescription(OH_AVMetadataBuilder* builder, const char* description)
344 {
345 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null");
346 CHECK_AND_RETURN_RET_LOG(description != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "description is null");
347 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder);
348 return metadata->SetDescription(description);
349 }
350
OH_AVMetadataBuilder_SetLyric(OH_AVMetadataBuilder * builder,const char * lyric)351 AVMetadata_Result OH_AVMetadataBuilder_SetLyric(OH_AVMetadataBuilder* builder, const char* lyric)
352 {
353 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null");
354 CHECK_AND_RETURN_RET_LOG(lyric != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "lyric is null");
355 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder);
356 return metadata->SetLyric(lyric);
357 }
358
OH_AVMetadataBuilder_SetAssetId(OH_AVMetadataBuilder * builder,const char * assetId)359 AVMetadata_Result OH_AVMetadataBuilder_SetAssetId(OH_AVMetadataBuilder* builder, const char* assetId)
360 {
361 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null");
362 CHECK_AND_RETURN_RET_LOG(assetId != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "assetId is null");
363 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder);
364 return metadata->SetAssetId(assetId);
365 }
366
OH_AVMetadataBuilder_SetSkipIntervals(OH_AVMetadataBuilder * builder,AVMetadata_SkipIntervals intervals)367 AVMetadata_Result OH_AVMetadataBuilder_SetSkipIntervals(OH_AVMetadataBuilder* builder,
368 AVMetadata_SkipIntervals intervals)
369 {
370 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null");
371 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder);
372 return metadata->SetSkipIntervals(intervals);
373 }
374
OH_AVMetadataBuilder_SetDisplayTags(OH_AVMetadataBuilder * builder,int32_t tags)375 AVMetadata_Result OH_AVMetadataBuilder_SetDisplayTags(OH_AVMetadataBuilder* builder, int32_t tags)
376 {
377 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null");
378 if (tags != AVSESSION_DISPLAYTAG_AUDIO_VIVID) {
379 return AVMETADATA_ERROR_INVALID_PARAM;
380 }
381 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder);
382 return metadata->SetDisplayTags(tags);
383 }
384
OH_AVMetadataBuilder_GenerateAVMetadata(OH_AVMetadataBuilder * builder,OH_AVMetadata ** avMetadata)385 AVMetadata_Result OH_AVMetadataBuilder_GenerateAVMetadata(OH_AVMetadataBuilder* builder,
386 OH_AVMetadata** avMetadata)
387 {
388 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null");
389 CHECK_AND_RETURN_RET_LOG(avMetadata != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "avMetadata is null");
390 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder);
391 return metadata->GenerateAVMetadata(avMetadata);
392 }
393
OH_AVMetadata_Destroy(OH_AVMetadata * avMetadata)394 AVMetadata_Result OH_AVMetadata_Destroy(OH_AVMetadata* avMetadata)
395 {
396 CHECK_AND_RETURN_RET_LOG(avMetadata != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "avMetadata is null");
397 AVMetaData* metadata = reinterpret_cast<AVMetaData*>(avMetadata);
398 delete metadata;
399 return AVMETADATA_SUCCESS;
400 }