From 17ac31590c5a49add9ce33d5e8497fcdfa52cb7e Mon Sep 17 00:00:00 2001
From: hyue7 <111051566+hyue7@users.noreply.github.com>
Date: Thu, 23 Nov 2023 13:32:21 +0800
Subject: [PATCH] [video_player_videohole] Implement 'httpHeaders' of
 'VideoPlayerController.network'. (#628)

---
 packages/video_player_videohole/CHANGELOG.md  |  4 ++
 packages/video_player_videohole/README.md     |  4 +-
 .../example/lib/main.dart                     |  2 +-
 .../tizen/src/video_player.cc                 | 37 ++++++++++++++++++-
 .../tizen/src/video_player.h                  |  3 +-
 .../tizen/src/video_player_tizen_plugin.cc    |  6 ++-
 6 files changed, 50 insertions(+), 6 deletions(-)

diff --git a/packages/video_player_videohole/CHANGELOG.md b/packages/video_player_videohole/CHANGELOG.md
index 07752697b..2e0cecd94 100644
--- a/packages/video_player_videohole/CHANGELOG.md
+++ b/packages/video_player_videohole/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.3.0
+
+* Implement `httpHeaders` of `VideoPlayerController.network`.
+
 ## 0.2.0
 
 * Implement functionality of selecting video, audio and text tracks.
diff --git a/packages/video_player_videohole/README.md b/packages/video_player_videohole/README.md
index 252c1cd97..0f79a937c 100644
--- a/packages/video_player_videohole/README.md
+++ b/packages/video_player_videohole/README.md
@@ -12,7 +12,7 @@ To use this package, add `video_player_videohole` as a dependency in your `pubsp
 
 ```yaml
 dependencies:
-  video_player_videohole: ^0.2.0
+  video_player_videohole: ^0.3.0
 ```
 
 Then you can import `video_player_videohole` in your Dart code:
@@ -112,12 +112,12 @@ TV emulator support is experimental. DRM content playback is not supported on TV
 
 The following options are not currently supported.
 
-- The `httpHeaders` option of `VideoPlayerController.network`
 - `VideoPlayerOptions.allowBackgroundPlayback`
 - `VideoPlayerOptions.mixWithOthers`
 
 This plugin has the following limitations.
 
+- The `httpHeaders` option of `VideoPlayerController.network` only support 'Cookie' and 'User-Agent'.
 - The `setPlaybackSpeed` method will fail if triggered within the last 3 seconds of the video.
 - The playback speed will reset to 1.0 when the video is replayed in loop mode.
 - The `seekTo` method works only when the playback speed is 1.0, and it sets the video position to the nearest keyframe, not the exact value passed.
diff --git a/packages/video_player_videohole/example/lib/main.dart b/packages/video_player_videohole/example/lib/main.dart
index 873360c4d..d65a58f77 100644
--- a/packages/video_player_videohole/example/lib/main.dart
+++ b/packages/video_player_videohole/example/lib/main.dart
@@ -24,7 +24,7 @@ class _App extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return DefaultTabController(
-      length: 5,
+      length: 6,
       child: Scaffold(
         key: const ValueKey<String>('home_page'),
         appBar: AppBar(
diff --git a/packages/video_player_videohole/tizen/src/video_player.cc b/packages/video_player_videohole/tizen/src/video_player.cc
index 81d1df2e7..4bbc25dd9 100644
--- a/packages/video_player_videohole/tizen/src/video_player.cc
+++ b/packages/video_player_videohole/tizen/src/video_player.cc
@@ -15,6 +15,19 @@
 
 static int64_t player_index = 1;
 
+template <typename T>
+static bool GetValueFromEncodableMap(const flutter::EncodableMap *map,
+                                     const char *key, T &out) {
+  auto iter = map->find(flutter::EncodableValue(key));
+  if (iter != map->end()) {
+    if (std::holds_alternative<T>(iter->second)) {
+      out = std::get<T>(iter->second);
+      return true;
+    }
+  }
+  return false;
+}
+
 VideoPlayer::VideoPlayer(flutter::PluginRegistrar *plugin_registrar,
                          void *native_window)
     : plugin_registrar_(plugin_registrar), native_window_(native_window) {
@@ -121,7 +134,8 @@ bool VideoPlayer::SetDisplay() {
 }
 
 int64_t VideoPlayer::Create(const std::string &uri, int drm_type,
-                            const std::string &license_server_url) {
+                            const std::string &license_server_url,
+                            const flutter::EncodableMap *http_headers) {
   LOG_INFO("[VideoPlayer] uri: %s, drm_type: %d", uri.c_str(), drm_type);
 
   player_id_ = player_index++;
@@ -151,6 +165,27 @@ int64_t VideoPlayer::Create(const std::string &uri, int drm_type,
     }
   }
 
+  if (http_headers && !http_headers->empty()) {
+    std::string cookie;
+    if (GetValueFromEncodableMap(http_headers, "Cookie", cookie)) {
+      ret = player_set_streaming_cookie(player_, cookie.c_str(), cookie.size());
+      if (ret != PLAYER_ERROR_NONE) {
+        LOG_ERROR("[MediaPlayer] player_set_streaming_cookie failed: %s.",
+                  get_error_message(ret));
+      }
+    }
+
+    std::string user_agent;
+    if (GetValueFromEncodableMap(http_headers, "User-Agent", user_agent)) {
+      ret = player_set_streaming_user_agent(player_, user_agent.c_str(),
+                                            user_agent.size());
+      if (ret != PLAYER_ERROR_NONE) {
+        LOG_ERROR("[MediaPlayer] player_set_streaming_user_agent failed: %s.",
+                  get_error_message(ret));
+      }
+    }
+  }
+
   ret = player_set_uri(player_, uri.c_str());
   if (ret != PLAYER_ERROR_NONE) {
     LOG_ERROR("[VideoPlayer] player_set_uri failed: %s",
diff --git a/packages/video_player_videohole/tizen/src/video_player.h b/packages/video_player_videohole/tizen/src/video_player.h
index 1fdf9038a..0eb02900e 100644
--- a/packages/video_player_videohole/tizen/src/video_player.h
+++ b/packages/video_player_videohole/tizen/src/video_player.h
@@ -75,7 +75,8 @@ class VideoPlayer {
   ~VideoPlayer();
 
   int64_t Create(const std::string &uri, int drm_type,
-                 const std::string &license_server_url);
+                 const std::string &license_server_url,
+                 const flutter::EncodableMap *http_headers);
   void Dispose();
 
   void SetDisplayRoi(int32_t x, int32_t y, int32_t width, int32_t height);
diff --git a/packages/video_player_videohole/tizen/src/video_player_tizen_plugin.cc b/packages/video_player_videohole/tizen/src/video_player_tizen_plugin.cc
index 11a2962a3..e32bad05e 100644
--- a/packages/video_player_videohole/tizen/src/video_player_tizen_plugin.cc
+++ b/packages/video_player_videohole/tizen/src/video_player_tizen_plugin.cc
@@ -118,6 +118,7 @@ ErrorOr<PlayerMessage> VideoPlayerTizenPlugin::Create(
   std::string uri;
   int32_t drm_type = 0;  // DRM_TYPE_NONE
   std::string license_server_url;
+  const flutter::EncodableMap *http_headers = nullptr;
 
   if (msg.asset() && !msg.asset()->empty()) {
     char *res_path = app_get_resource_path();
@@ -145,11 +146,14 @@ ErrorOr<PlayerMessage> VideoPlayerTizenPlugin::Create(
         }
       }
     }
+
+    http_headers = msg.http_headers();
   } else {
     return FlutterError("Invalid argument", "Either asset or uri must be set.");
   }
 
-  int64_t player_id = player->Create(uri, drm_type, license_server_url);
+  int64_t player_id =
+      player->Create(uri, drm_type, license_server_url, http_headers);
   if (player_id == -1) {
     return FlutterError("Operation failed", "Failed to create a player.");
   }