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 18using namespace OHOS::AVSession; 19 20AVMetadata_Result OHAVMetadataBuilder::SetTitle(const std::string &title) 21{ 22 title_ = title; 23 return AVMETADATA_SUCCESS; 24} 25 26AVMetadata_Result OHAVMetadataBuilder::SetArtist(const std::string &artist) 27{ 28 artist_ = artist; 29 return AVMETADATA_SUCCESS; 30} 31 32AVMetadata_Result OHAVMetadataBuilder::SetAuthor(const std::string &author) 33{ 34 author_ = author; 35 return AVMETADATA_SUCCESS; 36} 37 38AVMetadata_Result OHAVMetadataBuilder::SetAlbum(const std::string &album) 39{ 40 album_ = album; 41 return AVMETADATA_SUCCESS; 42} 43 44AVMetadata_Result OHAVMetadataBuilder::SetWriter(const std::string &writer) 45{ 46 writer_ = writer; 47 return AVMETADATA_SUCCESS; 48} 49 50AVMetadata_Result OHAVMetadataBuilder::SetComposer(const std::string &composer) 51{ 52 composer_ = composer; 53 return AVMETADATA_SUCCESS; 54} 55 56AVMetadata_Result OHAVMetadataBuilder::SetDuration(int64_t duration) 57{ 58 duration_ = duration; 59 return AVMETADATA_SUCCESS; 60} 61 62AVMetadata_Result OHAVMetadataBuilder::SetMediaImageUri(const std::string &mediaImageUri) 63{ 64 mediaImageUri_ = mediaImageUri; 65 return AVMETADATA_SUCCESS; 66} 67 68AVMetadata_Result OHAVMetadataBuilder::SetSubtitle(const std::string &subtitle) 69{ 70 subtitle_ = subtitle; 71 return AVMETADATA_SUCCESS; 72} 73 74AVMetadata_Result OHAVMetadataBuilder::SetDescription(const std::string &description) 75{ 76 description_ = description; 77 return AVMETADATA_SUCCESS; 78} 79 80AVMetadata_Result OHAVMetadataBuilder::SetLyric(const std::string &lyric) 81{ 82 lyric_ = lyric; 83 return AVMETADATA_SUCCESS; 84} 85 86AVMetadata_Result OHAVMetadataBuilder::SetAssetId(const std::string &assetId) 87{ 88 assetId_ = assetId; 89 return AVMETADATA_SUCCESS; 90} 91 92AVMetadata_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 106AVMetadata_Result OHAVMetadataBuilder::SetDisplayTags(int32_t tags) 107{ 108 tags_ = tags; 109 return AVMETADATA_SUCCESS; 110} 111 112size_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 123bool 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 157bool 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 188int32_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 201AVMetadata_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 metadata = nullptr; 226 *avMetadata = nullptr; 227 return AVMETADATA_ERROR_INVALID_PARAM; 228 } 229 230 metadata->SetTitle(title_); 231 metadata->SetArtist(artist_); 232 metadata->SetAuthor(author_); 233 metadata->SetAlbum(album_); 234 metadata->SetWriter(writer_); 235 metadata->SetComposer(composer_); 236 metadata->SetDuration(duration_); 237 metadata->SetMediaImageUri(mediaImageUri_); 238 metadata->SetSubTitle(subtitle_); 239 metadata->SetDescription(description_); 240 metadata->SetLyric(lyric_); 241 metadata->SetAssetId(assetId_); 242 metadata->SetDisplayTags(tags_); 243 244 DoDownload(*metadata, mediaImageUri_); 245 246 *avMetadata = reinterpret_cast<OH_AVMetadata*>(metadata); 247 248 return AVMETADATA_SUCCESS; 249} 250 251AVMetadata_Result OH_AVMetadataBuilder_Create(OH_AVMetadataBuilder** builder) 252{ 253 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null"); 254 255 OHAVMetadataBuilder* metadata = new OHAVMetadataBuilder(); 256 if (metadata == nullptr) { 257 SLOGE("Failed to allocate memory for OHAVMetadataBuilder"); 258 return AVMETADATA_ERROR_NO_MEMORY; 259 } 260 261 *builder = reinterpret_cast<OH_AVMetadataBuilder*>(metadata); 262 return AVMETADATA_SUCCESS; 263} 264 265AVMetadata_Result OH_AVMetadataBuilder_Destroy(OH_AVMetadataBuilder* builder) 266{ 267 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null"); 268 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder); 269 delete metadata; 270 metadata = nullptr; 271 return AVMETADATA_SUCCESS; 272} 273 274AVMetadata_Result OH_AVMetadataBuilder_SetTitle(OH_AVMetadataBuilder* builder, const char* title) 275{ 276 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null"); 277 CHECK_AND_RETURN_RET_LOG(title != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "title is null"); 278 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder); 279 return metadata->SetTitle(title); 280} 281 282AVMetadata_Result OH_AVMetadataBuilder_SetArtist(OH_AVMetadataBuilder* builder, const char* artist) 283{ 284 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null"); 285 CHECK_AND_RETURN_RET_LOG(artist != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "artist is null"); 286 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder); 287 return metadata->SetArtist(artist); 288} 289 290AVMetadata_Result OH_AVMetadataBuilder_SetAuthor(OH_AVMetadataBuilder* builder, const char* author) 291{ 292 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null"); 293 CHECK_AND_RETURN_RET_LOG(author != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "author is null"); 294 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder); 295 return metadata->SetAuthor(author); 296} 297 298AVMetadata_Result OH_AVMetadataBuilder_SetAlbum(OH_AVMetadataBuilder* builder, const char* album) 299{ 300 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null"); 301 CHECK_AND_RETURN_RET_LOG(album != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "album is null"); 302 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder); 303 return metadata->SetAlbum(album); 304} 305 306AVMetadata_Result OH_AVMetadataBuilder_SetWriter(OH_AVMetadataBuilder* builder, const char* writer) 307{ 308 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null"); 309 CHECK_AND_RETURN_RET_LOG(writer != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "writer is null"); 310 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder); 311 return metadata->SetWriter(writer); 312} 313 314AVMetadata_Result OH_AVMetadataBuilder_SetComposer(OH_AVMetadataBuilder* builder, const char* composer) 315{ 316 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null"); 317 CHECK_AND_RETURN_RET_LOG(composer != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "composer is null"); 318 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder); 319 return metadata->SetComposer(composer); 320} 321 322AVMetadata_Result OH_AVMetadataBuilder_SetDuration(OH_AVMetadataBuilder* builder, int64_t duration) 323{ 324 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null"); 325 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder); 326 return metadata->SetDuration(duration); 327} 328 329AVMetadata_Result OH_AVMetadataBuilder_SetMediaImageUri(OH_AVMetadataBuilder* builder, const char* mediaImageUri) 330{ 331 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null"); 332 CHECK_AND_RETURN_RET_LOG(mediaImageUri != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "mediaImageUri is null"); 333 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder); 334 return metadata->SetMediaImageUri(mediaImageUri); 335} 336 337AVMetadata_Result OH_AVMetadataBuilder_SetSubtitle(OH_AVMetadataBuilder* builder, const char* subtitle) 338{ 339 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null"); 340 CHECK_AND_RETURN_RET_LOG(subtitle != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "subtitle is null"); 341 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder); 342 return metadata->SetSubtitle(subtitle); 343} 344 345AVMetadata_Result OH_AVMetadataBuilder_SetDescription(OH_AVMetadataBuilder* builder, const char* description) 346{ 347 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null"); 348 CHECK_AND_RETURN_RET_LOG(description != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "description is null"); 349 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder); 350 return metadata->SetDescription(description); 351} 352 353AVMetadata_Result OH_AVMetadataBuilder_SetLyric(OH_AVMetadataBuilder* builder, const char* lyric) 354{ 355 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null"); 356 CHECK_AND_RETURN_RET_LOG(lyric != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "lyric is null"); 357 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder); 358 return metadata->SetLyric(lyric); 359} 360 361AVMetadata_Result OH_AVMetadataBuilder_SetAssetId(OH_AVMetadataBuilder* builder, const char* assetId) 362{ 363 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null"); 364 CHECK_AND_RETURN_RET_LOG(assetId != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "assetId is null"); 365 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder); 366 return metadata->SetAssetId(assetId); 367} 368 369AVMetadata_Result OH_AVMetadataBuilder_SetSkipIntervals(OH_AVMetadataBuilder* builder, 370 AVMetadata_SkipIntervals intervals) 371{ 372 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null"); 373 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder); 374 return metadata->SetSkipIntervals(intervals); 375} 376 377AVMetadata_Result OH_AVMetadataBuilder_SetDisplayTags(OH_AVMetadataBuilder* builder, int32_t tags) 378{ 379 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null"); 380 if (tags != AVSESSION_DISPLAYTAG_AUDIO_VIVID) { 381 return AVMETADATA_ERROR_INVALID_PARAM; 382 } 383 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder); 384 return metadata->SetDisplayTags(tags); 385} 386 387AVMetadata_Result OH_AVMetadataBuilder_GenerateAVMetadata(OH_AVMetadataBuilder* builder, 388 OH_AVMetadata** avMetadata) 389{ 390 CHECK_AND_RETURN_RET_LOG(builder != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "builder is null"); 391 CHECK_AND_RETURN_RET_LOG(avMetadata != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "avMetadata is null"); 392 OHAVMetadataBuilder* metadata = reinterpret_cast<OHAVMetadataBuilder*>(builder); 393 return metadata->GenerateAVMetadata(avMetadata); 394} 395 396AVMetadata_Result OH_AVMetadata_Destroy(OH_AVMetadata* avMetadata) 397{ 398 CHECK_AND_RETURN_RET_LOG(avMetadata != nullptr, AVMETADATA_ERROR_INVALID_PARAM, "avMetadata is null"); 399 AVMetaData* metadata = reinterpret_cast<AVMetaData*>(avMetadata); 400 delete metadata; 401 metadata = nullptr; 402 return AVMETADATA_SUCCESS; 403}