zhaoyadi 2 năm trước cách đây
mục cha
commit
2041716ea9
21 tập tin đã thay đổi với 318 bổ sung17 xóa
  1. 0 2
      kit/build.gradle
  2. 7 0
      kit/src/main/kotlin/com/tencent/liteav/demo/superplayer/PlayerApplication.java
  3. 18 0
      kit/src/main/kotlin/com/tencent/liteav/demo/superplayer/util/HttpUtils.kt
  4. 6 2
      ui/build.gradle
  5. 138 0
      ui/src/main/java/com/tencent/liteav/demo/player/util/ModelCourse.java
  6. 4 0
      ui/src/main/java/com/tencent/liteav/demo/player/util/ModelParser.java
  7. 2 2
      ui/src/main/java/com/tencent/liteav/demo/player/util/ModelProvider.java
  8. 3 3
      ui/src/main/kotlin/com/tencent/liteav/demo/player/PlayerActivity.kt
  9. 22 1
      ui/src/main/kotlin/com/tencent/liteav/demo/player/PlayerMenu.kt
  10. 5 1
      ui/src/main/kotlin/com/tencent/liteav/demo/player/PlayerVerify.kt
  11. 35 0
      ui/src/main/kotlin/com/tencent/liteav/demo/player/http/AuthorizationInterceptor.kt
  12. 12 0
      ui/src/main/kotlin/com/tencent/liteav/demo/player/http/CourseApi.kt
  13. 36 0
      ui/src/main/kotlin/com/tencent/liteav/demo/player/http/HttpManager.kt
  14. 7 0
      ui/src/main/kotlin/com/tencent/liteav/demo/player/http/HttpResult.kt
  15. 4 4
      ui/src/main/kotlin/com/tencent/liteav/demo/player/menu/PlayerTimer.kt
  16. 19 2
      ui/src/main/kotlin/com/tencent/liteav/demo/player/viewmodel/PlayerViewModel.kt
  17. BIN
      ui/src/main/res/mipmap-hdpi/item_favorited.png
  18. BIN
      ui/src/main/res/mipmap-mdpi/item_favorited.png
  19. BIN
      ui/src/main/res/mipmap-xhdpi/item_favorited.png
  20. BIN
      ui/src/main/res/mipmap-xxhdpi/item_favorited.png
  21. BIN
      ui/src/main/res/mipmap-xxxhdpi/item_favorited.png

+ 0 - 2
kit/build.gradle

