[M120 Migration][MM] Handle live stream duration and currenttime
[platform/framework/web/chromium-efl.git] / tizen_src / chromium_impl / media / filters / media_player_bridge_capi_tv.cc
index 94c898b..b18eaa3 100644 (file)
@@ -8,6 +8,8 @@
 #include "media/base/efl/media_player_util_efl.h"
 #include "tizen_src/chromium_impl/media/filters/media_player_tizen_client.h"
 
+#include <jsoncpp/json/json.h>
+
 namespace {
 const int kSeekableTimeUpdateInterval = 500;
 }
@@ -151,8 +153,11 @@ void MediaPlayerBridgeCapiTV::Pause(bool is_media_related_action) {
 
 void MediaPlayerBridgeCapiTV::PlaybackCompleteUpdate() {
   MediaPlayerBridgeCapi::PlaybackCompleteUpdate();
-  if (GetMediaPlayerClient())
+  if (GetMediaPlayerClient()) {
     GetMediaPlayerClient()->NotifyPlaybackState(kPlaybackFinish, player_id_);
+    if (is_live_stream_)
+      GetMediaPlayerClient()->OnLivePlaybackComplete();
+  }
 }  // namespace media
 
 void MediaPlayerBridgeCapiTV::PlayerPrepared() {
@@ -191,7 +196,7 @@ void MediaPlayerBridgeCapiTV::OnSeekableTimeUpdateTimerFired() {
 void MediaPlayerBridgeCapiTV::GetAdaptiveStreamingInfo() {
   int ret = player_get_adaptive_streaming_info(player_, &is_live_stream_,
                                                PLAYER_ADAPTIVE_INFO_IS_LIVE);
-  if (ret != PLAYER_ERROR_NONE || is_live_stream_) {
+  if (ret == PLAYER_ERROR_NONE && is_live_stream_) {
     LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
               << " A live stream.";
   }
@@ -235,7 +240,7 @@ bool MediaPlayerBridgeCapiTV::GetLiveStreamingDuration(int64_t* min,
   };
   char* live_ptr = live_duration;
   const auto err = player_get_adaptive_streaming_info(
-      player_, live_duration, PLAYER_ADAPTIVE_INFO_LIVE_DURATION);
+      player_, &live_ptr, PLAYER_ADAPTIVE_INFO_LIVE_DURATION);
   if (err != PLAYER_ERROR_NONE) {
     LOG(ERROR) << "(" << static_cast<void*>(this) << ") " << __func__
                << " |player_get_adaptive_streaming_info| failed " << err;
@@ -284,6 +289,67 @@ bool MediaPlayerBridgeCapiTV::GetLiveStreamingDuration(int64_t* min,
   return true;
 }
 
+void MediaPlayerBridgeCapiTV::ParseDashInfo() {
+  std::string dash_info = GetDashInfo();
+  Json::CharReaderBuilder builder;
+  Json::CharReader* reader(builder.newCharReader());
+  Json::Value value;
+
+  if (reader->parse(dash_info.c_str(), dash_info.c_str() + dash_info.length(),
+                    &value, nullptr)) {
+    mrs_url_ = value["mrsUrl"].asString();
+    std::string periodId = value["periodId"].asString();
+    if (periodId != "")
+      content_id_ = clean_url_ + "#period=" + periodId;
+  }
+  LOG(INFO) << "mrsUrl: " << mrs_url_ << ",contentId: " << content_id_;
+}
+
+std::string MediaPlayerBridgeCapiTV::GetDashInfo() {
+  char* dash_info = nullptr;
+  // dash_info format:
+  // {"type":0,"minBufferTime":4000,"mrsUrl":"","periodId":"first"}
+  const int ret = player_get_dash_info(player_, &dash_info);
+  if (ret != PLAYER_ERROR_NONE) {
+    if (dash_info)
+      free(dash_info);
+    LOG(ERROR) << "Fail to call player_get_dash_info,ret:" << ret;
+    return "";
+  }
+
+  if (!dash_info) {
+    LOG(ERROR) << "empty dash_info.";
+    return "";
+  }
+
+  const std::string info(dash_info);
+  free(dash_info);
+  LOG(INFO) << "dash info str: " << info;
+
+  return info;
+}
+
+bool MediaPlayerBridgeCapiTV::GetDashLiveDuration(int64_t* duration) {
+  DCHECK(duration);
+  std::string dash_info = GetDashInfo();
+  Json::CharReaderBuilder builder;
+  Json::CharReader* reader(builder.newCharReader());
+  Json::Value value;
+  int64_t out_duration = 0;
+
+  if (reader->parse(dash_info.c_str(), dash_info.c_str() + dash_info.length(),
+                    &value, nullptr)) {
+    out_duration = value["mediaPresentationDuration"].asInt();
+  }
+
+  // According to dash spec, if duration == -1, set max time as duration.
+  if (out_duration == -1)
+    out_duration = base::TimeDelta::Max().InMilliseconds();
+  *duration = out_duration;
+
+  return true;
+}
+
 void MediaPlayerBridgeCapiTV::AppendUrlHighBitRate(const std::string& url) {
   // don't use url.append("|STARTBITRATE=HIGHEST") to get hbbtv url
   // "|" will be replaced with "%7C"
@@ -365,7 +431,38 @@ void MediaPlayerBridgeCapiTV::UpdateDuration() {
     LOG(INFO) << "HBBTV preload not finished, no need update duration. ";
     return;
   }
-  MediaPlayerBridgeCapi::UpdateDuration();
+  if (is_live_stream_) {
+    int64_t duration = 0;
+    if (stream_type_ == HLS_STREAM) {
+      int64_t min = 0;
+      if (!GetLiveStreamingDuration(&min, &duration)) {
+        LOG(ERROR) << "Fail to get duration for hls live stream.";
+        return;
+      }
+    } else if (stream_type_ == DASH_STREAM) {
+      if (!GetDashLiveDuration(&duration)) {
+        if (duration_ != base::TimeDelta::Max()) {
+          duration_ = base::TimeDelta::Max();
+          OnDurationChange(player_id_, duration_.InSecondsF());
+        }
+        return;
+      }
+    } else {
+      LOG(ERROR) << "Unknown live stream type : " << stream_type_;
+    }
+
+    if (duration == 0) {
+      LOG(WARNING) << "live stream type : convert duration to max";
+      duration_ = base::TimeDelta::Max();
+      OnDurationChange(player_id_, duration_.InSecondsF());
+    } else if (duration_.InSecondsF() !=
+               ConvertMilliSecondsToSeconds(duration)) {
+      duration_ = base::Milliseconds(duration);
+      OnDurationChange(player_id_, duration_.InSecondsF());
+    }
+  } else {  // non-live stream sequence
+    MediaPlayerBridgeCapi::UpdateDuration();
+  }
 }
 
 void MediaPlayerBridgeCapiTV::UpdateMediaType() {
@@ -424,8 +521,8 @@ void MediaPlayerBridgeCapiTV::PlayerPreloaded() {
 
   is_preloaded_ = true;
   is_live_stream_ = CheckLiveStreaming();
-  // if (stream_type_ == DASH_STREAM)
-  //  ParseDashInfo();
+  if (stream_type_ == DASH_STREAM)
+    ParseDashInfo();
   if (is_live_stream_ && stream_type_ != OTHER_STREAM) {
     // UpdateSeekableTime();
     // StartSeekableTimeUpdateTimer();