diff --git a/packages/video_player_avplay/CHANGELOG.md b/packages/video_player_avplay/CHANGELOG.md index c5af82f96..7d1567299 100644 --- a/packages/video_player_avplay/CHANGELOG.md +++ b/packages/video_player_avplay/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.8.1 + +* Update the error callback when DRM license acquisition fails. + ## 0.8.0 * Support parsing SMPE-TT subtitle attributes for DASH. diff --git a/packages/video_player_avplay/README.md b/packages/video_player_avplay/README.md index 072def95d..56f83c80b 100644 --- a/packages/video_player_avplay/README.md +++ b/packages/video_player_avplay/README.md @@ -12,7 +12,7 @@ To use this package, add `video_player_avplay` as a dependency in your `pubspec. ```yaml dependencies: - video_player_avplay: ^0.8.0 + video_player_avplay: ^0.8.1 ``` Then you can import `video_player_avplay` in your Dart code: diff --git a/packages/video_player_avplay/lib/src/drm_configs.dart b/packages/video_player_avplay/lib/src/drm_configs.dart index 025237ffb..9a2cd213a 100644 --- a/packages/video_player_avplay/lib/src/drm_configs.dart +++ b/packages/video_player_avplay/lib/src/drm_configs.dart @@ -26,7 +26,14 @@ class DrmConfigs { this.type = DrmType.none, this.licenseServerUrl, this.licenseCallback, - }); + }) : assert( + (licenseServerUrl != null) ^ (licenseCallback != null), + 'Either licenseServerUrl or licenseCallback should be specified, but not both.', + ), + assert( + licenseServerUrl == null || licenseServerUrl != '', + 'License server URL cannot be empty.', + ); /// The DRM type. final DrmType type; diff --git a/packages/video_player_avplay/pubspec.yaml b/packages/video_player_avplay/pubspec.yaml index bac2c163b..db303ef61 100644 --- a/packages/video_player_avplay/pubspec.yaml +++ b/packages/video_player_avplay/pubspec.yaml @@ -2,7 +2,7 @@ name: video_player_avplay description: Flutter plugin for displaying inline video on Tizen TV devices. homepage: https://github.com/flutter-tizen/plugins repository: https://github.com/flutter-tizen/plugins/tree/master/packages/video_player_avplay -version: 0.8.0 +version: 0.8.1 environment: sdk: ">=3.1.0 <4.0.0" diff --git a/packages/video_player_avplay/tizen/src/drm_manager.cc b/packages/video_player_avplay/tizen/src/drm_manager.cc index c6e3250df..32ce0a7eb 100644 --- a/packages/video_player_avplay/tizen/src/drm_manager.cc +++ b/packages/video_player_avplay/tizen/src/drm_manager.cc @@ -86,7 +86,7 @@ bool DrmManager::SetChallenge(const std::string &media_url, return DM_ERROR_NONE == SetChallenge(media_url); } -void DrmManager::ReleaseDrmSession() { +void DrmManager::StopDrmSession() { if (drm_session_ == nullptr) { LOG_ERROR("[DrmManager] Already released."); return; @@ -109,8 +109,15 @@ void DrmManager::ReleaseDrmSession() { LOG_ERROR("[DrmManager] Fail to set finalize to drm session: %s", get_error_message(ret)); } +} - ret = DrmManagerProxy::GetInstance().DMGRReleaseDRMSession(drm_session_); +void DrmManager::ReleaseDrmSession() { + if (drm_session_ == nullptr) { + LOG_ERROR("[DrmManager] Already released."); + return; + } + + int ret = DrmManagerProxy::GetInstance().DMGRReleaseDRMSession(drm_session_); if (ret != DM_ERROR_NONE) { LOG_ERROR("[DrmManager] Fail to release drm session: %s", get_error_message(ret)); @@ -241,13 +248,16 @@ bool DrmManager::ProcessLicense(DataForLicenseProcess &data) { static_cast(drm_type_), nullptr, nullptr); if (DRM_SUCCESS != ret || nullptr == response_data || 0 == response_len) { LOG_ERROR("[DrmManager] Fail to get respone by license server url."); + SendInstallKeyError(); return false; } LOG_INFO("[DrmManager] Response length : %lu", response_len); - InstallKey(const_cast( - reinterpret_cast(data.session_id.c_str())), - static_cast(response_data), - reinterpret_cast(response_len)); + if (!InstallKey(const_cast(reinterpret_cast( + data.session_id.c_str())), + static_cast(response_data), + reinterpret_cast(response_len))) { + SendInstallKeyError(); + } free(response_data); } else if (request_license_channel_) { // Get license via the Dart callback. @@ -258,7 +268,7 @@ bool DrmManager::ProcessLicense(DataForLicenseProcess &data) { return false; } -void DrmManager::InstallKey(void *session_id, void *response_data, +bool DrmManager::InstallKey(void *session_id, void *response_data, void *response_len) { LOG_INFO("[DrmManager] Start install license."); @@ -271,6 +281,22 @@ void DrmManager::InstallKey(void *session_id, void *response_data, if (ret != DM_ERROR_NONE) { LOG_ERROR("[DrmManager] Fail to install eme key: %s", get_error_message(ret)); + return false; + } + return true; +} + +void DrmManager::SetErrorCallback(ErrorCallback callback) { + error_callback_ = callback; +} + +void DrmManager::SendInstallKeyError() { + if (error_callback_) { + std::string error_code = "[DrmManager] error"; + std::string error_message = + "Error: install drm key failed, please check licenseURL or network " + "connection."; + error_callback_(error_code, error_message); } } @@ -296,13 +322,16 @@ void DrmManager::RequestLicense(std::string &session_id, std::string &message) { response = std::get>(*success_value); } else { LOG_ERROR("[DrmManager] Fail to get response."); + SendInstallKeyError(); return; } LOG_INFO("[DrmManager] Response length : %d", response.size()); - InstallKey(const_cast( - reinterpret_cast(session_id.c_str())), - reinterpret_cast(response.data()), - reinterpret_cast(response.size())); + if (!InstallKey(const_cast(reinterpret_cast( + session_id.c_str())), + reinterpret_cast(response.data()), + reinterpret_cast(response.size()))) { + SendInstallKeyError(); + } }, nullptr, nullptr); request_license_channel_->InvokeMethod( diff --git a/packages/video_player_avplay/tizen/src/drm_manager.h b/packages/video_player_avplay/tizen/src/drm_manager.h index 1808e6f4f..3eaa6534e 100644 --- a/packages/video_player_avplay/tizen/src/drm_manager.h +++ b/packages/video_player_avplay/tizen/src/drm_manager.h @@ -19,6 +19,9 @@ class DrmManager { DRM_TYPE_WIDEVINECDM, } DrmType; + using ErrorCallback = + std::function; + explicit DrmManager(); ~DrmManager(); @@ -31,7 +34,10 @@ class DrmManager { bool SecurityInitCompleteCB(int *drm_handle, unsigned int len, unsigned char *pssh_data, void *user_data); int UpdatePsshData(const void *data, int length); + void StopDrmSession(); void ReleaseDrmSession(); + void SetErrorCallback(ErrorCallback callback); + void SendInstallKeyError(); private: struct DataForLicenseProcess { @@ -43,7 +49,7 @@ class DrmManager { }; void RequestLicense(std::string &session_id, std::string &message); - void InstallKey(void *session_id, void *response_data, void *response_len); + bool InstallKey(void *session_id, void *response_data, void *response_len); int SetChallenge(const std::string &media_url); static int OnChallengeData(void *session_id, int message_type, void *message, @@ -64,6 +70,7 @@ class DrmManager { std::mutex queue_mutex_; Ecore_Pipe *license_request_pipe_ = nullptr; std::queue license_request_queue_; + ErrorCallback error_callback_; }; #endif // FLUTTER_PLUGIN_DRM_MANAGER_H_ diff --git a/packages/video_player_avplay/tizen/src/plus_player.cc b/packages/video_player_avplay/tizen/src/plus_player.cc index ab3026704..652abddb7 100644 --- a/packages/video_player_avplay/tizen/src/plus_player.cc +++ b/packages/video_player_avplay/tizen/src/plus_player.cc @@ -71,6 +71,9 @@ PlusPlayer::PlusPlayer(flutter::BinaryMessenger *messenger, PlusPlayer::~PlusPlayer() { if (player_) { + if (drm_manager_) { + drm_manager_->StopDrmSession(); + } Stop(player_); Close(player_); UnregisterListener(player_); @@ -249,6 +252,9 @@ bool PlusPlayer::Activate() { bool PlusPlayer::Deactivate() { if (is_prebuffer_mode_) { + if (drm_manager_) { + drm_manager_->StopDrmSession(); + } Stop(player_); return true; } @@ -638,6 +644,12 @@ bool PlusPlayer::SetTrackSelection(int32_t track_id, std::string track_type) { bool PlusPlayer::SetDrm(const std::string &uri, int drm_type, const std::string &license_server_url) { drm_manager_ = std::make_unique(); + DrmManager::ErrorCallback drm_error_callback = + [this](const std::string &error_code, const std::string &error_message) { + this->SendError(error_code, error_message); + }; + drm_manager_->SetErrorCallback(drm_error_callback); + if (!drm_manager_->CreateDrmSession(drm_type, true)) { LOG_ERROR("[PlusPlayer] Fail to create drm session."); return false; @@ -798,6 +810,10 @@ bool PlusPlayer::StopAndClose() { return true; } + if (drm_manager_) { + drm_manager_->StopDrmSession(); + } + if (!::Stop(player_)) { LOG_ERROR("[PlusPlayer] Player fail to stop."); return false;