@@ -57,8 +57,6 @@ dependencies {
     implementation 'androidx.exifinterface:exifinterface:1.3.3'
     api 'androidx.constraintlayout:constraintlayout:2.1.4'
 
-    implementation("org.greenrobot:eventbus:3.3.1")
-
     def room_version = "2.4.0"
     implementation "androidx.room:room-runtime:$room_version"
     kapt "androidx.room:room-compiler:$room_version"

+ 7 - 0
kit/src/main/kotlin/com/tencent/liteav/demo/superplayer/PlayerApplication.java

@@ -7,11 +7,18 @@ import androidx.annotation.NonNull;
 import com.tencent.liteav.demo.superplayer.database.PlayerDatabase;
 import com.tencent.liteav.demo.superplayer.database.PlayerDatabaseProvider;
 import com.tencent.liteav.demo.superplayer.database.repo.PlayerRepository;
+import com.tencent.liteav.demo.superplayer.util.HttpUtils;
 
 public class PlayerApplication extends Application implements PlayerDatabaseProvider {
     private PlayerDatabase database;
     private PlayerRepository repository;
 
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        HttpUtils.INSTANCE.init(this);
+    }
+
     @NonNull
     @Override
     public PlayerDatabase getPlayerDatabase() {

+ 18 - 0
kit/src/main/kotlin/com/tencent/liteav/demo/superplayer/util/HttpUtils.kt

@@ -0,0 +1,18 @@
+package com.tencent.liteav.demo.superplayer.util
+
+import android.content.Context
+import java.util.*
+
+object HttpUtils {
+    private var application: Context? = null
+
+    fun init(context: Context) {
+        application = context.applicationContext
+    }
+
+    fun getApplication(): Context {
+        Objects.requireNonNull(application, "使先用HttpUtils.init(context)初始化")
+
+        return application!!
+    }
+}

+ 6 - 2
ui/build.gradle

@@ -52,9 +52,13 @@ dependencies {
     implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1"
     implementation "androidx.lifecycle:lifecycle-common-java8:2.5.1"
 
-    implementation 'androidx.appcompat:appcompat:1.0.0'
+    implementation 'androidx.appcompat:appcompat:1.4.2'
     implementation 'androidx.recyclerview:recyclerview:1.2.1'
-    implementation 'com.squareup.okhttp3:okhttp:4.9.3'
+
+    implementation 'com.squareup.okhttp3:okhttp:4.10.0'
+    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
+    implementation("com.squareup.retrofit2:converter-gson:2.9.0")
+    implementation("com.squareup.okhttp3:logging-interceptor:4.10.0")
 
     implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0'
     implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0'

+ 138 - 0
ui/src/main/java/com/tencent/liteav/demo/player/util/ModelCourse.java

@@ -0,0 +1,138 @@
+package com.tencent.liteav.demo.player.util;
+
+import java.util.ArrayList;
+
+public class ModelCourse {
+    public static class ChapterList{
+        public String id;
+        public String name;
+        public String createTime;
+        public Object updateTime;
+        public String aiCourseSkuId;
+        public int sort;
+        public Object coverImgUrl;
+        public ArrayList<ItemList> itemList;
+    }
+
+    public static class ItemList{
+        public String id;
+        public String name;
+        public String videoId;
+        public String aiCourseSkuId;
+        public int sort;
+        public String createTime;
+        public String updateTime;
+        public int readCount;
+        public String aiCourseItemChapterId;
+        public int type;
+        public int payType;
+        public int freeTime;
+        public Object audioId;
+        public String imgCover;
+        public Object richText;
+        public Object splitList;
+        public int hasReport;
+        public String clockInUserCount;
+        public int enable;
+        public int hasReply;
+        public int totalStarCount;
+        public ArrayList<Object> starList;
+        public String readCountStr;
+        public Video video;
+        public int hasClockIn;
+        public int getStarCount;
+    }
+
+    public static class Course{
+        public String id;
+        public String name;
+        public String imgCover;
+        public String imgCoverMini;
+        public String createTime;
+        public String updateTime;
+        public double price;
+        public double markingPrice;
+        public String categoryId;
+        public int courseCount;
+        public String aiCourseSpuId;
+        public String suitAge;
+        public Object wxNumber;
+        public Object wxQrCode;
+        public Object wxName;
+        public Object wxHeadImg;
+        public String description;
+        public int mediaType;
+        public String simpleDescription;
+        public int sort;
+        public int showChapter;
+        public int courseType;
+        public String subCategoryId;
+        public Object activityTag;
+        public ArrayList<Object> courseTags;
+        public int paidCount;
+        public Object latestLearnedRecordId;
+        public Object latestLearnedRecord;
+        public ArrayList<Object> abilityList;
+        public int commentCount;
+        public int shareCount;
+        public int collectCount;
+        public int isCollect;
+        public int hasPaid;
+        public int isComment;
+        public int isShare;
+        public Object imgCoverWidth;
+        public Object imgCoverHeight;
+        public String shareUrl;
+        public String shareUrlQRCode;
+        public Object groupBuyActivity;
+        public Object groupBuyActivityId;
+        public Object groupBuyActivityUrl;
+        public int show_cover_img;
+        public Spu spu;
+        public int totalStarCount;
+        public int getStarCount;
+        public ArrayList<ChapterList> chapterList;
+        public Object videoUrl;
+    }
+
+    public static class Spu{
+        public String id;
+        public String name;
+        public String imgCover;
+        public String imgCoverMini;
+        public Object videoUrl;
+        public String createTime;
+        public String updateTime;
+        public double price;
+        public double markingPrice;
+        public String categoryId;
+        public String suitAge;
+        public Object parentNotice;
+        public int courseCount;
+        public Object description;
+        public Object outline;
+        public Object notice;
+        public String simpleDescription;
+        public int mediaType;
+        public int status;
+        public int isDelete;
+        public int sort;
+        public int showChapter;
+        public boolean isShow;
+        public int showCoverImg;
+    }
+
+    public static class Video{
+        public String id;
+        public String videoUrl;
+        public String parentId;
+        public String createTime;
+        public String updateTime;
+        public int width;
+        public int height;
+        public String thumbnailUrl;
+        public String duration;
+    }
+
+
+}

+ 4 - 0
ui/src/main/java/com/tencent/liteav/demo/player/util/ModelParser.java

@@ -0,0 +1,4 @@
+package com.tencent.liteav.demo.player.util;
+
+public class ModelParser {
+}

+ 2 - 2
ui/src/main/java/com/tencent/liteav/demo/player/util/PlayerModelProvider.java → ui/src/main/java/com/tencent/liteav/demo/player/util/ModelProvider.java

@@ -5,12 +5,12 @@ import com.tencent.liteav.demo.superplayer.SuperPlayerModel;
 import java.util.ArrayList;
 import java.util.List;
 
-public class PlayerModelProvider {
+public class ModelProvider {
     private static final String VIDEO_URL = "https://www.douyin.com/aweme/v1/play/?video_id=v0200fg10000cc5ca8bc77u6euo714d0&line=0&file_id=9c767801265548eaac539800298114a9&sign=c2faa0a73f75bef995e495c4d6688e00&is_play_url=1&source=PackSourceEnum_FEED&aid=6383";
 
     private static final String COVER_URL = "https://p9-pc-sign.douyinpic.com/tos-cn-p-0015/57aaf7f5975247e09c3df35e152055e4_1654159193~tplv-dy-360p.jpeg?biz_tag=pcweb_cover&from=4257465056&se=false&x-expires=1662015600&x-signature=0uL3qAHjGGcvaNmDuopeSCKdfm8%3D";
 
-    private PlayerModelProvider() {
+    private ModelProvider() {
     }
 
     public static String getCourseId() {

+ 3 - 3
ui/src/main/kotlin/com/tencent/liteav/demo/player/PlayerActivity.kt

@@ -13,7 +13,7 @@ import com.tencent.liteav.demo.player.ViewInsets.ViewportMetrics
 import com.tencent.liteav.demo.player.databinding.ActivityPlayerBinding
 import com.tencent.liteav.demo.player.ui.PlayerListAdapter
 import com.tencent.liteav.demo.player.ui.PlayerListDecoration
-import com.tencent.liteav.demo.player.util.PlayerModelProvider
+import com.tencent.liteav.demo.player.util.ModelProvider
 import com.tencent.liteav.demo.player.viewmodel.PlayerViewModel
 import com.tencent.liteav.demo.player.viewmodel.PlayerViewModelFactory
 import com.tencent.liteav.demo.superplayer.SuperPlayerDef
@@ -59,7 +59,7 @@ class PlayerActivity : AppCompatActivity(),
 
     private val viewModel by viewModels<PlayerViewModel> {
         PlayerViewModelFactory(
-            PlayerModelProvider.getCourseId(),
+            ModelProvider.getCourseId(),
             ((application) as PlayerDatabaseProvider).getPlayerRepository()
         )
     }
@@ -205,7 +205,7 @@ class PlayerActivity : AppCompatActivity(),
     private fun updateList() {
         mVodPlayerListAdapter.clear()
 
-        val list = PlayerModelProvider.getList();
+        val list = ModelProvider.getList();
         for (videoModel in list) {
             mVodPlayerListAdapter.addSuperPlayerModel(videoModel)
         }

+ 22 - 1
ui/src/main/kotlin/com/tencent/liteav/demo/player/PlayerMenu.kt

@@ -6,9 +6,12 @@ import android.os.Bundle
 import android.view.*
 import androidx.appcompat.app.AppCompatActivity
 import com.tencent.liteav.demo.player.databinding.FragmentMenuBinding
+import com.tencent.liteav.demo.player.http.CourseApi
+import com.tencent.liteav.demo.player.http.HttpManager
 import com.tencent.liteav.demo.player.menu.PlayerTimer
+import kotlinx.coroutines.*
 
-class PlayerMenu : AppCompatActivity(), View.OnClickListener {
+class PlayerMenu : AppCompatActivity(), View.OnClickListener, CoroutineScope by MainScope() {
     private var _viewBinding: FragmentMenuBinding? = null
     private val viewBinding get() = _viewBinding!!
 
@@ -20,6 +23,8 @@ class PlayerMenu : AppCompatActivity(), View.OnClickListener {
 
     private lateinit var courseId: String
 
+    private val api: CourseApi = HttpManager.create()
+
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
 
@@ -60,6 +65,22 @@ class PlayerMenu : AppCompatActivity(), View.OnClickListener {
             R.id.menu_item_cast -> {
             }
             R.id.menu_item_favorite -> {
+                launch(Dispatchers.IO) {
+                    val result = api.favoriteCourse(
+                        mapOf(
+                            "aiCourseSkuId" to "1540203667959226370",
+                            "aiCourseSpuId" to "1540203667934060546",
+                        )
+                    )
+
+                    withContext(Dispatchers.Main) {
+                        if (result.data != null && result.data == 1) {
+                            imageFavorite.setIcon(R.mipmap.item_favorited)
+                        } else {
+                            imageFavorite.setIcon(R.mipmap.item_favorite)
+                        }
+                    }
+                }
             }
             R.id.menu_item_share -> {
             }

+ 5 - 1
ui/src/main/kotlin/com/tencent/liteav/demo/player/PlayerVerify.kt

@@ -77,7 +77,11 @@ class PlayerVerify : AppCompatActivity(), View.OnClickListener {
     private fun addNumber(num: Int) {
         resetInput()
         val result = binding.resultNum.text.toString()
-        binding.resultNum.text = result + num
+        if (result.length == 2) {
+            checkError()
+        } else {
+            binding.resultNum.text = result + num
+        }
     }
 
     private fun checkResult() {

+ 35 - 0
ui/src/main/kotlin/com/tencent/liteav/demo/player/http/AuthorizationInterceptor.kt

@@ -0,0 +1,35 @@
+package com.tencent.liteav.demo.player.http
+
+import android.content.Context
+import android.os.Build
+import com.tencent.liteav.demo.superplayer.util.HttpUtils
+import okhttp3.Interceptor
+import okhttp3.Response
+
+class AuthorizationInterceptor : Interceptor {
+    private var token: String? = null
+
+    companion object {
+        const val error = "{}"
+    }
+
+    override fun intercept(chain: Interceptor.Chain): Response {
+        if (token == null) {
+            val application = HttpUtils.getApplication()
+            val sp =
+                application.getSharedPreferences("FlutterSharedPreferences", Context.MODE_PRIVATE)
+
+            token = sp.getString("flutter.token", null)
+        }
+
+        token =
+            "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIxMzY0ODM1MjU0MDY0ODgxNjY1IiwiZXhwIjoxNjYyNjI2NjQ1fQ.z4kRUnx7RRwp0GCNjBofRazTse4VZXfdr8CAkECLosU"
+
+        val newRequest = chain.request()
+            .newBuilder()
+            .addHeader("token", token ?: "")
+            .build()
+
+        return chain.proceed(newRequest)
+    }
+}

+ 12 - 0
ui/src/main/kotlin/com/tencent/liteav/demo/player/http/CourseApi.kt

@@ -0,0 +1,12 @@
+package com.tencent.liteav.demo.player.http
+
+import retrofit2.http.Body
+import retrofit2.http.Field
+import retrofit2.http.POST
+
+interface CourseApi {
+    @POST("aiCourse/collect")
+    suspend fun favoriteCourse(
+        @Body data:Map<String,String>
+    ): HttpResult<Int>
+}

+ 36 - 0
ui/src/main/kotlin/com/tencent/liteav/demo/player/http/HttpManager.kt

@@ -0,0 +1,36 @@
+package com.tencent.liteav.demo.player.http
+
+import okhttp3.OkHttpClient
+import okhttp3.logging.HttpLoggingInterceptor
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+import java.util.concurrent.TimeUnit
+
+object HttpManager {
+    private const val GITHUB_GRAPHQL_API = "https://open.api.luojigou.vip/app/"
+    private const val TIMEOUT: Long = 30 * 1000
+
+    private val okHttpClient by lazy {
+        OkHttpClient.Builder()
+            .connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
+            .readTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
+            .writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
+            .addInterceptor(HttpLoggingInterceptor().apply {
+                level = HttpLoggingInterceptor.Level.BODY
+            })
+            .addInterceptor(AuthorizationInterceptor())
+            .build()
+    }
+
+    private val retrofit by lazy {
+        Retrofit.Builder()
+            .client(okHttpClient)
+            .baseUrl(GITHUB_GRAPHQL_API)
+            .addConverterFactory(GsonConverterFactory.create())
+            .build()
+    }
+
+    fun <T> create(service: Class<T>): T = retrofit.create(service)
+
+    inline fun <reified T> create(): T = create(T::class.java)
+}

+ 7 - 0
ui/src/main/kotlin/com/tencent/liteav/demo/player/http/HttpResult.kt

@@ -0,0 +1,7 @@
+package com.tencent.liteav.demo.player.http
+
+class HttpResult<T> {
+    var status = 500
+    var data: T? = null
+    var msg: String? = null
+}

+ 4 - 4
ui/src/main/kotlin/com/tencent/liteav/demo/player/menu/PlayerTimer.kt

@@ -59,16 +59,16 @@ class PlayerTimer : AppCompatActivity(), View.OnClickListener {
                 TimersUtil.sendNewTimer(1, 3)
             }
             dt10.id -> {
-                TimersUtil.sendNewTimer(2, 10)
+                TimersUtil.sendNewTimer(2, 10 * 60)
             }
             dt20.id -> {
-                TimersUtil.sendNewTimer(2, 20)
+                TimersUtil.sendNewTimer(2, 20 * 60)
             }
             dt30.id -> {
-                TimersUtil.sendNewTimer(2, 30)
+                TimersUtil.sendNewTimer(2, 30 * 60)
             }
             custom.id -> {
-                TimersUtil.sendNewTimer(2, 100)
+                TimersUtil.sendNewTimer(2, 100 * 60)
             }
         }
 

+ 19 - 2
ui/src/main/kotlin/com/tencent/liteav/demo/player/viewmodel/PlayerViewModel.kt

@@ -25,7 +25,7 @@ class PlayerViewModel(
     HistoryUtil.Listener,
     PlayerUtil.Listener {
     companion object {
-         val TAG = PlayerViewModel::class.java.simpleName.toString()
+        val TAG = PlayerViewModel::class.java.simpleName.toString()
     }
 
     init {
@@ -71,9 +71,25 @@ class PlayerViewModel(
             countDown = special
         }
 
+        resetCountDown()
         setCountDown(countDown, false)
     }
 
+    private fun resetCountDown() {
+        if (countDown.type == CountDown.TYPE_DURATION) {
+            if (countDown.rest > 0) {
+                val current = SimpleDateFormat("yyyy-MM-dd").format(Date())
+
+                if (countDown.datetime != current) {
+                    countDown = countDown.copyWith(
+                        rest = countDown.value
+                    )
+                    saveCountDown(countDown)
+                }
+            }
+        }
+    }
+
     /* 开启定时器 */
     private fun setCountDown(countDown: CountDown, forceSend: Boolean) {
         if (countDown.type == CountDown.TYPE_DURATION) {
@@ -141,6 +157,7 @@ class PlayerViewModel(
     override fun onTimeout(util: CountDownUtil?) {
         util?.pause()
         sendTimeout(true)
+        onStop()
     }
 
 
@@ -176,7 +193,7 @@ class PlayerViewModel(
     fun onStop() {
         Log.d(TAG, "onExit")
 
-        if(countDown.type == CountDown.TYPE_DURATION) {
+        if (countDown.type == CountDown.TYPE_DURATION) {
             val rest = countDown.rest - CountDownUtil.getInstance().count
             countDown = countDown.copyWith(rest = rest.toInt())
             saveCountDown(countDown)

BIN
ui/src/main/res/mipmap-hdpi/item_favorited.png


BIN
ui/src/main/res/mipmap-mdpi/item_favorited.png


BIN
ui/src/main/res/mipmap-xhdpi/item_favorited.png


BIN
ui/src/main/res/mipmap-xxhdpi/item_favorited.png


BIN
ui/src/main/res/mipmap-xxxhdpi/item_favorited.png