1 // Copyright 2023 Samsung Electronics Inc. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/filters/media_player_bridge_capi_tv.h"
7 #include "media/base/efl/media_player_util_efl.h"
8 #include "tizen_src/chromium_impl/media/filters/media_player_tizen_client.h"
11 const int kSeekableTimeUpdateInterval = 500;
16 MediaPlayerBridgeCapiTV::MediaPlayerBridgeCapiTV(const GURL& url,
17 const std::string& user_agent,
19 : MediaPlayerBridgeCapi(url, user_agent, volume), weak_factory_(this) {
20 LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
23 MediaPlayerBridgeCapiTV::~MediaPlayerBridgeCapiTV() {
24 LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
25 weak_factory_.InvalidateWeakPtrs();
28 void MediaPlayerBridgeCapiTV::SetContentMimeType(const std::string& mime_type) {
29 LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
30 << " mime_type : " << mime_type;
31 mime_type_ = mime_type;
34 void MediaPlayerBridgeCapiTV::Prepare() {
35 if (blink::IsHbbTV() && CheckHighBitRate() && stream_type_ == DASH_STREAM)
36 AppendUrlHighBitRate(url_.spec());
37 MediaPlayerBridgeCapi::Prepare();
40 void MediaPlayerBridgeCapiTV::Release() {
41 StopSeekableTimeUpdateTimer();
42 MediaPlayerBridgeCapi::Release();
45 bool MediaPlayerBridgeCapiTV::Play() {
46 if (!MediaPlayerBridgeCapi::Play())
51 void MediaPlayerBridgeCapiTV::PlaybackCompleteUpdate() {
52 MediaPlayerBridgeCapi::PlaybackCompleteUpdate();
55 void MediaPlayerBridgeCapiTV::PlayerPrepared() {
56 MediaPlayerBridgeCapi::PlayerPrepared();
58 GetAdaptiveStreamingInfo();
59 if (/*!blink::IsHbbTV() && */is_live_stream_) {
61 StartSeekableTimeUpdateTimer();
65 void MediaPlayerBridgeCapiTV::StartSeekableTimeUpdateTimer() {
66 if (!seekable_time_update_timer_.IsRunning()) {
67 seekable_time_update_timer_.Start(
68 FROM_HERE, base::Milliseconds(kSeekableTimeUpdateInterval), this,
69 &MediaPlayerBridgeCapiTV::OnSeekableTimeUpdateTimerFired);
73 void MediaPlayerBridgeCapiTV::StopSeekableTimeUpdateTimer() {
74 if (seekable_time_update_timer_.IsRunning())
75 seekable_time_update_timer_.Stop();
78 void MediaPlayerBridgeCapiTV::OnSeekableTimeUpdateTimerFired() {
82 void MediaPlayerBridgeCapiTV::GetAdaptiveStreamingInfo() {
83 int ret = player_get_adaptive_streaming_info(player_, &is_live_stream_,
84 PLAYER_ADAPTIVE_INFO_IS_LIVE);
85 if (ret != PLAYER_ERROR_NONE || is_live_stream_) {
86 LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
91 void MediaPlayerBridgeCapiTV::UpdateSeekableTime() {
92 if (GetPlayerState() == PLAYER_STATE_NONE || !is_live_stream_)
95 int64_t min = 0, max = 0;
96 if (GetLiveStreamingDuration(&min, &max)) {
97 if (min_seekable_time_.InMilliseconds() != min ||
98 max_seekable_time_.InMilliseconds() != max) {
99 min_seekable_time_ = base::Milliseconds(min);
100 max_seekable_time_ = base::Milliseconds(max);
101 if (GetMediaPlayerClient())
102 GetMediaPlayerClient()->OnSeekableTimeChange(
103 min_seekable_time_, max_seekable_time_, is_live_stream_);
109 GetAdaptiveStreamingInfo();
110 if (!is_live_stream_) {
111 LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
112 << " changed to static stream";
113 if (GetMediaPlayerClient())
114 GetMediaPlayerClient()->OnSeekableTimeChange({}, {}, is_live_stream_);
115 MediaPlayerBridgeCapi::UpdateDuration();
119 bool MediaPlayerBridgeCapiTV::GetLiveStreamingDuration(int64_t* min,
123 constexpr const size_t kDurationBufferSize = 64;
124 char live_duration[kDurationBufferSize] = {
127 char* live_ptr = live_duration;
128 const auto err = player_get_adaptive_streaming_info(
129 player_, live_duration, PLAYER_ADAPTIVE_INFO_LIVE_DURATION);
130 if (err != PLAYER_ERROR_NONE) {
131 LOG(ERROR) << "(" << static_cast<void*>(this) << ") " << __func__
132 << " |player_get_adaptive_streaming_info| failed " << err;
136 const std::string duration(live_duration);
137 const std::string::size_type delimiter = duration.find('|');
138 if (delimiter == std::string::npos) {
139 LOG(ERROR) << "(" << static_cast<void*>(this) << ") " << __func__
140 << " Failed to find delimiter | in duration: " << duration;
144 const std::string duration_min = duration.substr(0, delimiter);
145 if (duration_min.empty()) {
146 LOG(ERROR) << "(" << static_cast<void*>(this) << ") " << __func__
147 << " Failed empty min sub str: " << duration << ", "
153 if (!base::StringToInt64(duration_min, &out_min)) {
154 LOG(ERROR) << "(" << static_cast<void*>(this) << ") " << __func__
155 << " Failed to get min from duration: " << duration;
159 const std::string duration_max = duration.substr(delimiter + 1);
160 if (duration_max.empty()) {
161 LOG(ERROR) << "(" << static_cast<void*>(this) << ") " << __func__
162 << " empty max sub str: " << duration << ", " << delimiter;
167 if (!base::StringToInt64(duration_max, &out_max)) {
168 LOG(ERROR) << "(" << static_cast<void*>(this) << ") " << __func__
169 << " Failed to get max from duration: " << duration;
178 void MediaPlayerBridgeCapiTV::AppendUrlHighBitRate(const std::string& url) {
179 // don't use url.append("|STARTBITRATE=HIGHEST") to get hbbtv url
180 // "|" will be replaced with "%7C"
181 const char high_bitrate[] = "|STARTBITRATE=HIGHEST";
182 int len = url.length() + strlen(high_bitrate) + 1;
183 char* str_url = new char[len];
188 memset(str_url, 0, len);
189 strncat(str_url, url.c_str(), url.length());
190 strncat(str_url, high_bitrate, strlen(high_bitrate));
191 hbbtv_url_ = str_url;
193 LOG(INFO) << "hbbtv url:" << hbbtv_url_.c_str();
196 bool MediaPlayerBridgeCapiTV::CheckHighBitRate() {
197 if (!GetMediaPlayerClient()) {
198 LOG(ERROR) << "MediaPlayerClient is null";
201 content::WebContentsDelegate* web_contents_delegate =
202 GetMediaPlayerClient()->GetWebContentsDelegate();
203 if (!web_contents_delegate) {
204 LOG(ERROR) << "get web_contents_delegate fail";
207 bool ret = web_contents_delegate->IsHighBitRate();
208 LOG(INFO) << "get high bit rate: " << std::boolalpha << ret;