Merge branch 'dev_robotaxi-d_231206_6.2.4_video_refactor' into 'dev_robotaxi-p_231219_5.2.5'

Dev robotaxi d 231206 6.2.4 video refactor

See merge request SCA/L4HA/AndroidApp/MoGoEagleEye!847
This commit is contained in:
aibingbing
2023-12-20 11:02:12 +00:00
44 changed files with 2349 additions and 2144 deletions

View File

@@ -1,7 +1,6 @@
package com.mogo.och.bus.passenger;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS_P;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_TAXI_P;
import android.content.Context;
@@ -17,7 +16,7 @@ import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.util.MultiDisplayUtils;
import com.mogo.och.bus.passenger.constant.BusPassengerConst;
import com.mogo.och.bus.passenger.ui.BusPassengerRouteFragment;
import com.mogo.och.common.module.wigets.video.VideoPlayerActivity;
import com.mogo.och.common.module.wigets.media.MediaPlayerActivity;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -48,7 +47,7 @@ public class MogoOCHBusPassenger implements IMogoOCH {
showFragment();
if (AppIdentityModeUtils.isJL(FunctionBuildConfig.appIdentityMode) && activity != null) {
MultiDisplayUtils.INSTANCE.startActWithSecond(activity, VideoPlayerActivity.class);
MultiDisplayUtils.INSTANCE.startActWithSecond(activity, MediaPlayerActivity.class);
}
return null;

View File

@@ -2,16 +2,19 @@ package com.mogo.och.charter.passenger.bean;
public class TaxiPassengerVideoPlay {
public TaxiPassengerVideoPlay(String url, String imageUrl, String title) {
public TaxiPassengerVideoPlay(String url, String imageUrl, String title, int type) {
this.url = url;
this.imageUrl = imageUrl;
this.title = title;
this.type = type;
}
private String url;
private String imageUrl;
private String title;
private int type;
public String getTitle() {
return title;
}
@@ -35,4 +38,12 @@ public class TaxiPassengerVideoPlay {
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}

View File

@@ -490,5 +490,9 @@ class ConsultVideoPlayer : StandardGSYVideoPlayer {
fun getVideoAllCallBack(): VideoAllCallBack? {
return mVideoAllCallBack
}
fun showOrHideStartPlayButton(isShow: Boolean) {
aivStartPlay?.visibility = if (isShow ) View.VISIBLE else View.GONE
}
}

View File

@@ -5,12 +5,26 @@ import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.main.MainMoGoApplication
import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.charter.passenger.R
import com.mogo.och.charter.passenger.bean.TaxiPassengerVideoPlay
import com.mogo.och.charter.passenger.callback.IClearViewCallback
import com.mogo.och.charter.passenger.ui.softcontrol.layoutmanage.CarouselLayoutManager
import com.mogo.och.charter.passenger.ui.softcontrol.layoutmanage.CarouselZoomPostLayoutListener
import com.mogo.och.charter.passenger.ui.softcontrol.layoutmanage.CenterScrollListener
import com.mogo.och.charter.passenger.ui.video.adapter.RecyclerVideoAdapter
import com.mogo.och.common.module.wigets.media.IMediaDataSourceListener
import com.mogo.och.common.module.wigets.media.MediaDataSourceManager
import com.mogo.och.common.module.wigets.media.MediaFileCacheManager
import com.mogo.och.common.module.wigets.media.MediaItem
import com.mogo.och.common.module.wigets.media.MediaPlayLogger
import com.shuyu.gsyvideoplayer.video.base.GSYVideoView
import kotlinx.android.synthetic.main.charter_p_video_fragment.view.rvVideoPlaylist
import kotlin.math.floor
@@ -22,27 +36,32 @@ class VideoView @JvmOverloads constructor(
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoAutopilotStatusListener {
companion object {
const val TAG = "DebugView"
const val TAG = "VideoView"
}
private val arrayListOf = ArrayList<com.mogo.och.charter.passenger.bean.TaxiPassengerVideoPlay>()
var goneViewListener: IClearViewCallback? = null
private val mediaList = mutableListOf<TaxiPassengerVideoPlay>()
//新的数据在view不展示的时候完成新数据更新
private val mNewMediaList = mutableListOf<TaxiPassengerVideoPlay>()
init {
LayoutInflater.from(context).inflate(R.layout.charter_p_video_fragment, this, true)
onClick {
goneViewListener?.goneAllView()
}
initConsultData()
initView()
}
private fun initView() {
val carouselLayoutManager =
com.mogo.och.charter.passenger.ui.softcontrol.layoutmanage.CarouselLayoutManager(
CarouselLayoutManager(
CarouselLayoutManager.HORIZONTAL,
true
)
carouselLayoutManager.setPostLayoutListener(com.mogo.och.charter.passenger.ui.softcontrol.layoutmanage.CarouselZoomPostLayoutListener())
carouselLayoutManager.setPostLayoutListener(CarouselZoomPostLayoutListener())
carouselLayoutManager.maxVisibleItems = 1
rvVideoPlaylist.addOnScrollListener(object : com.mogo.och.charter.passenger.ui.softcontrol.layoutmanage.CenterScrollListener() {
rvVideoPlaylist.addOnScrollListener(object : CenterScrollListener() {
var prePlayerPosition = 0
override fun pageSelect(recyclerView: RecyclerView?, newState: Int) {
//播放视频
@@ -62,6 +81,7 @@ class VideoView @JvmOverloads constructor(
}
}
prePlayerPosition = centerItemPosition
MediaPlayLogger.printInfoLog("pageSelect, currentPosition=$prePlayerPosition")
}
override fun pageStop() {
@@ -70,7 +90,6 @@ class VideoView @JvmOverloads constructor(
player.onVideoPause()
}
}
})
carouselLayoutManager.addOnDargAutoDiffListener { adapterPosition, currentPosition ->
val fl = adapterPosition - floor(adapterPosition)
@@ -84,16 +103,16 @@ class VideoView @JvmOverloads constructor(
}
}
val recyclerVideoAdapter =
com.mogo.och.charter.passenger.ui.video.adapter.RecyclerVideoAdapter(
RecyclerVideoAdapter(
context,
arrayListOf,
mediaList,
rvVideoPlaylist
)
recyclerVideoAdapter.setOnThumbImageClilckListener {
val (_, player) = getPlayer(carouselLayoutManager)
if (player is ConsultVideoPlayer) {
player.onVideoReset()
player.thumbImageViewLayout.visibility = View.VISIBLE
player.thumbImageViewLayout.visibility = VISIBLE
}
rvVideoPlaylist?.smoothScrollToPosition(it)
}
@@ -104,7 +123,43 @@ class VideoView @JvmOverloads constructor(
override fun onAttachedToWindow() {
super.onAttachedToWindow()
MediaFileCacheManager.createFileCacheDir(MainMoGoApplication.getApp().applicationContext)
MediaDataSourceManager.init(TAG, object : IMediaDataSourceListener {
override fun onMediaDataSourceChanged(list: List<MediaItem>) {
val isNewData = mediaList.isNotEmpty()
MediaPlayLogger.printInfoLog("onMediaDataSourceChangedisNewData=$isNewData, dataSize=${list.size}, list=${GsonUtils.toJson(list)}")
val localMediaList = mutableListOf<TaxiPassengerVideoPlay>()
list.forEach {
val taxiPassengerVideoPlay = TaxiPassengerVideoPlay(
it.fileUrl,
it.coverImageUrl,
it.title,
it.fileType
)
localMediaList.add(taxiPassengerVideoPlay)
}
if (isNewData) {
if (!isVisible) {
updateMediaListDataAndView(localMediaList)
MediaPlayLogger.printInfoLog("onMediaDataSourceChanged, 宣传视频数据已更新")
} else {
mNewMediaList.clear()
mNewMediaList.addAll(localMediaList)
}
} else {
updateMediaListDataAndView(localMediaList)
MediaPlayLogger.printInfoLog("onMediaDataSourceChanged, 宣传视频数据已更新")
}
}
})
}
private fun updateMediaListDataAndView(newList: MutableList<TaxiPassengerVideoPlay>) {
mediaList.clear()
mediaList.addAll(newList)
UiThreadHandler.post {
initView()
}
}
private fun getPlayer(carouselLayoutManager: com.mogo.och.charter.passenger.ui.softcontrol.layoutmanage.CarouselLayoutManager): Pair<Int, ConsultVideoPlayer?> {
@@ -115,6 +170,7 @@ class VideoView @JvmOverloads constructor(
}
override fun onDetachedFromWindow() {
MediaDataSourceManager.unInit(TAG)
super.onDetachedFromWindow()
}
@@ -133,40 +189,17 @@ class VideoView @JvmOverloads constructor(
player.onVideoReset()
}
}
try {
// 在播放完成的时机更新整体数据
if (mNewMediaList.isNotEmpty()) {
updateMediaListDataAndView(mNewMediaList)
mNewMediaList.clear()
MediaPlayLogger.printInfoLog("onVisibilityChanged, 宣传视频数据已更新")
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
private fun initConsultData() {
arrayListOf.clear()
arrayListOf.add(
com.mogo.och.charter.passenger.bean.TaxiPassengerVideoPlay(
"https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708596763/全车型混剪增加红旗车队.m4v",
"https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969511280/车队.png",
"蘑菇车联覆盖生活的方方面面"
)
)
arrayListOf.add(
com.mogo.och.charter.passenger.bean.TaxiPassengerVideoPlay(
"https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708554279/红旗车队.m4v",
"https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969553174/红旗重新排版.png",
"蘑菇车联之红旗车队"
)
)
arrayListOf.add(
com.mogo.och.charter.passenger.bean.TaxiPassengerVideoPlay(
"https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708499497/大运会合作解说版.m4v",
"https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969536177/大运会.png",
"蘑菇车联牵手成都大运会"
)
)
arrayListOf.add(
com.mogo.och.charter.passenger.bean.TaxiPassengerVideoPlay(
"https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708409810/20210610重新排版3屏.m4v",
"https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969579713/三屏.png",
"多视角体验蘑菇车联自动驾驶"
)
)
}
}

View File

@@ -10,6 +10,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.mogo.och.common.module.wigets.media.MediaItem;
import com.mogo.och.common.module.wigets.toast.ToastCharterUtils;
import com.mogo.och.charter.passenger.R;
import com.mogo.och.charter.passenger.bean.TaxiPassengerVideoPlay;
@@ -62,27 +63,40 @@ public class RecyclerVideoAdapter extends RecyclerView.Adapter<RecyclerItemVideo
@Override
public void onBindViewHolder(@NonNull final RecyclerItemVideoHolder holder, int position) {
final TaxiPassengerVideoPlay taxiPassengerVideoPlay = itemDataList.get(position);
boolean isVideo = taxiPassengerVideoPlay.getType() == MediaItem.MEDIA_TYPE_VIDEO;
AutoSizeCompat.autoConvertDensityOfGlobal(holder.itemView.getResources());
holder.gsyVideoOptionBuilder
.setEnlargeImageRes(R.drawable.charter_p_change_full)
.setUrl(taxiPassengerVideoPlay.getUrl())
.setCacheWithPlay(true)
.setPlayTag(taxiPassengerVideoPlay.getImageUrl()+position)
.setPlayTag(taxiPassengerVideoPlay.getUrl()+position)
.setThumbPlay(false)
.setStartAfterPrepared(isVideo ? true : false)
.build(holder.gsyVideoPlayer);
holder.gsyVideoPlayer.getTitleTextView().setText(taxiPassengerVideoPlay.getTitle());
String imageUrl;
if (isVideo) {
imageUrl = taxiPassengerVideoPlay.getImageUrl();
} else {
imageUrl = taxiPassengerVideoPlay.getUrl();
}
Glide.with(context)
.load(taxiPassengerVideoPlay.getImageUrl())
.load(imageUrl)
.apply(new RequestOptions().placeholder(R.drawable.charter_p_video_holder).centerCrop())
.into(holder.gsyVideoPlayer.coverImage);
holder.gsyVideoPlayer.getThumbImageViewLayout().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(onThumbImageClilckListener!=null){
holder.gsyVideoPlayer.getTitleTextView().setText(taxiPassengerVideoPlay.getTitle());
holder.gsyVideoPlayer.getFullscreenButton().setVisibility(isVideo ? View.VISIBLE : View.INVISIBLE);
holder.gsyVideoPlayer.getStartButton().setVisibility(isVideo ? View.VISIBLE : View.INVISIBLE);
holder.gsyVideoPlayer.showOrHideStartPlayButton(isVideo ? true : false);
if (isVideo) {
holder.gsyVideoPlayer.getThumbImageViewLayout().setOnClickListener(v -> {
if (onThumbImageClilckListener != null) {
onThumbImageClilckListener.onDxChanged(holder.getAbsoluteAdapterPosition());
}
}
});
});
} else {
holder.gsyVideoPlayer.getThumbImageViewLayout().setOnClickListener(null);
}
holder.gsyVideoPlayer.setVideoAllCallBack(new GSYSampleCallBack(){
@Override
public void onAutoComplete(String url, Object... objects) {

View File

@@ -3,11 +3,10 @@
<application>
<activity
android:name=".wigets.video.VideoPlayerActivity"
android:name=".wigets.media.MediaPlayerActivity"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize"
android:enabled="true"
android:exported="true"
android:process=":video_ad"
android:resizeableActivity="false"
android:resumeWhilePausing="true"
android:screenOrientation="landscape"

View File

@@ -19,6 +19,12 @@ class OchCommonConst {
fun getSweeperUrl(): String {
return FunctionBuildConfig.urlJson.sweeperUrl
}
@JvmStatic
fun getEagleMisUrl(): String {
return FunctionBuildConfig.urlJson.eagleMisUrl
}
// token 失效 重新获取token
const val WAIT_TAKEN = 100046

View File

@@ -0,0 +1,178 @@
package com.mogo.och.common.module.utils;
import android.content.Context;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import java.io.File;
/**
* @authorliuhai
* @date2017/10/14 14:47
* @modifierubt
* @modify_date2017/10/14 14:47
* 文件缓存存储
* version
*/
public class FileUtils {
/**
* 获取应用专属缓存目录
* android 4.4及以上系统不需要申请SD卡读写权限
* 因此也不用考虑6.0系统动态申请SD卡读写权限问题切随应用被卸载后自动清空 不会污染用户存储空间
*
* @param context 上下文
* @param type 文件夹类型 可以为空为空则返回API得到的一级目录
* @return 缓存文件夹 如果没有SD卡或SD卡有问题则返回内存缓存目录否则优先返回SD卡缓存目录
*/
public static String getCacheDirectory(Context context, String type) {
File appCacheDir = getExternalCacheDirectory(context, type);
if (appCacheDir == null) {
appCacheDir = getInternalCacheDirectory(context, type);
}
if (appCacheDir == null) {
Log.e("FileUtils", "getCacheDirectory fail ,the reason is mobile phone unknown exception !");
} else {
if (!appCacheDir.exists() && !appCacheDir.mkdirs()) {
Log.e("FileUtils", "getCacheDirectory fail ,the reason is make directory fail !");
}
}
Log.d("FileUtils", "appCacheDir===" + appCacheDir.getPath() + File.separator);
return appCacheDir.getPath() + File.separator;
}
/**
* 获取SD卡缓存目录
*
* @param context 上下文
* @param type 文件夹类型 如果为空则返回 /storage/emulated/0/Android/data/app_package_name/cache
* 否则返回对应类型的文件夹如Environment.DIRECTORY_PICTURES 对应的文件夹为 .../data/app_package_name/files/Pictures
* {@link android.os.Environment#DIRECTORY_MUSIC},
* {@link android.os.Environment#DIRECTORY_PODCASTS},
* {@link android.os.Environment#DIRECTORY_RINGTONES},
* {@link android.os.Environment#DIRECTORY_ALARMS},
* {@link android.os.Environment#DIRECTORY_NOTIFICATIONS},
* {@link android.os.Environment#DIRECTORY_PICTURES}, or
* {@link android.os.Environment#DIRECTORY_MOVIES}.or 自定义文件夹名称
* @return 缓存目录文件夹 或 null无SD卡或SD卡挂载失败
*/
public static File getExternalCacheDirectory(Context context, String type) {
File appCacheDir = null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
if (TextUtils.isEmpty(type)) {
appCacheDir = context.getExternalCacheDir();
} else {
appCacheDir = context.getExternalFilesDir(type);
}
if (appCacheDir == null) {// 有些手机需要通过自定义目录
appCacheDir = new File(Environment.getExternalStorageDirectory(), "Android/data/" + context.getPackageName() + "/cache/" + type);
}
if (appCacheDir == null) {
Log.e("FileUtils", "getExternalDirectory fail ,the reason is sdCard unknown exception !");
} else {
if (!appCacheDir.exists() && !appCacheDir.mkdirs()) {
Log.e("FileUtils", "getExternalDirectory fail ,the reason is make directory fail !");
}
}
} else {
Log.e("FileUtils", "getExternalDirectory fail ,the reason is sdCard nonexistence or sdCard mount fail !");
}
return appCacheDir;
}
/**
* 获取内存缓存目录
*
* @param type 子目录,可以为空,为空直接返回一级目录
* @return 缓存目录文件夹 或 null创建目录文件失败
* 注:该方法获取的目录是能供当前应用自己使用,外部应用没有读写权限,如 系统相机应用
*/
public static File getInternalCacheDirectory(Context context, String type) {
File appCacheDir = null;
if (TextUtils.isEmpty(type)) {
appCacheDir = context.getCacheDir();// /data/data/app_package_name/cache
} else {
appCacheDir = new File(context.getFilesDir(), type);// /data/data/app_package_name/files/type
}
if (!appCacheDir.exists() && !appCacheDir.mkdirs()) {
Log.e("FileUtils", "getInternalDirectory fail ,the reason is make directory fail !");
}
return appCacheDir;
}
/**
* 删除缓存文件
*
* @param context
* @param fileName 视频文件名称
*/
public static void clearCacheFile(Context context, String fileName) {
String filepath = getCacheDirectory(context, "");
File file = new File(filepath + fileName);
if (file.exists()) {
file.delete();
}
}
private static final int NOT_FOUND = -1;
/**
* The Unix separator character.
*/
private static final char UNIX_NAME_SEPARATOR = '/';
/**
* The Windows separator character.
*/
private static final char WINDOWS_NAME_SEPARATOR = '\\';
/**
* The extension separator character.
*
* @since 1.4
*/
public static final char EXTENSION_SEPARATOR = '.';
public static String getExtension(final String filename) {
if (filename == null) {
return null;
}
final int index = indexOfExtension(filename);
if (index == NOT_FOUND) {
return "";
} else {
return filename.substring(index + 1);
}
}
public static int indexOfExtension(final String filename) {
if (filename == null) {
return NOT_FOUND;
}
final int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR);//点的位置
final int lastSeparator = indexOfLastSeparator(filename);//最后一个斜杠的位置
return lastSeparator > extensionPos ? NOT_FOUND : extensionPos;
}
public static int indexOfLastSeparator(final String filename) {
if (filename == null) {
return NOT_FOUND;
}
final int lastUnixPos = filename.lastIndexOf(UNIX_NAME_SEPARATOR);//unix的/
final int lastWindowsPos = filename.lastIndexOf(WINDOWS_NAME_SEPARATOR);// windows的\
return Math.max(lastUnixPos, lastWindowsPos);
}
public static void main(String[] args) {
String url = "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357834634/5.m4v";
String[] fileName = url.split("/");
String fileSuffix = getExtension(fileName[fileName.length - 1]);
System.out.println(fileSuffix);
}
}

View File

@@ -0,0 +1,23 @@
package com.mogo.och.common.module.wigets.media
data class MediaDataList(val medias: MutableList<MediaItem>)
data class MediaItem(
var fileUrl: String,
var fileType: Int,
var coverImageUrl: String,
var title: String
) {
companion object {
const val MEDIA_TYPE_IMAGE = 1
const val MEDIA_TYPE_VIDEO = 2
}
fun isImageType(): Boolean {
return this.fileType == MEDIA_TYPE_IMAGE
}
fun isVideoType(): Boolean {
return this.fileType == MEDIA_TYPE_VIDEO
}
}

View File

@@ -0,0 +1,278 @@
package com.mogo.och.common.module.wigets.media
import android.annotation.SuppressLint
import android.content.Context
import android.text.TextUtils
import com.google.gson.reflect.TypeToken
import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.debug.DebugConfig
import com.mogo.eagle.core.data.BaseData
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.function.call.telematic.CallerTelematicManager
import com.mogo.eagle.core.network.MoGoRetrofitFactory
import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.mogo.eagle.core.utilcode.util.NetworkUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.common.module.biz.constant.OchCommonConst
import com.mogo.och.common.module.biz.network.OchCommonServiceCallback
import com.mogo.och.common.module.biz.network.OchCommonSubscribeImpl
import com.mogo.och.common.module.biz.network.interceptor.transformTry
import com.mogo.och.common.module.wigets.media.MediaItem.Companion.MEDIA_TYPE_IMAGE
import com.mogo.och.common.module.wigets.media.MediaItem.Companion.MEDIA_TYPE_VIDEO
import io.reactivex.Observable
import retrofit2.http.GET
import retrofit2.http.Headers
import retrofit2.http.Query
import java.util.concurrent.ConcurrentHashMap
/**
* 广告视频数据源 管理类
* 1.第一优先级:从管理后台拿对应车型的宣传视频
* 如果无网络或无司机SN或请求异常 失败5次后立马使用第二优先级本地数据播放
* 失败尝试时间间隔1秒
* 2.第二优先级:使用本地数据播放
* 3.请求管理后台数据成功后间隔5分钟再次检查
*/
object MediaDataSourceManager {
private val TAG = MediaDataSourceManager::class.java.simpleName
private const val RETRY_MAX_COUNT = 5
private var mRetryCount = 0
private val mNetworkService: IMediaNetworkApi =
MoGoRetrofitFactory.getInstance(OchCommonConst.getEagleMisUrl())
.create(IMediaNetworkApi::class.java)
private var driverSnCache = ""
private val driverSn: String
get() {
val serverToken = CallerTelematicManager.getServerToken()
if (serverToken != driverSnCache && serverToken.isNotEmpty()) {
driverSnCache = serverToken
}
return driverSnCache
}
val context: Context
get() {
return AbsMogoApplication.getApp()
}
private val mLastMediaDataSourceList = mutableListOf<MediaItem>()
private var mHasEverGetMediaDataFromMis = false
private val mMediaDataSourceListenerMap: ConcurrentHashMap<String, IMediaDataSourceListener> =
ConcurrentHashMap()
private val getAdDataSourceLoopRunnable = Runnable {
startGetMediaDataSourceLoop()
}
fun init(tag: String, dataSourceListener: IMediaDataSourceListener) {
if (!mMediaDataSourceListenerMap.containsKey(tag)) {
mMediaDataSourceListenerMap[tag] = dataSourceListener
}
val isSassProject = isSassProject()
MediaPlayLogger.printInfoLog("init, 初始化环境 isSassProject=$isSassProject")
if (isSassProject) {
MediaPlayLogger.printInfoLog("init, 开始检查后台配置数据")
startGetMediaDataSourceLoop()
} else {
MediaPlayLogger.printInfoLog("init, 使用本地配置数据初始化")
//非Sass环境下后端没有实现可配置默认只走本地配置
val localAdDataList = getMediaDataFromLocalConfig()
updateMediaDataSource(localAdDataList)
}
}
fun unInit(tag: String) {
MediaPlayLogger.printInfoLog("unInit")
removeGetMediaDataSourceLoop()
if (mMediaDataSourceListenerMap.containsKey(tag)) {
mMediaDataSourceListenerMap.remove(tag)
}
}
/**
* 是否是Sass环境
*/
private fun isSassProject(): Boolean {
return DebugConfig.getProjectFlavor().lowercase().contains("saas")
}
@SuppressLint("MissingPermission")
private fun startGetMediaDataSourceLoop() {
MediaPlayLogger.printInfoLog("startGetMediaDataSourceLoop, 开始执行后台配置数据检查")
removeGetMediaDataSourceLoop()
// 失败5次且从来没有从MIS获取配置信息成功过先试用本地数据播放
if (mRetryCount == RETRY_MAX_COUNT && !mHasEverGetMediaDataFromMis) {
val localAdDataList = getMediaDataFromLocalConfig()
updateMediaDataSource(localAdDataList)
MediaPlayLogger.printErrorLog("startGetMediaDataSourceLoop失败${mRetryCount}次,先使用本地数据播放")
}
if (driverSn.isBlank()) {
MediaPlayLogger.printErrorLog("startGetMediaDataSourceLoop司机屏sn为空跳过本次查询")
mRetryCount++
UiThreadHandler.postDelayed(getAdDataSourceLoopRunnable, 1000L)
return
}
if (!NetworkUtils.isConnected()) {
MediaPlayLogger.printErrorLog("startGetMediaDataSourceLoop当前无网络跳过本次查询")
mRetryCount++
UiThreadHandler.postDelayed(getAdDataSourceLoopRunnable, 1000L)
return
}
getMediaDataFromMis(object : OchCommonServiceCallback<MediaDataResp> {
override fun onSuccess(data: MediaDataResp?) {
mHasEverGetMediaDataFromMis = true
MediaPlayLogger.printInfoLog(
"startGetMediaDataSourceLoopsuccess, 从管理后台获取到数据MediaSize=${data?.data?.size}, MediaData=${
GsonUtils.toJson(
data
)
}"
)
val newDataList = MediaDataResp.toMediaItemList(data?.data)
// 管理平台如果配置数据为空,不更新
if (newDataList.isNotEmpty()) {
if (compareMediaDataSource(newDataList)) {
updateMediaDataSource(newDataList)
MediaPlayLogger.printInfoLog("startGetMediaDataSourceLoopsuccess, 从管理后台获取到数据,数据有变化更新数据")
} else {
MediaPlayLogger.printInfoLog("startGetMediaDataSourceLoopsuccess, 从管理后台获取到数据,数据无变化无需更新")
}
} else {
//请求成功获取到后台配置数据了,但是数据为空,此时为了有内容展示,还是使用本地数据更新播放
if (mLastMediaDataSourceList.isEmpty()) {
val localAdDataList = getMediaDataFromLocalConfig()
updateMediaDataSource(localAdDataList)
MediaPlayLogger.printInfoLog("startGetMediaDataSourceLoopsuccess, 从管理后台获取到数据,返回数据为空,使用本地配置数据播放")
}
}
// 获取成功后延迟5分钟再查询
UiThreadHandler.postDelayed(getAdDataSourceLoopRunnable, 5 * 60 * 1000L)
MediaPlayLogger.printInfoLog("startGetMediaDataSourceLoopsuccess, 延迟5分钟后再次检查更新")
}
override fun onFail(code: Int, msg: String?) {
MediaPlayLogger.printErrorLog("startGetMediaDataSourceLoopfailed, code=$code, msg=$msg")
mRetryCount++
val delay = if (mHasEverGetMediaDataFromMis) 5000L else 1000L
UiThreadHandler.postDelayed(getAdDataSourceLoopRunnable, delay)
MediaPlayLogger.printErrorLog("startGetMediaDataSourceLoopfailed, 延迟${delay / 1000L}秒后再次请求")
}
override fun onError() {
super.onError()
MediaPlayLogger.printErrorLog("startGetMediaDataSourceLooperror, 网络异常")
mRetryCount++
val delay = if (mHasEverGetMediaDataFromMis) 5000L else 1000L
UiThreadHandler.postDelayed(getAdDataSourceLoopRunnable, delay)
MediaPlayLogger.printErrorLog("startGetMediaDataSourceLooperror, 网络异常,延迟${delay / 1000L}秒后再次请求")
}
})
}
private fun removeGetMediaDataSourceLoop() {
UiThreadHandler.removeCallbacks(getAdDataSourceLoopRunnable)
}
private fun getMediaDataFromMis(callback: OchCommonServiceCallback<MediaDataResp>) {
MediaPlayLogger.printInfoLog("getMediaDataFromMis准备发送请求driverSn=$driverSn")
mNetworkService.queryMediaDataFromMis(
sn = driverSn,
screenType = "2",
).transformTry().subscribe(OchCommonSubscribeImpl(context, callback, "getMediaDataFromMis"))
}
private fun getMediaDataFromLocalConfig(): List<MediaItem> {
val localAdDataList = mutableListOf<MediaItem>()
try {
val datas: MediaDataList = GsonUtils.fromJson(
FunctionBuildConfig.mediaUrlConfig, object : TypeToken<MediaDataList>() {}.type
)
localAdDataList.addAll(datas.medias)
} catch (e: Exception) {
e.printStackTrace()
}
MediaPlayLogger.printInfoLog("getMediaDataFromLocalConfig, 获取本地配置数据dataSize=${localAdDataList.size}")
return localAdDataList
}
private fun compareMediaDataSource(newDataList: List<MediaItem>): Boolean {
if (mLastMediaDataSourceList.isEmpty() && newDataList.isNotEmpty()) {
return true
}
if (mLastMediaDataSourceList.size != newDataList.size) {
return true
}
try {
newDataList.forEachIndexed { index, rotationItem ->
val oldIndexItem = mLastMediaDataSourceList[index]
if (rotationItem?.fileUrl != oldIndexItem?.fileUrl) {
return true
}
}
} catch (e: Exception) {
e.printStackTrace()
}
return false
}
private fun updateMediaDataSource(newDataList: List<MediaItem>) {
mLastMediaDataSourceList.clear()
mLastMediaDataSourceList.addAll(newDataList)
mMediaDataSourceListenerMap.forEach {
val listener = it.value
listener.onMediaDataSourceChanged(newDataList)
}
MediaPlayLogger.printInfoLog("下发新MediaData给监听者dataSize=${newDataList.size}")
}
}
interface IMediaDataSourceListener {
fun onMediaDataSourceChanged(list: List<MediaItem>)
}
interface IMediaNetworkApi {
@Headers("Content-type:application/json;charset=UTF-8")
@GET("/platform/biz/adv/screen/advs")
fun queryMediaDataFromMis(
@Query("sn") sn: String,
@Query("screenType") screenType: String
): Observable<MediaDataResp>
}
data class MediaData(
var id: String?,
var title: String?, //素材标题
var brand: String?,
var file_type: Int = 0, //素材类型: 1 - 视频,2 - 图片
var cover_path: String?, //封面图片, 适用 素材类型为视频
var file_path: String?, //素材url
var descr: String?, //素材描述
var apply_screen: Int = 0 //应用屏幕类型: 1司机屏幕 2乘客屏
)
data class MediaDataResp(val data: List<MediaData>) : BaseData() {
companion object {
fun toMediaItemList(mediaDataList: List<MediaData>?): List<MediaItem> {
val rotationItemList = mutableListOf<MediaItem>()
mediaDataList?.forEach {
val rotationItem = MediaItem(
fileUrl = if (TextUtils.isEmpty(it.file_path)) "" else "${it.file_path}",
fileType = if (it.file_type == 1) MEDIA_TYPE_VIDEO else MEDIA_TYPE_IMAGE,
coverImageUrl = if (TextUtils.isEmpty(it.cover_path)) "" else "${it.cover_path}",
title = if (TextUtils.isEmpty(it.title)) "" else "${it.title}"
)
rotationItemList.add(rotationItem)
}
return rotationItemList
}
}
}

View File

@@ -0,0 +1,88 @@
package com.mogo.och.common.module.wigets.media
import android.content.Context
import android.os.Environment
import android.text.TextUtils
import android.util.Log
import com.mogo.eagle.core.utilcode.download.DownloadUtils
import com.mogo.eagle.core.utilcode.download.callback.IDownloadListener
import com.mogo.eagle.core.utilcode.util.EncryptUtils
import com.mogo.och.common.module.utils.FileUtils
import java.io.File
/**
* 宣传视频文件本地缓存管理类
* 1, 统一了本地缓存文件的存放目录
* 2统一了本地缓存文件的命名md5编码
*/
object MediaFileCacheManager {
const val TAG = "MediaFileCacheManager"
/**
* 创建media缓存文件夹目录优先放SD卡
*/
fun createFileCacheDir(context: Context): Boolean {
val cacheDirPath = getFileCacheDir(context)
MediaPlayLogger.printInfoLog("createFileCacheDir dirPath=$cacheDirPath")
return com.mogo.eagle.core.utilcode.util.FileUtils.createFileDir(cacheDirPath)
}
/**
* 获取本地缓存文件的文件全路径
*/
private fun getFileCacheDir(context: Context): String {
// 有些手机需要通过自定义目录
val relativePath = "mogo" + File.separator + "media" + File.separator
val cacheDir = File(Environment.getExternalStorageDirectory(), relativePath)
if (com.mogo.eagle.core.utilcode.util.FileUtils.createOrExistsDir(cacheDir)) {
return cacheDir.absolutePath
}
return FileUtils.getCacheDirectory(context, "") + relativePath
}
/**
* 本地缓存文件的文件名md5编码避免文件名重复或者特殊字符编码问题
*/
fun getCacheFileName(mediaUrl: String): String {
val fileSuffix = FileUtils.getExtension(mediaUrl)
if (TextUtils.isEmpty(fileSuffix)) {
Log.e(TAG, "getCacheFileName 根据url获取文件后缀不合法mediaUrl=$mediaUrl")
return ""
}
return EncryptUtils.encryptMD5ToString(mediaUrl) + FileUtils.EXTENSION_SEPARATOR + fileSuffix
}
/**
* 获取文件缓存的缓存path, 文件名以base64编码避免 中文命名,重复文件名的影响
*/
fun getCacheFileFullPathByUrl(context: Context, mediaUrl: String): String {
return getFileCacheDir(context) + getCacheFileName(mediaUrl)
}
/**
* 本地是否已经存在下载完成的文件
*/
fun isLocalCacheFileExists(context: Context, mediaUrl: String): Boolean {
val localVideoCacheFilePath =
getCacheFileFullPathByUrl(context, mediaUrl)
return com.mogo.eagle.core.utilcode.util.FileUtils.isFileExists(localVideoCacheFilePath)
}
/**
* 下载文件
*/
fun downloadFile(context: Context, mediaUrl: String, listener: IDownloadListener) {
val downloadUrl = mediaUrl
val downloadDir = getFileCacheDir(context)
val downloadFileName = getCacheFileName(mediaUrl)
DownloadUtils.downLoad(
context,
downloadUrl,
downloadDir,
downloadFileName,
listener
)
}
}

View File

@@ -0,0 +1,311 @@
package com.mogo.och.common.module.wigets.media
import AdvanceImageView
import AdvanceVideoView
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.RelativeLayout
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.util.CountDownTimer
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.common.module.wigets.media.MediaLoopPlayView.Companion.IMAGE_COUNT_DOWN_SECONDS
import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
class MediaLoopPlayView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : RelativeLayout(context, attrs) {
companion object {
const val TAG = "MediaLoopPlayView"
const val IMAGE_COUNT_DOWN_SECONDS = 5
}
private var viewPager: AdvanceViewPager? = null
private var pagerAdapter: AdvancePagerAdapter? = null
init {
initView()
}
private fun initView() {
viewPager = AdvanceViewPager(context)
pagerAdapter = AdvancePagerAdapter(context, viewPager!!)
viewPager?.adapter = pagerAdapter
addView(viewPager, LayoutParams(-1, -1))
}
fun setMediaData(list: MutableList<MediaItem>) {
pagerAdapter?.setMediaData(list)
}
fun setNewMediaData(list: MutableList<MediaItem>) {
pagerAdapter?.setNewMediaData(list)
}
fun setPause() {
pagerAdapter?.setPause()
}
fun setResume() {
pagerAdapter?.setResume()
}
}
class AdvanceViewPager : ViewPager {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
override fun onTouchEvent(ev: MotionEvent?): Boolean {
return false
}
override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
return false
}
}
class AdvancePagerAdapter(context: Context, viewPager: ViewPager) : PagerAdapter(),
ViewPager.OnPageChangeListener {
private val mContext: Context = context
private val mViewPager: ViewPager = viewPager
private var mDataList = mutableListOf<MediaItem>()
private var mItemViewList = mutableListOf<View>()
//新的数据,在轮播下一次切换的时机完成整体数据的更新
private val mNewDataList: MutableList<MediaItem> = mutableListOf()
private var mLastViewPagerPosition = -1
private var mImageCountDownTimer: CountDownTimer? = null
fun setMediaData(list: MutableList<MediaItem>) {
if (list.isEmpty()) {
MediaPlayLogger.printInfoLog( "setMediaData, list为空")
return
}
mDataList.clear()
mDataList.addAll(list)
mItemViewList.clear()
list.forEach {
addItemView(it)
}
mViewPager.addOnPageChangeListener(this)
notifyDataSetChanged()
mViewPager.currentItem = 0
if (mItemViewList.size > 0) {
startLoopPlay()
}
}
fun setNewMediaData(list: MutableList<MediaItem>) {
mNewDataList.clear()
mNewDataList.addAll(list)
}
override fun getCount(): Int {
return mDataList.size
}
override fun isViewFromObject(view: View, `object`: Any): Boolean {
return view === `object`
}
override fun destroyItem(container: ViewGroup, position: Int, obj: Any) {
try {
container.removeView(obj as View)
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val view: View = mItemViewList[position]
container.addView(view)
return view
}
override fun getItemPosition(`object`: Any): Int {
return POSITION_NONE
}
private fun addItemView(item: MediaItem) {
if (item.isImageType()) {
val imageView = AdvanceImageView(mContext)
imageView.initImageUrlData(item.fileUrl)
mItemViewList.add(imageView)
} else if (item.isVideoType()) {
val videoView = AdvanceVideoView(mContext)
videoView.initVideoUrlData(item.fileUrl, item.coverImageUrl)
mItemViewList.add(videoView)
} else {
MediaPlayLogger.printErrorLog( "addItemView 不支持的文件类型:${item.fileType}")
}
}
/**
* 开始播放循环
* 1.如果是视频开始播放视频等到播放完成后根据media类型开始播放下一个
* 2.如果是图片展示图片同时开始timer倒计时倒计时完时根据media类型开始播放下一个
*/
private fun startLoopPlay() {
val currentPosition = mViewPager.currentItem
val currentMediaItem = mDataList[currentPosition]
if (mItemViewList[currentPosition] is AdvanceVideoView) {
MediaPlayLogger.printInfoLog("startLoopPlay: AdvanceVideoView, url=${currentMediaItem.fileUrl}")
val videoView = mItemViewList[currentPosition] as AdvanceVideoView
videoView.setThumbImageViewVisible()
videoView.startPlayVideo(videoPlayLifecycleCallBack)
} else if (mItemViewList[currentPosition] is AdvanceImageView) {
MediaPlayLogger.printInfoLog("startLoopPlay: AdvanceImageView, url=${currentMediaItem.fileUrl}")
val imageView = mItemViewList[currentPosition] as AdvanceImageView
imageView.displayImage()
startImageCountDownTimer()
} else {
MediaPlayLogger.printErrorLog("startLoopPlay 不支持的文件类型:${currentMediaItem.fileType}, url=${currentMediaItem.fileUrl}")
}
}
private var videoPlayLifecycleCallBack = object : GSYSampleCallBack() {
override fun onPrepared(url: String?, vararg objects: Any?) {
CallerLogger.d(MediaLoopPlayView.TAG, "onPrepared")
}
override fun onAutoComplete(url: String?, vararg objects: Any?) {
CallerLogger.d(MediaLoopPlayView.TAG, "onAutoComplete")
playNextItemView(false)
}
override fun onPlayError(url: String?, vararg objects: Any?) {
super.onPlayError(url, *objects)
CallerLogger.d(MediaLoopPlayView.TAG, "onPlayError, error=${objects}")
playNextItemView(true)
}
}
private fun startImageCountDownTimer() {
if (mImageCountDownTimer != null) {
mImageCountDownTimer?.cancel()
mImageCountDownTimer = null
}
mImageCountDownTimer = object : CountDownTimer(IMAGE_COUNT_DOWN_SECONDS * 1000L, 1000L) {
override fun onTick(millisUntilFinished: Long) {
CallerLogger.d(
MediaLoopPlayView.TAG,
"mImageCountDownTimer倒计时秒, countDown=${millisUntilFinished / 1000}"
)
}
override fun onFinish() {
MediaPlayLogger.printInfoLog( "mImageCountDownTimer, 倒计时${IMAGE_COUNT_DOWN_SECONDS}秒, onFinish")
playNextItemView(false)
}
}.start()
MediaPlayLogger.printInfoLog("mImageCountDownTimer, 开始倒计时 ${IMAGE_COUNT_DOWN_SECONDS}")
}
private fun cancelImageCountDownTimer() {
if (mImageCountDownTimer != null) {
mImageCountDownTimer?.cancel()
mImageCountDownTimer = null
}
}
/**
* 根据当前item情况播放下一个item
*/
private fun playNextItemView(isOnVideoError: Boolean) {
// 在播放完成的时机更新整体数据
if (mNewDataList.isNotEmpty()) {
setMediaData(mNewDataList)
mNewDataList.clear()
ToastUtils.showShort("宣传视频数据已更新")
MediaPlayLogger.printInfoLog("playNextItemView, 宣传视频数据已更新")
return
}
MediaPlayLogger.printInfoLog("playNextItemView")
val currentPosition = mViewPager.currentItem
val currentMediaItem = mDataList[currentPosition]
val currentItemView = mItemViewList[currentPosition]
MediaPlayLogger.printInfoLog("playNextItemView, currentPosition=$currentPosition, type=${currentMediaItem.fileType}, url=${currentMediaItem.fileUrl}")
if (currentItemView is AdvanceVideoView) {
currentItemView.onVideoReset()
//videoView.setCacheImageViewVisible()
if (isOnVideoError) {
currentItemView.clearLocalErrorVideo()
}
if (mItemViewList.size == 1) {
currentItemView.startPlay(currentMediaItem.fileUrl)
return
}
}
if (currentPosition == mItemViewList.size - 1) {
//已经到最后一个, 从头开始
mViewPager.post {
mViewPager.setCurrentItem(0, true)
}
} else {
mViewPager.post {
mViewPager.setCurrentItem(mViewPager.currentItem + 1, true)
}
}
}
fun setPause() {
MediaPlayLogger.printInfoLog("${MediaLoopPlayView.TAG}, setPause")
if (mItemViewList.size <= 0) {
return
}
val currentPosition = mViewPager.currentItem
if (mItemViewList[currentPosition] is AdvanceVideoView) {
val videoView = mItemViewList[mViewPager.currentItem] as AdvanceVideoView
videoView.setVideoPause()
} else if (mItemViewList[currentPosition] is AdvanceImageView) {
cancelImageCountDownTimer()
}
}
fun setResume() {
MediaPlayLogger.printInfoLog("${MediaLoopPlayView.TAG}, setResume")
if (mItemViewList.size <= 0) {
return
}
val currentPosition = mViewPager.currentItem
if (mItemViewList[currentPosition] is AdvanceVideoView) {
val videoView = mItemViewList[mViewPager.currentItem] as AdvanceVideoView
videoView.setVideoResume()
} else if (mItemViewList[currentPosition] is AdvanceImageView) {
startImageCountDownTimer()
}
}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
}
override fun onPageSelected(position: Int) {
}
override fun onPageScrollStateChanged(state: Int) {
if (state == 0) { //静止,什么都没做
val currentPosition = mViewPager.currentItem
CallerLogger.d(
MediaLoopPlayView.TAG,
"onPageScrollStateChanged, state = $state, currentItem = $currentPosition, lastPosition = $mLastViewPagerPosition"
)
if (mItemViewList.size > 1) { //多于1才会循环跳转
startLoopPlay()
mLastViewPagerPosition = currentPosition
}
}
}
}

View File

@@ -0,0 +1,44 @@
package com.mogo.och.common.module.wigets.media
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.mogo.commons.utils.MogoAnalyticUtils
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
object MediaPlayLogger {
const val TAG = "MediaPlayLogger"
private const val MEDIA_PLAY_PROCESS_KEY_NODE_LOG =
"och.media.play.process.key.node.log"
fun printInfoLog(msg: String) {
CallerLogger.i(TAG, msg)
trackEvent("Info", msg)
}
fun printWarnLog(msg: String) {
CallerLogger.w(TAG, msg)
trackEvent("Warn", msg)
}
fun printErrorLog(msg: String) {
CallerLogger.e(TAG, msg)
trackEvent("Error", msg)
}
/**
* 上报埋点
*/
private fun trackEvent(level: String, msg: String) {
ProcessLifecycleOwner.get().lifecycleScope.launch(Dispatchers.IO) {
val map: MutableMap<String, Any> = HashMap()
map["level"] = level
map["msg"] = msg
MogoAnalyticUtils.track(
MEDIA_PLAY_PROCESS_KEY_NODE_LOG,
map
)
}
}
}

View File

@@ -1,16 +1,16 @@
package com.mogo.och.common.module.wigets.video
package com.mogo.och.common.module.wigets.media
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.mogo.eagle.core.utilcode.util.BarUtils
import com.mogo.och.common.module.R
class VideoPlayerActivity : AppCompatActivity() {
class MediaPlayerActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_video_player)
val fragment = VideoPlayerFragment()
val fragment = MediaPlayerFragment()
supportFragmentManager.beginTransaction().add(R.id.videoPlayerContainer, fragment)
.commitAllowingStateLoss()
BarUtils.hideStatusBarAndSticky(this.window)

View File

@@ -0,0 +1,380 @@
import android.content.Context
import android.media.AudioManager
import android.net.Uri
import android.util.AttributeSet
import android.widget.ImageView
import android.widget.RelativeLayout
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.mogo.eagle.core.utilcode.download.callback.IDownloadListener
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.mogo.eagle.core.utilcode.util.FileUtils
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.eagle.core.widget.media.video.TextureVideoViewOutlineProvider
import com.mogo.och.common.module.R
import com.mogo.och.common.module.wigets.media.MediaFileCacheManager
import com.mogo.och.common.module.wigets.media.MediaLoopPlayView
import com.mogo.och.common.module.wigets.media.MediaPlayLogger
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
import com.shuyu.gsyvideoplayer.utils.GSYVideoType
import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
import me.jessyan.autosize.utils.AutoSizeUtils
import java.io.File
class AdvanceVideoView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : RelativeLayout(context, attrs) {
private var containerLayout: RelativeLayout? = null
private var thumbnailImageView: ImageView? = null
private var videoPlayerView: AdvanceGSYVideoPlayer? = null
private var gsyVideoPlayerOptionBuilder: GSYVideoOptionBuilder? = null
private var gsyVideoPlayerLifecycleCallback: GSYSampleCallBack? = null
private var thumbnailImageUrl: String = ""
private var videoUrl: String = ""
private val downListener = object : IDownloadListener {
override fun onStart(url: String) {
setThumbImageViewVisible()
Logger.d(MediaLoopPlayView.TAG, "video play download, onStart")
}
override fun onProgress(url: String, downloaded: Long, total: Long) {
val percent = (downloaded * 100 / total).toInt()
Logger.d(
MediaLoopPlayView.TAG,
"video play download, onProgress= ${percent}"
)
if (percent % 10 == 0) {
MediaPlayLogger.printInfoLog("downListenerpercent=$percent, downloadUrl=${videoUrl}")
}
}
override fun onFinished(url: String, path: String) {
Logger.d(MediaLoopPlayView.TAG, "video play download, onFinished = $url")
//发现下载工具在断网又连网后,已完成的任务又都下载,跳转播放出现问题
if (url == videoUrl) {
//下载完成
ThreadUtils.runOnUiThread {
startPlay(Uri.fromFile(File(path)).toString())
}
MediaPlayLogger.printInfoLog("download finished, 开始播放downloadUrl=${videoUrl}")
} else {//如果当前文件不存在再次去下载当前的
Logger.d(
MediaLoopPlayView.TAG,
"video play download, onFinished but not current url , currentUrl = $videoUrl"
)
if (FileUtils.isFileExists(path)) {
Logger.d(MediaLoopPlayView.TAG, "video play download, had download, startPlay")
ThreadUtils.runOnUiThread {
startPlay(Uri.fromFile(File(path)).toString())
}
MediaPlayLogger.printInfoLog("download finished, 开始播放downloadUrl=${videoUrl}")
} else {
startDownLoadVideoFile()
}
}
}
override fun onError(url: String, error: String?) {
Logger.d(MediaLoopPlayView.TAG, "video play download, onError msg=$error")
MediaPlayLogger.printErrorLog("download error, 准备重新下载downloadUrl=${videoUrl}")
//出错再次下载
startDownLoadVideoFile()
}
}
init {
initView()
}
private fun initView() {
//容器
containerLayout = RelativeLayout(context)
addView(containerLayout, LayoutParams(-1, -1))
//缩略图
thumbnailImageView = ImageView(context)
thumbnailImageView?.scaleType = ImageView.ScaleType.FIT_XY
//视频播放控件
if (videoPlayerView === null) {
videoPlayerView = AdvanceGSYVideoPlayer(context)
}
val videoPlayerViewLayoutParams = LayoutParams(-1, -1)
//设置videoview占满父view播放
videoPlayerViewLayoutParams.addRule(ALIGN_PARENT_LEFT)
videoPlayerViewLayoutParams.addRule(ALIGN_PARENT_RIGHT)
videoPlayerViewLayoutParams.addRule(ALIGN_PARENT_TOP)
videoPlayerViewLayoutParams.addRule(ALIGN_PARENT_BOTTOM)
containerLayout?.addView(videoPlayerView, videoPlayerViewLayoutParams)
}
/**
* 初始化数据
*/
fun initVideoUrlData(videoUrl: String, thumbnailImageUrl: String) {
// https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357834634/5.m4v
// https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360274126/10.mp4
this.videoUrl = videoUrl
this.thumbnailImageUrl = thumbnailImageUrl
}
/**
* 开始播放逻辑
*/
fun startPlayVideo(onCompletionListener: GSYSampleCallBack) {
//首先根据url检查video是否有已经下载完的本地视频文件
gsyVideoPlayerLifecycleCallback = onCompletionListener
if (MediaFileCacheManager.isLocalCacheFileExists(context, this.videoUrl)) {
val localVideoCacheFilePath = MediaFileCacheManager.getCacheFileFullPathByUrl(
context, this.videoUrl
)
MediaPlayLogger.printInfoLog("本地已经有缓存文件准备开始播放videoPath=${localVideoCacheFilePath}")
val realUri = Uri.fromFile(File(localVideoCacheFilePath)).toString()
setThumbImageViewGone()
startPlay(realUri)
CallerLogger.d(
MediaLoopPlayView.TAG, "播放视频videoUri=$realUri"
)
} else {
thumbnailImageView?.setImageResource(R.drawable.video_holder)
videoPlayerView?.thumbImageView = thumbnailImageView
thumbnailImageView?.also {
Glide.with(context).asBitmap().load(thumbnailImageUrl)
.apply(
RequestOptions().useUnlimitedSourceGeneratorsPool(true)
.placeholder(R.drawable.video_holder)
.error(R.drawable.video_holder)
.fallback(R.drawable.video_holder)
.centerCrop()
)
.into(it)
}
setThumbImageViewVisible()
startDownLoadVideoFile()
MediaPlayLogger.printInfoLog("本地无缓存文件准备下载downloadUrl=${this.videoUrl}")
}
}
fun setThumbImageViewVisible() {
UiThreadHandler.post {
videoPlayerView?.setCacheImageViewVisible()
}
}
private fun setThumbImageViewGone() {
UiThreadHandler.post {
videoPlayerView?.setCacheImageViewGone()
}
}
private fun startDownLoadVideoFile() {
//下载视频,下载成功后再播放
MediaPlayLogger.printInfoLog( "startDownLoadVideoFile, downloadUrl=${this.videoUrl}")
MediaFileCacheManager.downloadFile(
context,
videoUrl,
downListener
)
}
fun clearLocalErrorVideo() {
val localVideoPath = MediaFileCacheManager.getCacheFileFullPathByUrl(context, videoUrl)
if (FileUtils.isFileExists(localVideoPath)) {
FileUtils.delete(localVideoPath)
}
MediaPlayLogger.printInfoLog( "clearLocalErrorVideo, localPath=${localVideoPath}")
}
fun startPlay(localVideoPath: String?) {
try {
Logger.d(MediaLoopPlayView.TAG, "startPlay")
gsyVideoPlayerOptionBuilder = GSYVideoOptionBuilder()
gsyVideoPlayerOptionBuilder
?.setUrl(localVideoPath) // "/data/user/0/com.mogo.launcher.f/files/video/"
?.setPlayTag(MediaFileCacheManager.getCacheFileName(videoUrl))
?.setCacheWithPlay(false)
?.setThumbPlay(false)
?.build(videoPlayerView)
videoPlayerView?.isFocusableInTouchMode = false
videoPlayerView?.setVideoAllCallBack(gsyVideoPlayerLifecycleCallback)
videoPlayerView?.startPlayLogic()
} catch (e: Exception) {
Logger.e(MediaLoopPlayView.TAG, "startPlay error, msg=${e.message}")
}
}
fun onVideoReset() {
videoPlayerView?.onVideoReset()
gsyVideoPlayerLifecycleCallback = null
}
fun setVideoPause() {
videoPlayerView?.onVideoPause()
}
fun setVideoResume() {
videoPlayerView?.onVideoResume()
}
}
class AdvanceGSYVideoPlayer : StandardGSYVideoPlayer {
constructor(context: Context?) : super(context)
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
init {
hideWidget()
GSYVideoType.setShowType(GSYVideoType.SCREEN_MATCH_FULL)
GSYVideoType.setRenderType(GSYVideoType.GLSURFACE)
}
override fun hideAllWidget() {
Logger.d(MediaLoopPlayView.TAG, "AdvanceGSYVideoPlayerhideAllWidget")
}
override fun changeUiToNormal() {
Logger.d(MediaLoopPlayView.TAG, "AdvanceGSYVideoPlayerchangeUiToNormal-hide")
hideWidget()
}
override fun changeUiToPreparingShow() {
Logger.d(MediaLoopPlayView.TAG, "AdvanceGSYVideoPlayerchangeUiToPreparingShow-hide")
hideWidget()
}
override fun changeUiToPlayingShow() {
Logger.d(MediaLoopPlayView.TAG, "AdvanceGSYVideoPlayerchangeUiToPlayingShow")
setCacheImageViewGone()
}
override fun changeUiToPauseShow() {
Logger.d(MediaLoopPlayView.TAG, "AdvanceGSYVideoPlayerchangeUiToPauseShow-hide")
startPlayLogic()
}
override fun changeUiToCompleteShow() {
Logger.d(MediaLoopPlayView.TAG, "AdvanceGSYVideoPlayerchangeUiToCompleteShow")
setCacheImageViewGone()
}
override fun changeUiToPlayingBufferingShow() {
Logger.d(MediaLoopPlayView.TAG, "AdvanceGSYVideoPlayerchangeUiToPlayingBufferingShow")
hideWidget()
}
override fun changeUiToError() {
Logger.d(MediaLoopPlayView.TAG, "AdvanceGSYVideoPlayerchangeUiToError")
hideWidget()
}
private fun hideWidget() {
setViewShowState(mBottomContainer, INVISIBLE)
setViewShowState(mProgressBar, INVISIBLE)
setViewShowState(mCurrentTimeTextView, INVISIBLE)
setViewShowState(mTotalTimeTextView, INVISIBLE)
setViewShowState(mBottomProgressBar, INVISIBLE)
setViewShowState(mBackButton, INVISIBLE)
setViewShowState(mStartButton, INVISIBLE)
setViewShowState(mThumbImageViewLayout, VISIBLE)
setViewShowState(mThumbImageView, VISIBLE)
setViewShowState(mTopContainer, INVISIBLE)
setViewShowState(mLoadingProgressBar, INVISIBLE)
setViewShowState(mLockScreen, INVISIBLE)
setIsTouchWiget(false)
isFocusableInTouchMode = false
}
fun setCacheImageViewVisible() {
Logger.d(MediaLoopPlayView.TAG, "AdvanceGSYVideoPlayersetCacheImageViewVisible")
setViewShowState(mThumbImageViewLayout, VISIBLE)
// setViewShowState(mThumbImageView, VISIBLE)
}
fun setCacheImageViewGone() {
Logger.d(MediaLoopPlayView.TAG, "AdvanceGSYVideoPlayersetCacheImageViewGone")
setViewShowState(mThumbImageViewLayout, INVISIBLE)
// setViewShowState(mThumbImageView, INVISIBLE)
}
//失去焦点声音压低
override fun onLossTransientCanDuck() {
// setStreamVolume(0.2f)
setNeedMute(true)
}
//获取焦点声音恢复
override fun onGankAudio() {
// setStreamVolume(5.0f)
setNeedMute(false)
}
private fun setStreamVolume(percent: Float) {
var mAudioManager = mContext?.getSystemService(Context.AUDIO_SERVICE) as AudioManager
var maxVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
var volume = (percent * maxVolume).toInt()
if (volume < 0) {
volume = 0
}
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0)
}
private fun setNeedMute(isMute: Boolean) {
gsyVideoManager?.player?.setNeedMute(isMute)
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
if (!mIfCurrentIsFullscreen) {
val dp2px = AutoSizeUtils.dp2px(context, 16f)
this.outlineProvider = TextureVideoViewOutlineProvider(dp2px.toFloat())
this.clipToOutline = true
}
}
}
class AdvanceImageView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : RelativeLayout(context, attrs) {
private var imageView: ImageView? = null
private var imageUrl: String = ""
init {
initView()
}
private fun initView() {
imageView = ImageView(context)
imageView?.scaleType = ImageView.ScaleType.FIT_XY
addView(imageView, LayoutParams(-1, -1))
}
fun initImageUrlData(url: String) {
this.imageUrl = url
}
fun displayImage() {
imageView?.setImageResource(R.drawable.video_holder)
imageView?.also {
Glide.with(context).asBitmap().load(imageUrl).apply(
RequestOptions().useUnlimitedSourceGeneratorsPool(true)
.placeholder(R.drawable.video_holder)
.error(R.drawable.video_holder)
.fallback(R.drawable.video_holder)
.centerCrop()
).into(it)
}
}
}

View File

@@ -0,0 +1,75 @@
package com.mogo.och.common.module.wigets.media
import com.mogo.commons.mvp.MvpFragment
import com.mogo.commons.mvp.Presenter
import com.mogo.eagle.core.function.main.MainMoGoApplication
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.common.module.R
import kotlinx.android.synthetic.main.fragment_video_player.imageVideoRotationView
/**
* @author: wangmingjun
* @date: 2022/4/12
*/
class MediaPlayerFragment :
MvpFragment<MediaPlayerFragment?, MediaPlayerPresenter?>() {
companion object {
private val TAG = MediaPlayerFragment::class.java.simpleName
}
private var arrayListOf = mutableListOf<MediaItem>()
override fun getLayoutId(): Int {
return R.layout.fragment_video_player
}
override fun createPresenter(): MediaPlayerPresenter {
return MediaPlayerPresenter(this)
}
override fun getTagName(): String {
return TAG
}
override fun initViews() {
MediaFileCacheManager.createFileCacheDir(MainMoGoApplication.getApp().applicationContext)
MediaDataSourceManager.init(TAG, object : IMediaDataSourceListener {
override fun onMediaDataSourceChanged(list: List<MediaItem>) {
val isNewData = arrayListOf.isNotEmpty()
CallerLogger.d(
TAG, "onMediaDataSourceChangedisNewData=$isNewData, list=${GsonUtils.toJson(list)}"
)
arrayListOf.clear()
arrayListOf.addAll(list)
UiThreadHandler.post {
if (isNewData) {
imageVideoRotationView.setNewMediaData(arrayListOf)
} else {
imageVideoRotationView.setMediaData(arrayListOf)
}
}
}
})
}
override fun onPause() {
super.onPause()
imageVideoRotationView.setPause()
}
override fun onResume() {
super.onResume()
imageVideoRotationView.setResume()
}
override fun onDestroy() {
MediaDataSourceManager.unInit(TAG)
super.onDestroy()
}
}
class MediaPlayerPresenter(view: MediaPlayerFragment?) :
Presenter<MediaPlayerFragment?>(view)

View File

@@ -1,10 +0,0 @@
package com.mogo.och.common.module.wigets.video
data class AdsDatas(val ads:MutableList<RotationItem>)
data class RotationItem(
var path: String,
var type: Int,
var cacheImgPath: String,
var title: String
)

View File

@@ -1,44 +0,0 @@
package com.mogo.och.common.module.wigets.video
import AdvancePagerAdapter
import AdvanceViewPager
import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.widget.RelativeLayout
class ImageVideoRotationView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : RelativeLayout(context, attrs) {
private var viewPager: AdvanceViewPager? = null
private var pagerAdapter: AdvancePagerAdapter? = null
companion object {
const val TAG = "ImageAndVideoRotation"
}
init {
initView()
}
@SuppressLint("ClickableViewAccessibility")
private fun initView() {
viewPager = AdvanceViewPager(context)
pagerAdapter = AdvancePagerAdapter(context, viewPager!!)
viewPager?.adapter = pagerAdapter
addView(viewPager, LayoutParams(-1, -1))
}
fun setData(list: MutableList<RotationItem>) {
pagerAdapter?.setData(list)
}
fun setPause() {
pagerAdapter?.setPause()
}
fun setResume() {
pagerAdapter?.setResume()
}
}

View File

@@ -1,62 +0,0 @@
package com.mogo.och.common.module.wigets.video
import com.google.gson.reflect.TypeToken
import com.mogo.commons.mvp.MvpFragment
import com.mogo.commons.mvp.Presenter
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.mogo.och.common.module.R
import kotlinx.android.synthetic.main.fragment_video_player.*
/**
* @author: wangmingjun
* @date: 2022/4/12
*/
class VideoPlayerFragment :
MvpFragment<VideoPlayerFragment?, VideoPlayerPresenter?>() {
private var arrayListOf = mutableListOf<RotationItem>()
override fun getLayoutId(): Int {
return R.layout.fragment_video_player
}
override fun createPresenter(): VideoPlayerPresenter {
return VideoPlayerPresenter(this)
}
companion object {
private val TAG = VideoPlayerFragment::class.java.simpleName
}
override fun getTagName(): String {
return TAG
}
override fun initViews() {
initResourceData()
imageVideoRotationView.setData(arrayListOf)
}
override fun onPause() {
super.onPause()
imageVideoRotationView.setPause()
}
override fun onResume() {
super.onResume()
imageVideoRotationView.setResume()
}
private fun initResourceData() {
try {
arrayListOf.clear()
var datas: AdsDatas = GsonUtils.fromJson(FunctionBuildConfig.tempConfig,object : TypeToken<AdsDatas>() {}.type)
arrayListOf.addAll(datas.ads)
} catch (e: Exception) {
}
}
}
class VideoPlayerPresenter(view: VideoPlayerFragment?) :
Presenter<VideoPlayerFragment?>(view)

View File

@@ -1,589 +0,0 @@
import android.annotation.SuppressLint
import android.content.Context
import android.media.AudioManager
import android.net.Uri
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.RelativeLayout
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.mogo.eagle.core.utilcode.download.*
import com.mogo.eagle.core.utilcode.download.callback.*
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.CountDownTimer
import com.mogo.eagle.core.utilcode.util.FileUtils
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.common.module.R
import com.mogo.och.common.module.wigets.video.ImageVideoRotationView
import com.mogo.och.common.module.wigets.video.RotationItem
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
import com.shuyu.gsyvideoplayer.utils.Debuger
import com.shuyu.gsyvideoplayer.utils.GSYVideoType
import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
import java.io.File
class AdvanceVideoView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : RelativeLayout(context, attrs) {
private var videoRelativeLayout: RelativeLayout? = null
private var cacheImage: ImageView? = null
private var videoViewPlayer: AdvanceGSYVideoPlayer? = null
private var gsyVideoOptionBuilder: GSYVideoOptionBuilder? = null
private var mOnCompletionListener: GSYSampleCallBack? = null
private var downloadVideoName = ""
private var fileNetPath: String? = ""
private var cacheImageUrl: String? = ""
private var mVideoDirPath: String? = ""
init {
mVideoDirPath = context.filesDir.absolutePath + File.separator + "video" + File.separator
initView()
}
private fun initView() {
initCacheImgView()
initVideoView()
}
private fun initCacheImgView() {
cacheImage = ImageView(context)
cacheImage?.scaleType = ImageView.ScaleType.FIT_XY
}
private fun initVideoView() {
videoRelativeLayout = RelativeLayout(context)
addView(videoRelativeLayout, LayoutParams(-1, -1))
if (videoViewPlayer === null) {
//视频播放控件
videoViewPlayer = AdvanceGSYVideoPlayer(context)
}
var layoutParams = LayoutParams(-1, -1)
//设置videoview占满父view播放
layoutParams.addRule(ALIGN_PARENT_LEFT)
layoutParams.addRule(ALIGN_PARENT_RIGHT)
layoutParams.addRule(ALIGN_PARENT_TOP)
layoutParams.addRule(ALIGN_PARENT_BOTTOM)
videoRelativeLayout?.addView(videoViewPlayer, layoutParams)
}
fun setVideoPath(path: String, cacheImageUrl: String) {
// https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357834634/5.m4v
// https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360274126/10.mp4
this.fileNetPath = path
this.cacheImageUrl = cacheImageUrl
val pathList = path.split("/")
if (pathList.isNotEmpty()) {
this.downloadVideoName = pathList[pathList.size - 1]
}
}
private fun loadCacheImg() {
videoViewPlayer?.thumbImageView = cacheImage
cacheImage?.setImageResource(R.drawable.video_holder)
// setCacheImageViewVisible()
Logger.d(ImageVideoRotationView.TAG, "setVideoPath")
cacheImage?.let {
Glide.with(context).asBitmap().load(cacheImageUrl)
.apply(
RequestOptions().useUnlimitedSourceGeneratorsPool(true)
.placeholder(R.drawable.video_holder)
.error(R.drawable.video_holder)
.fallback(R.drawable.video_holder)
.centerCrop()
)
.into(it)
}
}
fun clearLocalErrorVideo() {
if (downloadVideoName.isNotEmpty()
&& FileUtils.isFileExists(mVideoDirPath + downloadVideoName)
) {
FileUtils.delete(mVideoDirPath + downloadVideoName)
}
}
@SuppressLint("CheckResult")
fun setCacheImageViewVisible() {
UiThreadHandler.post {
videoViewPlayer?.setCacheImageViewVisible()
}
}
fun setCacheImageViewGone() {
UiThreadHandler.post {
videoViewPlayer?.setCacheImageViewGone()
}
}
fun setVideo(onCompletionListener: GSYSampleCallBack) {
loadCacheImg()
Logger.d(ImageVideoRotationView.TAG, "setVideo")
mOnCompletionListener = onCompletionListener
//判断是否已经下载
if (downloadVideoName.isNotEmpty()) {
Logger.d(
ImageVideoRotationView.TAG,
"video local url = $mVideoDirPath$downloadVideoName"
)
if (FileUtils.isFileExists(mVideoDirPath + downloadVideoName)) {
Logger.d(ImageVideoRotationView.TAG, "have cache startPlay")
startPlay(Uri.fromFile(File(mVideoDirPath + downloadVideoName)).toString())
return
}
startDownLoadVideo()
}
}
private fun startDownLoadVideo() {
//下载视频, 下载成功后再播放
Logger.d(ImageVideoRotationView.TAG, "startDownLoadVideo")
FileUtils.createFileDir(mVideoDirPath)
DownloadUtils.downLoad(
context, fileNetPath!!, mVideoDirPath!!, downloadVideoName, downListener)
}
fun startPlay(localVideoPath: String?) {
try {
Logger.d(ImageVideoRotationView.TAG, "startPlay")
gsyVideoOptionBuilder = GSYVideoOptionBuilder()
gsyVideoOptionBuilder
?.setUrl(
localVideoPath
) // "/data/user/0/com.mogo.launcher.f/files/video/"
?.setPlayTag(downloadVideoName)
?.setCacheWithPlay(false)
?.setThumbPlay(false)
?.build(videoViewPlayer)
videoViewPlayer?.isFocusableInTouchMode = false
videoViewPlayer?.setVideoAllCallBack(mOnCompletionListener)
videoViewPlayer?.startPlayLogic()
} catch (e: Exception) {
Logger.d(ImageVideoRotationView.TAG, "startPlay e = ${e.message}")
}
}
fun onVideoReset() {
videoViewPlayer?.onVideoReset()
mOnCompletionListener = null
}
fun setPause() {
if (videoViewPlayer !== null) {
videoViewPlayer?.onVideoPause()
}
}
fun setResume() {
if (videoViewPlayer !== null) {
videoViewPlayer?.onVideoResume()
}
}
private val downListener = object : IDownloadListener {
override fun onStart(url: String) {
setCacheImageViewVisible()
Logger.d(ImageVideoRotationView.TAG, "download-onStart")
}
override fun onProgress(url: String, downloaded: Long, total: Long) {
Logger.d(ImageVideoRotationView.TAG, "download-onProgress== ${ (downloaded * 100 / total).toInt() }")
}
override fun onFinished(url: String, path: String) {
Logger.d(ImageVideoRotationView.TAG, "download-onFinished = $url")
if (url == fileNetPath) { //发现下载工具在断网又连网后,已完成的任务又都下载,跳转播放出现问题
//下载完成
ThreadUtils.runOnUiThread {
startPlay(Uri.fromFile(File(path)).toString())
}
} else {//如果当前文件不存在再次去下载当前的
Logger.d(
ImageVideoRotationView.TAG, "download-onFinished = not current" +
",currentUrl = $fileNetPath "
)
if (FileUtils.isFileExists(path)) {
Logger.d(ImageVideoRotationView.TAG, "have download startPlay")
ThreadUtils.runOnUiThread {
startPlay(Uri.fromFile(File(path)).toString())
}
return
} else {
startDownLoadVideo()
}
}
}
override fun onError(url: String, error: String?) {
Logger.d(ImageVideoRotationView.TAG, "download-onError-$error")
//出错再次下载
startDownLoadVideo()
}
}
}
class AdvanceViewPager : ViewPager {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
override fun onTouchEvent(ev: MotionEvent?): Boolean {
return false
}
override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
return false
}
}
class AdvancePagerAdapter(context: Context, viewPager: ViewPager) : PagerAdapter(),
ViewPager.OnPageChangeListener {
private val mContext: Context = context
private val mViewPager: ViewPager = viewPager
private var dataList = mutableListOf<RotationItem>()
private var viewList = mutableListOf<View>()
private var lastPosition = -1
private var current = 0
private val time = 5000
private var pause = false
private var countDownTimer: CountDownTimer? = null
fun setData(list: MutableList<RotationItem>) {
if (list.isEmpty()) return
dataList.addAll(list)
viewList.clear()
list.forEach {
addView(it)
}
mViewPager.addOnPageChangeListener(this)
notifyDataSetChanged()
mViewPager.currentItem = 0
if (viewList.size > 0) {
if (viewList[mViewPager.currentItem] is AdvanceVideoView) {//有人反应第一个是视频不播放这边优化了一下
Logger.d(ImageVideoRotationView.TAG, "第一个是视频")
val video = viewList[mViewPager.currentItem] as AdvanceVideoView
video.setVideo(gsySampleCallBack)
} else if (viewList[mViewPager.currentItem] is AdvanceImageView) {
Logger.d(ImageVideoRotationView.TAG, "startTimer()_1")
current = 0//换页重新计算时间
startTimer()
}
}
}
override fun getCount(): Int {
return dataList.size
}
override fun isViewFromObject(view: View, `object`: Any): Boolean {
return view === `object`
}
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
container.removeView(viewList[position])
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val view: View = viewList[position]
container.addView(view)
return view
}
override fun getItemPosition(`object`: Any): Int {
return POSITION_NONE
}
private fun addView(item: RotationItem) {
if (item.type == 1) { // 表示视频
val videoView = AdvanceVideoView(mContext)
videoView.setVideoPath(item.path, item.cacheImgPath)
viewList.add(videoView)
} else { // 表示图片
val imageView = AdvanceImageView(mContext)
imageView.setImagePath(item.path)
viewList.add(imageView)
}
}
fun setPause() {
pause = true
if (viewList.size > 0 && viewList[mViewPager.currentItem] is AdvanceVideoView) {
val videoView = viewList[mViewPager.currentItem] as AdvanceVideoView
videoView.setPause()
}
}
fun setResume() {
pause = false
if (viewList.size > 0 && viewList[mViewPager.currentItem] is AdvanceVideoView) {
val videoView = viewList[mViewPager.currentItem] as AdvanceVideoView
videoView.setResume()
}
}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
}
override fun onPageSelected(position: Int) {
}
override fun onPageScrollStateChanged(state: Int) {
// 由于viewpager的预加载机制onPageSelected这里面加载videoview 放的跟玩一样 等操作完成后再播放videoview就香了 很丝滑
if (state == 0) { //静止,什么都没做
val currentItem = mViewPager.currentItem
Logger.d(
ImageVideoRotationView.TAG,
"state = $state currentItem = $currentItem lastPosition = $lastPosition"
)
if (viewList.size > 1) { //多于1才会循环跳转
if (viewList[mViewPager.currentItem] is AdvanceVideoView) {
val videoView = (viewList[mViewPager.currentItem] as AdvanceVideoView)
videoView.setCacheImageViewVisible()
videoView.setVideo(gsySampleCallBack)
} else if (viewList[mViewPager.currentItem] is AdvanceImageView) {
Logger.d(ImageVideoRotationView.TAG, "startTimer()")
current = 0//换页重新计算时间
startTimer()
}
lastPosition = mViewPager.currentItem
}
}
}
private var gsySampleCallBack = object : GSYSampleCallBack() {
override fun onPrepared(url: String?, vararg objects: Any?) {
Logger.d(ImageVideoRotationView.TAG, "onPrepared")
// if (viewList[mViewPager.currentItem] is AdvanceVideoView) {
// val videoView = (viewList[mViewPager.currentItem] as AdvanceVideoView)
// UiThreadHandler.postDelayed(Runnable {
// videoView.setCacheImageViewGone()
// }, 1000)
// }
}
override fun onAutoComplete(url: String?, vararg objects: Any?) {
Logger.d(ImageVideoRotationView.TAG, "onAutoComplete()")
if (viewList[mViewPager.currentItem] is AdvanceVideoView) {
val videoView = (viewList[mViewPager.currentItem] as AdvanceVideoView)
videoView.onVideoReset()
if (viewList.size == 1){
videoView.startPlay(url)
}else{
goNextItemView()
}
}
}
override fun onPlayError(url: String?, vararg objects: Any?) {
super.onPlayError(url, *objects)
Logger.d(ImageVideoRotationView.TAG, "onPlayError()-${objects}")
if (viewList[mViewPager.currentItem] is AdvanceVideoView) {
val videoView = (viewList[mViewPager.currentItem] as AdvanceVideoView)
videoView.onVideoReset()
// videoView.setCacheImageViewVisible()
videoView.clearLocalErrorVideo()
goNextItemView()
}
}
}
private fun startTimer() {
if (countDownTimer != null) {
countDownTimer?.cancel()
countDownTimer = null
}
countDownTimer = object : CountDownTimer(5000, 1000) {
override fun onTick(millisUntilFinished: Long) {
CallerLogger.d(
SceneConstant.M_BUS_P + "startTimer",
"倒计时秒 = ${millisUntilFinished / 1000}"
)
}
override fun onFinish() {
CallerLogger.d(ImageVideoRotationView.TAG + "startTimer", "5s到跳转")
goNextItemView()
}
}.start()
}
/**
* view 跳转
*/
private fun goNextItemView() {
if (mViewPager.currentItem == viewList.size - 1) {//已经到最后一个
mViewPager.post {
mViewPager.setCurrentItem(0, true)
}
} else {
mViewPager.post {
mViewPager.setCurrentItem(mViewPager.currentItem + 1, true)
}
}
}
}
class AdvanceImageView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : RelativeLayout(context, attrs) {
private var imageView: ImageView? = null
init {
initView()
}
private fun initView() {
imageView = ImageView(context)
imageView?.scaleType = ImageView.ScaleType.FIT_XY
addView(imageView, LayoutParams(-1, -1))
}
@SuppressLint("CheckResult")
fun setImagePath(path: String) {
imageView?.setImageResource(R.drawable.video_holder)
imageView?.let {
Glide.with(context).asBitmap().load(path)
.apply(
RequestOptions().useUnlimitedSourceGeneratorsPool(true)
.placeholder(R.drawable.video_holder)
.error(R.drawable.video_holder)
.fallback(R.drawable.video_holder)
.centerCrop()
)
.into(it)
}
}
}
class AdvanceGSYVideoPlayer : StandardGSYVideoPlayer {
constructor(context: Context?) : super(context)
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
init {
hideWidget()
GSYVideoType.setShowType(GSYVideoType.SCREEN_MATCH_FULL)
GSYVideoType.setRenderType(GSYVideoType.GLSURFACE)
}
override fun hideAllWidget() {
Logger.d("ImageAndVideoRotation", "hideAllWidget")
}
override fun changeUiToNormal() {
Logger.d("ImageAndVideoRotation", "changeUiToNormal-hide")
hideWidget()
}
override fun changeUiToPreparingShow() {
Logger.d("ImageAndVideoRotation", "changeUiToPreparingShow-hide")
hideWidget()
}
override fun changeUiToPlayingShow() {
Logger.d("ImageAndVideoRotation", "changeUiToPlayingShow")
setCacheImageViewGone()
}
override fun changeUiToPauseShow() {
Logger.d("ImageAndVideoRotation", "changeUiToPauseShow-hide")
startPlayLogic()
}
override fun changeUiToCompleteShow() {
Logger.d("ImageAndVideoRotation", "changeUiToCompleteShow")
setCacheImageViewGone()
}
override fun changeUiToPlayingBufferingShow() {
Logger.d("ImageAndVideoRotation", "changeUiToPlayingBufferingShow -hide")
hideWidget()
}
override fun changeUiToError() {
Logger.d("ImageAndVideoRotation", "changeUiToError-hide")
hideWidget()
}
private fun hideWidget(){
setViewShowState(mBottomContainer, INVISIBLE)
setViewShowState(mProgressBar, INVISIBLE)
setViewShowState(mCurrentTimeTextView, INVISIBLE)
setViewShowState(mTotalTimeTextView, INVISIBLE)
setViewShowState(mBottomProgressBar, INVISIBLE)
setViewShowState(mBackButton, INVISIBLE)
setViewShowState(mStartButton, INVISIBLE)
setViewShowState(mThumbImageViewLayout, VISIBLE)
setViewShowState(mThumbImageView, VISIBLE)
setViewShowState(mTopContainer, INVISIBLE)
setViewShowState(mLoadingProgressBar, INVISIBLE)
setViewShowState(
mLockScreen, INVISIBLE
)
setIsTouchWiget(false)
isFocusableInTouchMode = false
}
fun setCacheImageViewVisible() {
Logger.d("ImageAndVideoRotation", "CacheImageViewVISIBLE")
setViewShowState(mThumbImageViewLayout, VISIBLE)
// setViewShowState(mThumbImageView, VISIBLE)
}
fun setCacheImageViewGone() {
Logger.d("ImageAndVideoRotation", "CacheImageViewGONE")
setViewShowState(mThumbImageViewLayout, INVISIBLE)
// setViewShowState(mThumbImageView, INVISIBLE)
}
//失去焦点声音压低
override fun onLossTransientCanDuck() {
// setStreamVolume(0.2f)
setNeedMute(true)
}
//获取焦点声音恢复
override fun onGankAudio() {
// setStreamVolume(5.0f)
setNeedMute(false)
}
private fun setStreamVolume(percent: Float){
var mAudioManager = mContext?.getSystemService(Context.AUDIO_SERVICE) as AudioManager
var maxVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
var volume = (percent * maxVolume).toInt()
if (volume < 0 ){
volume = 0
}
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC,volume,0)
}
private fun setNeedMute(isMute: Boolean){
gsyVideoManager?.player?.setNeedMute(isMute)
}
}

View File

@@ -2,11 +2,9 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 图片或视频广告-->
<com.mogo.och.common.module.wigets.video.ImageVideoRotationView
<com.mogo.och.common.module.wigets.media.MediaLoopPlayView
android:id="@+id/imageVideoRotationView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -16,7 +16,7 @@ import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.util.MultiDisplayUtils;
import com.mogo.och.bus.passenger.constant.BusPassengerConst;
import com.mogo.och.bus.passenger.ui.BusPassengerRouteFragment;
import com.mogo.och.common.module.wigets.video.VideoPlayerActivity;
import com.mogo.och.common.module.wigets.media.MediaPlayerActivity;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -47,7 +47,7 @@ public class MogoOCHBusPassenger implements IMogoOCH {
showFragment();
if (AppIdentityModeUtils.isJL(FunctionBuildConfig.appIdentityMode)) {
MultiDisplayUtils.INSTANCE.startActWithSecond(activity, VideoPlayerActivity.class);
MultiDisplayUtils.INSTANCE.startActWithSecond(activity, MediaPlayerActivity.class);
}
return null;
}

View File

@@ -1,7 +0,0 @@
package com.mogo.och.bus.passenger.presenter
import com.mogo.commons.mvp.Presenter
import com.mogo.och.bus.passenger.ui.video.PM2VideoFragment
class PM2VideoPresenter(view: PM2VideoFragment?) :
Presenter<PM2VideoFragment?>(view)

View File

@@ -1,11 +1,9 @@
package com.mogo.och.bus.passenger.ui
import android.provider.Settings
import android.view.Surface
import com.mogo.commons.mvp.MvpFragment
import com.mogo.och.bus.passenger.R
import com.mogo.och.bus.passenger.presenter.PM2Presenter
import com.mogo.och.bus.passenger.ui.video.PM2VideoFragment
import com.mogo.och.common.module.wigets.media.MediaPlayerFragment
/**
* @author: wangmingjun
@@ -16,7 +14,7 @@ class PM2BaseFragment :
private var drivingFragment : PM2DrivingInfoFragment? = null
private var hdMapFragment : PM2HPMapFragment? = null
private var videoFragment : PM2VideoFragment? = null
private var mediaFragment : MediaPlayerFragment? = null
override fun getLayoutId(): Int {
return R.layout.p_m2_fragment
@@ -57,9 +55,9 @@ class PM2BaseFragment :
childFragmentManager.beginTransaction().add(R.id.hd_map_fragment, hdMapFragment!!)
.show(hdMapFragment!!).commitAllowingStateLoss()
if (videoFragment == null) videoFragment = PM2VideoFragment()
childFragmentManager.beginTransaction().add(R.id.video_fragment, videoFragment!!)
.show(videoFragment!!).commitAllowingStateLoss()
if (mediaFragment == null) mediaFragment = MediaPlayerFragment()
childFragmentManager.beginTransaction().add(R.id.video_fragment, mediaFragment!!)
.show(mediaFragment!!).commitAllowingStateLoss()
}
override fun createPresenter(): PM2Presenter {
@@ -67,6 +65,6 @@ class PM2BaseFragment :
}
companion object {
public val TAG = PM2BaseFragment::class.java.simpleName
val TAG = PM2BaseFragment::class.java.simpleName
}
}

View File

@@ -1,64 +0,0 @@
package com.mogo.och.bus.passenger.ui.video
import com.google.gson.reflect.TypeToken
import com.mogo.commons.mvp.MvpFragment
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.mogo.och.bus.passenger.R
import com.mogo.och.bus.passenger.presenter.PM2VideoPresenter
import com.mogo.och.common.module.wigets.video.AdsDatas
import com.mogo.och.common.module.wigets.video.RotationItem
import kotlinx.android.synthetic.m2.p_m2_video_fragment.*
/**
* @author: wangmingjun
* @date: 2022/4/12
*/
class PM2VideoFragment :
MvpFragment<PM2VideoFragment?, PM2VideoPresenter?>() {
private var arrayListOf = mutableListOf<RotationItem>()
override fun getLayoutId(): Int {
return R.layout.p_m2_video_fragment
}
override fun createPresenter(): PM2VideoPresenter {
return PM2VideoPresenter(this)
}
companion object {
private val TAG = PM2VideoFragment::class.java.simpleName
}
override fun getTagName(): String {
return TAG
}
override fun initViews() {
initResourceData()
imageVideoRotationView.setData(arrayListOf)
}
override fun onPause() {
super.onPause()
imageVideoRotationView.setPause()
}
override fun onResume() {
super.onResume()
imageVideoRotationView.setResume()
}
private fun initResourceData() {
try {
arrayListOf.clear()
var datas: AdsDatas = GsonUtils.fromJson(FunctionBuildConfig.tempConfig,object : TypeToken<AdsDatas>() {}.type)
arrayListOf.addAll(datas.ads)
} catch (e: Exception) {
e.printStackTrace()
}
}
}

View File

@@ -1,137 +0,0 @@
package com.mogo.och.bus.passenger.ui.widget.video
import android.content.Context
import android.media.AudioManager
import android.util.AttributeSet
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.mogo.eagle.core.widget.media.video.TextureVideoViewOutlineProvider
import com.shuyu.gsyvideoplayer.utils.GSYVideoType
import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
import me.jessyan.autosize.utils.AutoSizeUtils
/**
* @author: wangmingjun
* @date: 2023/2/17
* 隐藏所有控件的player
*/
class AdvanceGSYVideoPlayer: StandardGSYVideoPlayer {
constructor(context: Context?) : super(context)
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
init {
hideWidget()
GSYVideoType.setShowType(GSYVideoType.SCREEN_TYPE_16_9)
GSYVideoType.setRenderType(GSYVideoType.GLSURFACE)
}
override fun hideAllWidget() {
Logger.d(ImageAndVideoRotation.TAG, "hideAllWidget")
// hideWidget()
}
override fun changeUiToNormal() {
Logger.d(ImageAndVideoRotation.TAG, "changeUiToNormal-hide")
hideWidget()
}
override fun changeUiToPreparingShow() {
Logger.d(ImageAndVideoRotation.TAG, "changeUiToPreparingShow-hide")
hideWidget()
}
override fun changeUiToPlayingShow() {
Logger.d(ImageAndVideoRotation.TAG, "changeUiToPlayingShow")
setCacheImageViewGone()
}
override fun changeUiToPauseShow() {
Logger.d(ImageAndVideoRotation.TAG, "changeUiToPauseShow-hide")
startPlayLogic()
// hideWidget()
}
override fun changeUiToCompleteShow() {
Logger.d(ImageAndVideoRotation.TAG, "changeUiToCompleteShow")
setCacheImageViewGone()
}
override fun changeUiToPlayingBufferingShow() {
Logger.d(ImageAndVideoRotation.TAG, "changeUiToPlayingBufferingShow -hide")
hideWidget()
}
override fun changeUiToError() {
Logger.d(ImageAndVideoRotation.TAG, "changeUiToError-hide")
hideWidget()
}
private fun hideWidget(){
setViewShowState(mBottomContainer, INVISIBLE)
setViewShowState(mProgressBar, INVISIBLE)
setViewShowState(mCurrentTimeTextView, INVISIBLE)
setViewShowState(mTotalTimeTextView, INVISIBLE)
setViewShowState(mBottomProgressBar, INVISIBLE)
setViewShowState(mBackButton, INVISIBLE)
setViewShowState(mStartButton, INVISIBLE)
setViewShowState(mThumbImageViewLayout, VISIBLE)
setViewShowState(mThumbImageView, VISIBLE)
setViewShowState(mTopContainer, INVISIBLE)
setViewShowState(mLoadingProgressBar, INVISIBLE)
setViewShowState(
mLockScreen, INVISIBLE
)
setIsTouchWiget(false)
isFocusableInTouchMode = false
}
fun setCacheImageViewVisible() {
Logger.d(ImageAndVideoRotation.TAG, "CacheImageViewVISIBLE")
setViewShowState(mThumbImageViewLayout, VISIBLE)
// setViewShowState(mThumbImageView, VISIBLE)
}
fun setCacheImageViewGone() {
Logger.d(ImageAndVideoRotation.TAG, "CacheImageViewGONE")
setViewShowState(mThumbImageViewLayout, INVISIBLE)
// setViewShowState(mThumbImageView, INVISIBLE)
}
//失去焦点声音压低
override fun onLossTransientCanDuck() {
// setStreamVolume(0.2f)
setNeedMute(true)
}
//获取焦点声音恢复
override fun onGankAudio() {
// setStreamVolume(5.0f)
setNeedMute(false)
}
private fun setStreamVolume(percent: Float){
var mAudioManager = mContext?.getSystemService(Context.AUDIO_SERVICE) as AudioManager
var maxVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
var volume = (percent * maxVolume).toInt()
if (volume < 0 ){
volume = 0
}
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC,volume,0)
}
private fun setNeedMute(isMute: Boolean){
gsyVideoManager?.player?.setNeedMute(isMute)
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
if (!mIfCurrentIsFullscreen) {
val dp2px = AutoSizeUtils.dp2px(context, 16f)
this.outlineProvider = TextureVideoViewOutlineProvider(dp2px.toFloat())
this.clipToOutline = true
}
}
}

View File

@@ -1,45 +0,0 @@
package com.mogo.och.bus.passenger.ui.widget.video
import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.widget.ImageView
import android.widget.RelativeLayout
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.mogo.och.bus.passenger.R
/**
* @author: wangmingjun
* @date: 2023/2/6
*/
class AdvanceImageView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : RelativeLayout(context, attrs) {
private var imageView: ImageView? = null
init {
initView()
}
private fun initView() {
imageView = ImageView(context)
imageView?.scaleType = ImageView.ScaleType.FIT_XY
addView(imageView, LayoutParams(-1, -1))
}
@SuppressLint("CheckResult")
fun setImagePath(path: String){
imageView?.setImageResource(R.drawable.m2_p_video_holder)
imageView?.let { Glide.with(context).asBitmap().load(path)
.apply(
RequestOptions().useUnlimitedSourceGeneratorsPool(true)
.placeholder(R.drawable.m2_p_video_holder)
.error(R.drawable.m2_p_video_holder)
.fallback(R.drawable.m2_p_video_holder)
.centerCrop()
)
.into(it) }
}
}

View File

@@ -1,211 +0,0 @@
package com.mogo.och.bus.passenger.ui.widget.video
import android.content.Context
import android.view.View
import android.view.ViewGroup
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.CountDownTimer
import com.mogo.och.common.module.wigets.video.RotationItem
import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
/**
* @author: wangmingjun
* @date: 2023/2/6
*/
class AdvancePagerAdapter(context: Context, viewPager: ViewPager) : PagerAdapter(),
ViewPager.OnPageChangeListener {
private val mContext: Context = context
private val mViewPager: ViewPager = viewPager
private var dataList = mutableListOf<RotationItem>()
private var viewList = mutableListOf<View>()
private var lastPosition = -1
private var current = 0
private val time = 5000
private var pause = false
private var countDownTimer: CountDownTimer? = null
fun setData(list: MutableList<RotationItem>) {
if (list.isEmpty()) return
dataList.addAll(list)
viewList.clear()
list.forEach {
addView(it)
}
mViewPager.addOnPageChangeListener(this)
notifyDataSetChanged()
mViewPager.currentItem = 0
if (viewList.size > 0) {
if (viewList[mViewPager.currentItem] is AdvanceVideoView) {//有人反应第一个是视频不播放这边优化了一下
Logger.d(ImageAndVideoRotation.TAG, "第一个是视频")
val video = viewList[mViewPager.currentItem] as AdvanceVideoView
video.setVideo(gsySampleCallBack)
} else if (viewList[mViewPager.currentItem] is AdvanceImageView) {
Logger.d(ImageAndVideoRotation.TAG, "startTimer()_1")
current = 0//换页重新计算时间
startTimer()
}
}
}
override fun getCount(): Int {
return dataList.size
}
override fun isViewFromObject(view: View, `object`: Any): Boolean {
return view === `object`
}
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
container.removeView(viewList[position])
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val view: View = viewList[position]
container.addView(view)
return view
}
override fun getItemPosition(`object`: Any): Int {
return POSITION_NONE
}
private fun addView(item: RotationItem) {
if (item.type == 1) { // 表示视频
val videoView = AdvanceVideoView(mContext)
videoView.setVideoPath(item.path,item.cacheImgPath)
viewList.add(videoView)
} else { // 表示图片
val imageView = AdvanceImageView(mContext)
imageView.setImagePath(item.path)
viewList.add(imageView)
}
}
fun setPause() {
pause = true
if (viewList.size > 0 && viewList[mViewPager.currentItem] is AdvanceVideoView) {
val videoView = viewList[mViewPager.currentItem] as AdvanceVideoView
videoView.setPause()
}
}
fun setResume() {
pause = false
if (viewList.size > 0 && viewList[mViewPager.currentItem] is AdvanceVideoView) {
val videoView = viewList[mViewPager.currentItem] as AdvanceVideoView
videoView.setResume()
}
}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
}
override fun onPageSelected(position: Int) {
}
override fun onPageScrollStateChanged(state: Int) {
// 由于viewpager的预加载机制onPageSelected这里面加载videoview 放的跟玩一样 等操作完成后再播放videoview就香了 很丝滑
if (state == 0) { //静止,什么都没做
val currentItem = mViewPager.currentItem
Logger.d(ImageAndVideoRotation.TAG,
"state = $state currentItem = $currentItem lastPosition = $lastPosition")
if (viewList.size > 1) { //多于1才会循环跳转
if (viewList[mViewPager.currentItem] is AdvanceVideoView) {
val videoView = (viewList[mViewPager.currentItem] as AdvanceVideoView)
videoView.setCacheImageViewVisible()
videoView.setVideo(gsySampleCallBack)
} else if (viewList[mViewPager.currentItem] is AdvanceImageView) {
Logger.d(ImageAndVideoRotation.TAG, "startTimer()")
current = 0//换页重新计算时间
startTimer()
}
lastPosition = mViewPager.currentItem
}
}
}
private var gsySampleCallBack = object : GSYSampleCallBack() {
override fun onPrepared(url: String?, vararg objects: Any?) {
Logger.d(ImageAndVideoRotation.TAG, "onPrepared--$url")
}
override fun onAutoComplete(url: String?, vararg objects: Any?) {
Logger.d(ImageAndVideoRotation.TAG, "onAutoComplete()-$url")
if (viewList[mViewPager.currentItem] is AdvanceVideoView){
val videoView = (viewList[mViewPager.currentItem] as AdvanceVideoView)
if (viewList.size == 1){
videoView.startPlay(url)
}else{
videoView.onVideoReset()
goNextItemView()
}
}
}
override fun onPlayError(url: String?, vararg objects: Any?) {
super.onPlayError(url, *objects)
Logger.d(ImageAndVideoRotation.TAG, "onPlayError()-$url")
if (viewList[mViewPager.currentItem] is AdvanceVideoView){
val videoView = (viewList[mViewPager.currentItem] as AdvanceVideoView)
videoView.onVideoReset()
// videoView.setCacheImageViewVisible()
videoView.clearLocalErrorVideo()
goNextItemView()
}
}
}
private fun startTimer() {
if (countDownTimer != null){
countDownTimer?.cancel()
countDownTimer = null
}
countDownTimer = object : CountDownTimer(5000,1000){
override fun onTick(millisUntilFinished: Long) {
d(SceneConstant.M_BUS_P + "startTimer", "倒计时秒 = ${millisUntilFinished/1000}" )
}
override fun onFinish() {
d(ImageAndVideoRotation.TAG+ "startTimer", "5s到跳转")
goNextItemView()
}
}.start()
}
/**
* view 跳转
*/
private fun goNextItemView() {
if (mViewPager.currentItem == viewList.size - 1) {//已经到最后一个
mViewPager.post {
mViewPager.setCurrentItem(0, true)
}
} else {
mViewPager.post {
mViewPager.setCurrentItem(mViewPager.currentItem + 1, true)
}
}
}
}

View File

@@ -1,254 +0,0 @@
package com.mogo.och.bus.passenger.ui.widget.video
import android.annotation.SuppressLint
import android.content.Context
import android.net.Uri
import android.util.AttributeSet
import android.widget.ImageView
import android.widget.RelativeLayout
import com.mogo.eagle.core.utilcode.download.*
import com.mogo.eagle.core.utilcode.download.callback.*
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.mogo.eagle.core.utilcode.util.FileUtils
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.bus.passenger.R
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
import java.io.File
/**
* @author: wangmingjun
* @date: 2023/2/8
*/
class AdvanceVideoView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : RelativeLayout(context, attrs) {
private var videoRelativeLayout: RelativeLayout? = null
private var cacheImage: ImageView? = null
private var videoViewPlayer: AdvanceGSYVideoPlayer? = null
private var gsyVideoOptionBuilder: GSYVideoOptionBuilder? = null
private var mOnCompletionListener: GSYSampleCallBack? = null
private var downloadVideoName = ""
private var fileNetPath: String? = ""
private var cacheImageUrl: String? = ""
private var mVideoDirPath: String? = ""
init {
mVideoDirPath = context.filesDir.absolutePath + File.separator + "video" + File.separator
// mVideoDirPath = Config.downLoadPath
initView()
}
private fun initView() {
initVideoView()
initCacheImgView()
}
private fun initCacheImgView() {
cacheImage = ImageView(context)
cacheImage?.scaleType = ImageView.ScaleType.FIT_XY
// addView(cacheImage, LayoutParams(-1, -1))
}
private fun initVideoView() {
videoRelativeLayout = RelativeLayout(context)
val outLayout = LayoutParams(-1, -1)
addView(videoRelativeLayout, outLayout)
if (videoViewPlayer === null) {
//视频播放控件
videoViewPlayer = AdvanceGSYVideoPlayer(context)
}
val layoutParams = LayoutParams(-1, -1)
//设置videoview占满父view播放
layoutParams.addRule(ALIGN_PARENT_LEFT)
layoutParams.addRule(ALIGN_PARENT_RIGHT)
layoutParams.addRule(ALIGN_PARENT_TOP)
layoutParams.addRule(ALIGN_PARENT_BOTTOM)
videoRelativeLayout?.addView(videoViewPlayer, layoutParams)
}
fun setVideoPath(path: String, cacheImageUrl: String) {
// https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357834634/5.m4v
// https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360274126/10.mp4
this.fileNetPath = path
this.cacheImageUrl = cacheImageUrl
val pathList = path.split("/")
if (pathList.isNotEmpty()) {
this.downloadVideoName = pathList[pathList.size - 1]
}
}
private fun loadCacheImg() {
// BitmapHelper.getVideoThumbnail(path) /*获取第一帧图*
// OCHThreadPoolManager.getsInstance().execute {
// var bitmap = BitmapHelper.getVideoThumbnail(fileNetPath)
Logger.d(ImageAndVideoRotation.TAG, "setVideoPath")
// ThreadUtils.runOnUiThread {
// Logger.d(ImageAndVideoRotation.TAG, "bitmap加载")
cacheImage?.setImageResource(R.drawable.m2_p_video_holder)
// cacheImage?.let { //暂时去掉加载首帧图,加载视频时,用本地默认图
// Glide.with(context).asBitmap().load(cacheImageUrl)
// .apply(
// RequestOptions().useUnlimitedSourceGeneratorsPool(true)
// .placeholder(R.drawable.m2_p_video_holder)
// .error(R.drawable.m2_p_video_holder)
// .fallback(R.drawable.m2_p_video_holder)
// .centerCrop()
// )
// .into(it)
// }
videoViewPlayer?.thumbImageView = cacheImage
// setCacheImageViewVisible()
// }
// }
}
fun clearLocalErrorVideo() {
if (downloadVideoName.isNotEmpty()
&& FileUtils.isFileExists(mVideoDirPath + downloadVideoName)
) {
FileUtils.delete(mVideoDirPath + downloadVideoName)
}
}
@SuppressLint("CheckResult")
fun setCacheImageViewVisible() {
UiThreadHandler.post {
// cacheImage?.visibility = VISIBLE
videoViewPlayer?.setCacheImageViewVisible()
}
}
fun setCacheImageViewGone() {
UiThreadHandler.post {
// cacheImage?.visibility = GONE
videoViewPlayer?.setCacheImageViewGone()
}
}
fun setVideo(onCompletionListener: GSYSampleCallBack) {
loadCacheImg()
Logger.d(ImageAndVideoRotation.TAG, "setVideo")
mOnCompletionListener = onCompletionListener
//判断是否已经下载
if (downloadVideoName.isNotEmpty()) {
Logger.d(
ImageAndVideoRotation.TAG,
"video local url = $mVideoDirPath$downloadVideoName"
)
if (FileUtils.isFileExists(mVideoDirPath + downloadVideoName)) {
Logger.d(ImageAndVideoRotation.TAG, "have cache startPlay")
startPlay(Uri.fromFile(File(mVideoDirPath + downloadVideoName)).toString())
return
}
startDownLoadVideo()
}
}
private fun startDownLoadVideo() {
//下载视频, 下载成功后再播放
Logger.d(ImageAndVideoRotation.TAG, "startDownLoadVideo")
FileUtils.createFileDir(mVideoDirPath)
val downloadUrl = fileNetPath
val downloadDir = mVideoDirPath
if (downloadUrl != null && downloadDir != null) {
DownloadUtils.downLoad(
context, downloadUrl, downloadDir, downloadVideoName, downListener
)
}
}
fun startPlay(localVideoPath: String?) {
if (localVideoPath === "") return
try {
Logger.d(ImageAndVideoRotation.TAG, "startPlay")
gsyVideoOptionBuilder = GSYVideoOptionBuilder()
gsyVideoOptionBuilder
// ?.setUrl("file:///mnt/sdcard/downloads/$downloadVideoName")
?.setUrl(localVideoPath) // "/data/user/0/com.mogo.launcher.f/files/video/"
?.setPlayTag(downloadVideoName)
?.setCacheWithPlay(false)
?.setThumbPlay(false)
?.build(videoViewPlayer)
videoViewPlayer?.isFocusableInTouchMode = false
videoViewPlayer?.setVideoAllCallBack(mOnCompletionListener)
videoViewPlayer?.startPlayLogic()
} catch (e: Exception) {
Logger.d(ImageAndVideoRotation.TAG, "startPlay e = ${e.message}")
}
}
fun onVideoReset() {
videoViewPlayer?.onVideoReset()
mOnCompletionListener = null
}
fun setPause() {
if (videoViewPlayer !== null) {
videoViewPlayer?.onVideoPause()
}
}
fun setResume() {
if (videoViewPlayer !== null) {
videoViewPlayer?.onVideoResume()
}
}
private val downListener = object : IDownloadListener {
override fun onStart(url: String) {
setCacheImageViewVisible()
Logger.d(ImageAndVideoRotation.TAG, "download-onStart")
}
// override fun onPause(url: String, threadBean: ThreadBean?) {
// Logger.d(ImageAndVideoRotation.TAG, "download-onPause")
//// UiThreadHandler.postDelayed(Runnable {
//// startDownLoadVideo()
//// },DOWNLOAD_DELAY)
// // todo 测试下网络断掉是否会走onpause且网络回复也不会继续下载
// }
override fun onProgress(url: String, downloaded: Long, total: Long) {
Logger.d(ImageAndVideoRotation.TAG, "download-onProgress== ${ (downloaded * 1.0f * 100/total).toInt() }")
}
override fun onFinished(url: String, path: String) {
Logger.d(ImageAndVideoRotation.TAG, "download-onFinished = $url")
if (url.equals(fileNetPath)) { //发现下载工具在断网又连网后,已完成的任务又都下载,跳转播放出现问题
//下载完成
ThreadUtils.runOnUiThread {
startPlay(Uri.fromFile(File(path)).toString())
}
} else {//如果当前文件不存在再次去下载当前的
Logger.d(
ImageAndVideoRotation.TAG, "download-onFinished = not current" +
",currentUrl = $fileNetPath "
)
if (FileUtils.isFileExists(path)) {
Logger.d(ImageAndVideoRotation.TAG, "have download startPlay")
ThreadUtils.runOnUiThread {
startPlay(Uri.fromFile(File(path)).toString())
}
return
} else {
startDownLoadVideo()
}
}
}
override fun onError(url: String, error: String?) {
Logger.d(ImageAndVideoRotation.TAG, "download-onError-$error")
//出错再次下载
startDownLoadVideo()
}
}
}

View File

@@ -1,24 +0,0 @@
package com.mogo.och.bus.passenger.ui.widget.video
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import androidx.viewpager.widget.ViewPager
/**
* @author: wangmingjun
* @date: 2023/2/21
*/
class AdvanceViewPager: ViewPager{
constructor(context: Context) : super(context)
constructor(context: Context,attrs: AttributeSet?) : super(context,attrs)
override fun onTouchEvent(ev: MotionEvent?): Boolean {
return false
}
override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
return false
}
}

View File

@@ -1,49 +0,0 @@
package com.mogo.och.bus.passenger.ui.widget.video
import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.widget.RelativeLayout
import androidx.viewpager.widget.ViewPager
import com.mogo.och.common.module.wigets.video.RotationItem
/**
* @author: wangmingjun
* @date: 2023/2/6
*/
class ImageAndVideoRotation @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : RelativeLayout(context, attrs) {
private var viewPager: AdvanceViewPager? = null
private var pagerAdapter: AdvancePagerAdapter? = null
companion object {
const val TAG = "ImageAndVideoRotation"
}
init {
initView()
}
@SuppressLint("ClickableViewAccessibility")
private fun initView() {
viewPager = AdvanceViewPager(context)
pagerAdapter = AdvancePagerAdapter(context, viewPager!!)
viewPager?.adapter = pagerAdapter
addView(viewPager, LayoutParams(-1, -1))
}
fun setData(list: MutableList<RotationItem>){
pagerAdapter?.setData(list)
}
fun setPause(){
pagerAdapter?.setPause()
}
fun setResume(){
pagerAdapter?.setResume()
}
}

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 图片或视频广告-->
<com.mogo.och.bus.passenger.ui.widget.video.ImageAndVideoRotation
android:id="@+id/imageVideoRotationView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,3 +1,3 @@
package com.mogo.och.taxi.passenger.bean
class TaxiPassengerVideoPlay(var url: String, var imageUrl: String, var title: String)
class TaxiPassengerVideoPlay(var url: String, var imageUrl: String, var title: String, var type: Int)

View File

@@ -7,7 +7,17 @@ import android.view.LayoutInflater
import android.view.View
import android.widget.FrameLayout
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.function.main.MainMoGoApplication
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.common.module.wigets.media.IMediaDataSourceListener
import com.mogo.och.common.module.wigets.media.MediaDataSourceManager
import com.mogo.och.common.module.wigets.media.MediaFileCacheManager
import com.mogo.och.common.module.wigets.media.MediaItem
import com.mogo.och.common.module.wigets.media.MediaPlayLogger
import com.mogo.och.taxi.passenger.R
import com.mogo.och.taxi.passenger.bean.TaxiPassengerVideoPlay
import com.mogo.och.taxi.passenger.ui.video.layoutmanage.CarouselLayoutManager
@@ -35,7 +45,7 @@ internal class InfoVideoView @JvmOverloads constructor(
defStyleAttr
) {
companion object{
companion object {
private const val TAG = "VideoView"
}
@@ -47,35 +57,9 @@ internal class InfoVideoView @JvmOverloads constructor(
private var rvVideoPlaylist: RecyclerView? = null
private lateinit var indicatorView: IndicatorView
private lateinit var clContain: ConstraintLayout
private val arrayListOf by lazy {
arrayListOf<TaxiPassengerVideoPlay>().apply {
add(TaxiPassengerVideoPlay(
"https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708596763/全车型混剪增加红旗车队.m4v",
"https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969511280/车队.png",
"蘑菇车联覆盖生活的方方面面"
))
add(TaxiPassengerVideoPlay(
"https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708554279/红旗车队.m4v",
"https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969553174/红旗重新排版.png",
"蘑菇车联之红旗车队"
))
add(
TaxiPassengerVideoPlay(
"https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708499497/大运会合作解说版.m4v",
"https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969536177/大运会.png",
"蘑菇车联牵手成都大运会"
)
)
add(
TaxiPassengerVideoPlay(
"https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708409810/20210610重新排版3屏.m4v",
"https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969579713/三屏.png",
"多视角体验蘑菇车联自动驾驶"
)
)
}
}
private val mediaList = mutableListOf<TaxiPassengerVideoPlay>()
//新的数据在view不展示的时候完成新数据更新
private val mNewMediaList = mutableListOf<TaxiPassengerVideoPlay>()
fun exitFullScreenMode(resetVideoPlayer: Boolean) {
val carouselLayoutManager = rvVideoPlaylist?.layoutManager as CarouselLayoutManager
@@ -83,7 +67,7 @@ internal class InfoVideoView @JvmOverloads constructor(
player?.let {
it.exitFullScreenMode()
it.onVideoPause()
if(resetVideoPlayer) {
if (resetVideoPlayer) {
it.onVideoReset()
}
}
@@ -91,12 +75,49 @@ internal class InfoVideoView @JvmOverloads constructor(
override fun onAttachedToWindow() {
super.onAttachedToWindow()
configPage()
initData()
MediaFileCacheManager.createFileCacheDir(MainMoGoApplication.getApp().applicationContext)
MediaDataSourceManager.init(TAG, object : IMediaDataSourceListener {
override fun onMediaDataSourceChanged(list: List<MediaItem>) {
val isNewData = mediaList.isNotEmpty()
MediaPlayLogger.printInfoLog("onMediaDataSourceChangedisNewData=$isNewData, dataSize=${list.size}, list=${GsonUtils.toJson(list)}")
val localMediaList = mutableListOf<TaxiPassengerVideoPlay>()
list.forEach {
val taxiPassengerVideoPlay = TaxiPassengerVideoPlay(
it.fileUrl,
it.coverImageUrl,
it.title,
it.fileType
)
localMediaList.add(taxiPassengerVideoPlay)
}
if (isNewData) {
if (!isVisible) {
updateMediaListDataAndView(localMediaList)
MediaPlayLogger.printInfoLog("onMediaDataSourceChanged, 宣传视频数据已更新")
} else {
mNewMediaList.clear()
mNewMediaList.addAll(localMediaList)
}
} else {
updateMediaListDataAndView(localMediaList)
MediaPlayLogger.printInfoLog("onMediaDataSourceChanged, 宣传视频数据已更新")
}
}
})
}
private fun updateMediaListDataAndView(newList: MutableList<TaxiPassengerVideoPlay>) {
mediaList.clear()
mediaList.addAll(newList)
UiThreadHandler.post {
initData()
}
}
override fun onVisibilityChanged(changedView: View, visibility: Int) {
super.onVisibilityChanged(changedView, visibility)
if(changedView!=this){
if (changedView != this) {
return
}
val carouselLayoutManager = rvVideoPlaylist?.layoutManager as CarouselLayoutManager
@@ -109,17 +130,29 @@ internal class InfoVideoView @JvmOverloads constructor(
GSYVideoView.CURRENT_STATE_PAUSE -> {
//player.onVideoResume(false)
}
else -> {}
}
}
}
}
else -> {
player?.let {
if (!player.isIfCurrentIsFullscreen) {
player.onVideoPause()
}
}
try {
// 在播放完成的时机更新整体数据
if (mNewMediaList.isNotEmpty()) {
updateMediaListDataAndView(mNewMediaList)
mNewMediaList.clear()
MediaPlayLogger.printInfoLog("onVisibilityChanged, 宣传视频数据已更新")
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
@@ -130,16 +163,11 @@ internal class InfoVideoView @JvmOverloads constructor(
clContain = findViewById(R.id.infoContainer)
}
private fun configPage() {
// FullVideoUtils.dismissOverlayView(true)
initData()
}
private fun initData() {
val carouselLayoutManager = CarouselLayoutManager(CarouselLayoutManager.HORIZONTAL, true)
carouselLayoutManager.setPostLayoutListener(CarouselZoomPostLayoutListener())
carouselLayoutManager.maxVisibleItems = 1
indicatorView.notifyDataChanged(arrayListOf.size)
indicatorView.notifyDataChanged(mediaList.size)
indicatorView.setSlideMode(IndicatorSlideMode.SCALE)
indicatorView.setOrientation(IndicatorOrientation.INDICATOR_HORIZONTAL)
indicatorView.setIndicatorStyle(IndicatorStyle.ROUND_RECT)
@@ -171,6 +199,7 @@ internal class InfoVideoView @JvmOverloads constructor(
}
}
prePlayerPosition = centerItemPosition
MediaPlayLogger.printInfoLog("pageSelect, currentPosition=$prePlayerPosition")
}
override fun pageStop() {
@@ -179,7 +208,6 @@ internal class InfoVideoView @JvmOverloads constructor(
player.onVideoPause()
}
}
})
carouselLayoutManager.addOnDargAutoDiffListener { adapterPosition, currentPosition ->
val fl = adapterPosition - floor(adapterPosition)
@@ -193,7 +221,7 @@ internal class InfoVideoView @JvmOverloads constructor(
}
indicatorView.onPageScrolled(currentIndex, fl, 0)
}
val recyclerVideoAdapter = RecyclerVideoAdapter(context, arrayListOf, rvVideoPlaylist)
val recyclerVideoAdapter = RecyclerVideoAdapter(context, mediaList, rvVideoPlaylist)
recyclerVideoAdapter.setOnThumbImageClilckListener {
val (_: Int, player) = getPlayer(carouselLayoutManager)
if (player is ConsultVideoPlayer) {
@@ -219,14 +247,14 @@ internal class InfoVideoView @JvmOverloads constructor(
val carouselLayoutManager = rvVideoPlaylist?.layoutManager as CarouselLayoutManager
val (_: Int, player) = getPlayer(carouselLayoutManager)
player?.let {
if(it.isInPlayingState&&!it.isIfCurrentIsFullscreen&&!hasWindowFocus){
if (it.isInPlayingState && !it.isIfCurrentIsFullscreen && !hasWindowFocus) {
player.onVideoPause()
}
}
}
override fun onDetachedFromWindow() {
MediaDataSourceManager.unInit(TAG)
super.onDetachedFromWindow()
}
}

View File

@@ -11,6 +11,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.mogo.eagle.core.utilcode.util.ToastUtils;
import com.mogo.och.common.module.wigets.media.MediaItem;
import com.mogo.och.taxi.passenger.R;
import com.mogo.och.taxi.passenger.bean.TaxiPassengerVideoPlay;
import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack;
@@ -48,29 +49,45 @@ public class RecyclerVideoAdapter extends RecyclerView.Adapter<RecyclerItemVideo
return recyclerItemVideoHolder;
}
@Override
public void onBindViewHolder(@NonNull final RecyclerItemVideoHolder holder, int position) {
final TaxiPassengerVideoPlay taxiPassengerVideoPlay = itemDataList.get(position);
boolean isVideo = taxiPassengerVideoPlay.getType() == MediaItem.MEDIA_TYPE_VIDEO;
AutoSizeCompat.autoConvertDensityOfGlobal(holder.itemView.getResources());
holder.gsyVideoOptionBuilder
.setEnlargeImageRes(R.drawable.taxi_p_change_full)
.setUrl(taxiPassengerVideoPlay.getUrl())
.setCacheWithPlay(true)
.setPlayTag(taxiPassengerVideoPlay.getImageUrl()+position)
.setPlayTag(taxiPassengerVideoPlay.getUrl()+position)
.setThumbPlay(false)
.setStartAfterPrepared(isVideo ? true : false)
.build(holder.gsyVideoPlayer);
holder.gsyVideoPlayer.getTitleTextView().setText(taxiPassengerVideoPlay.getTitle());
String imageUrl;
if (isVideo) {
imageUrl = taxiPassengerVideoPlay.getImageUrl();
} else {
imageUrl = taxiPassengerVideoPlay.getUrl();
}
Glide.with(context)
.load(taxiPassengerVideoPlay.getImageUrl())
.load(imageUrl)
.apply(new RequestOptions().placeholder(R.drawable.taxi_p_video_holder).centerCrop())
.into(holder.gsyVideoPlayer.coverImage);
holder.gsyVideoPlayer.getThumbImageViewLayout().setOnClickListener(v -> {
if(onThumbImageClilckListener!=null){
onThumbImageClilckListener.onDxChanged(holder.getAbsoluteAdapterPosition());
}
});
if (isVideo) {
holder.gsyVideoPlayer.getThumbImageViewLayout().setOnClickListener(v -> {
if (onThumbImageClilckListener != null) {
onThumbImageClilckListener.onDxChanged(holder.getAbsoluteAdapterPosition());
}
});
} else {
holder.gsyVideoPlayer.getThumbImageViewLayout().setOnClickListener(null);
}
holder.gsyVideoPlayer.getFullscreenButton().setVisibility(isVideo ? View.VISIBLE : View.INVISIBLE);
holder.gsyVideoPlayer.getStartButton().setVisibility(isVideo ? View.VISIBLE : View.INVISIBLE);
holder.gsyVideoPlayer.showOrHideStartPlayButton(isVideo ? true : false);
holder.gsyVideoPlayer.setVideoAllCallBack(new GSYSampleCallBack(){
@Override
public void onAutoComplete(String url, Object... objects) {
@@ -105,13 +122,11 @@ public class RecyclerVideoAdapter extends RecyclerView.Adapter<RecyclerItemVideo
return itemDataList.size();
}
@Override
public int getItemViewType(int position) {
return 1;
}
public interface OnThumbImageClilckListener {
void onDxChanged(int targetPosition);
}

View File

@@ -527,5 +527,9 @@ class ConsultVideoPlayer : StandardGSYVideoPlayer {
fun getVideoAllCallBack(): VideoAllCallBack? {
return mVideoAllCallBack
}
fun showOrHideStartPlayButton(isShow: Boolean) {
aivStartPlay?.visibility = if (isShow ) View.VISIBLE else View.GONE
}
}

View File

@@ -148,26 +148,26 @@ android {
dimension "project"
buildConfigField 'boolean', 'secure', "true"
buildConfigField 'String', 'URLs', "\"${readFileToJson("mogo").replace("\"", "\\\"")}\""
buildConfigField 'String', 'tempConfig', "\"${readFileToJsonTemp("mogo").replace("\"", "\\\"")}\""
buildConfigField 'String', 'mediaUrlConfig', "\"${readMediaUrlConfigFromJsonFile("mogo").replace("\"", "\\\"")}\""
}
yantai {
dimension "project"
buildConfigField 'boolean', 'secure', "false"
buildConfigField 'String', 'URLs', "\"${readFileToJson("yantai").replace("\"", "\\\"")}\""
buildConfigField 'String', 'tempConfig', "\"${readFileToJsonTemp("yantai").replace("\"", "\\\"")}\""
buildConfigField 'String', 'mediaUrlConfig', "\"${readMediaUrlConfigFromJsonFile("yantai").replace("\"", "\\\"")}\""
}
dali {
dimension "project"
buildConfigField 'boolean', 'secure', "false"
buildConfigField 'String', 'URLs', "\"${readFileToJson("dali").replace("\"", "\\\"")}\""
buildConfigField 'String', 'tempConfig', "\"${readFileToJsonTemp("dali").replace("\"", "\\\"")}\""
buildConfigField 'String', 'mediaUrlConfig', "\"${readMediaUrlConfigFromJsonFile("dali").replace("\"", "\\\"")}\""
}
saas {
dimension "project"
buildConfigField 'boolean', 'secure', "false"
buildConfigField 'String', 'URLs', "\"${readFileToJson("saas").replace("\"", "\\\"")}\""
buildConfigField 'String', 'tempConfig', "\"${readFileToJsonTemp("saas").replace("\"", "\\\"")}\""
buildConfigField 'String', 'mediaUrlConfig', "\"${readMediaUrlConfigFromJsonFile("saas").replace("\"", "\\\"")}\""
}
// 配置网络环境QA、线上、演示
qa {
@@ -395,10 +395,15 @@ def variantName() {
}
Object readFileToJsonTemp(env){
/**
* 读取各车型宣传视频本地配置
* @param env
* @return
*/
Object readMediaUrlConfigFromJsonFile(env){
try {
// 加载config.json 文件
File file = new File("${rootDir}/app/config/tempConfig.json")
File file = new File("${rootDir}/app/config/MediaUrlConfig.json")
def jsonSlurper = new JsonSlurper()
// 解析json
def config = jsonSlurper.parse(file)

View File

@@ -0,0 +1,714 @@
{
"mogo": {
"shuttlepassengerochjl": {
"medias": [
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357256102/1.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "1"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"fileType": 1,
"coverImageUrl": "",
"title": "2"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357557335/3.mp4",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"title": "3"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "4"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357834634/5.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "5"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676358660379/6.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "6"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360154589/7.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "7"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360185500/8.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "8"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"fileType": 1,
"coverImageUrl": "",
"title": "9"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360274126/10.mp4",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"title": "10"
}
]
},
"buspassengerochjl": {
"medias": [
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357256102/1.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "1"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"fileType": 1,
"coverImageUrl": "",
"title": "2"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357557335/3.mp4",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"title": "3"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "4"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357834634/5.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "5"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676358660379/6.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "6"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360154589/7.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "7"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360185500/8.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "8"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"fileType": 1,
"coverImageUrl": "",
"title": "9"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360274126/10.mp4",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"title": "10"
}
]
},
"shuttlepassengerochm2": {
"medias": [
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681716116231/6923474a99a1983c9a0410ad3357888d.mov",
"fileType": 2,
"coverImageUrl": "",
"title": "1"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681716116231/6923474a99a1983c9a0410ad3357888d.mov",
"fileType": 2,
"coverImageUrl": "",
"title": "2"
}
]
},
"taxiunmannedpassengerochdfhq": {
"medias": [
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708596763/全车型混剪增加红旗车队.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969511280/车队.png",
"title": "蘑菇车联覆盖生活的方方面面"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708554279/红旗车队.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969553174/红旗重新排版.png",
"title": "蘑菇车联之红旗车队"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708499497/大运会合作解说版.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969536177/大运会.png",
"title": "蘑菇车联牵手成都大运会"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708409810/20210610重新排版3屏.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969579713/三屏.png",
"title": "多视角体验蘑菇车联自动驾驶"
}
]
},
"charterpassengerochm1": {
"medias": [
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708596763/全车型混剪增加红旗车队.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969511280/车队.png",
"title": "蘑菇车联覆盖生活的方方面面"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708554279/红旗车队.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969553174/红旗重新排版.png",
"title": "蘑菇车联之红旗车队"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708499497/大运会合作解说版.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969536177/大运会.png",
"title": "蘑菇车联牵手成都大运会"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708409810/20210610重新排版3屏.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969579713/三屏.png",
"title": "多视角体验蘑菇车联自动驾驶"
}
]
}
},
"dali": {
"shuttlepassengerochjl": {
"medias": [
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357256102/1.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "1"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"fileType": 1,
"coverImageUrl": "",
"title": "2"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357557335/3.mp4",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"title": "3"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "4"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357834634/5.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "5"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676358660379/6.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "6"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360154589/7.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "7"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360185500/8.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "8"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"fileType": 1,
"coverImageUrl": "",
"title": "9"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360274126/10.mp4",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"title": "10"
}
]
},
"buspassengerochjl": {
"medias": [
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357256102/1.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "1"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"fileType": 1,
"coverImageUrl": "",
"title": "2"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357557335/3.mp4",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"title": "3"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "4"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357834634/5.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "5"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676358660379/6.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "6"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360154589/7.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "7"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360185500/8.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "8"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"fileType": 1,
"coverImageUrl": "",
"title": "9"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360274126/10.mp4",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"title": "10"
}
]
},
"shuttlepassengerochm2": {
"medias": [
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681716116231/6923474a99a1983c9a0410ad3357888d.mov",
"fileType": 2,
"coverImageUrl": "",
"title": "1"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681716116231/6923474a99a1983c9a0410ad3357888d.mov",
"fileType": 2,
"coverImageUrl": "",
"title": "2"
}
]
},
"taxiunmannedpassengerochdfhq": {
"medias": [
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708596763/全车型混剪增加红旗车队.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969511280/车队.png",
"title": "蘑菇车联覆盖生活的方方面面"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708554279/红旗车队.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969553174/红旗重新排版.png",
"title": "蘑菇车联之红旗车队"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708499497/大运会合作解说版.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969536177/大运会.png",
"title": "蘑菇车联牵手成都大运会"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708409810/20210610重新排版3屏.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969579713/三屏.png",
"title": "多视角体验蘑菇车联自动驾驶"
}
]
},
"charterpassengerochm1": {
"medias": [
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708596763/全车型混剪增加红旗车队.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969511280/车队.png",
"title": "蘑菇车联覆盖生活的方方面面"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708554279/红旗车队.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969553174/红旗重新排版.png",
"title": "蘑菇车联之红旗车队"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708499497/大运会合作解说版.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969536177/大运会.png",
"title": "蘑菇车联牵手成都大运会"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708409810/20210610重新排版3屏.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969579713/三屏.png",
"title": "多视角体验蘑菇车联自动驾驶"
}
]
}
},
"yantai": {
"shuttlepassengerochjl": {
"medias": [
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681210971943/yangmadou.mp4",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1680774790614/yangmadao_photo.jpg",
"title": "1"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681210971943/yangmadou.mp4",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1680774790614/yangmadao_photo.jpg",
"title": "2"
}
]
},
"buspassengerochjl": {
"medias": [
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681210971943/yangmadou.mp4",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1680774790614/yangmadao_photo.jpg",
"title": "1"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681210971943/yangmadou.mp4",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1680774790614/yangmadao_photo.jpg",
"title": "2"
}
]
},
"shuttlepassengerochm2": {
"medias": [
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681716116231/6923474a99a1983c9a0410ad3357888d.mov",
"fileType": 2,
"coverImageUrl": "",
"title": "1"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681716116231/6923474a99a1983c9a0410ad3357888d.mov",
"fileType": 2,
"coverImageUrl": "",
"title": "2"
}
]
},
"taxiunmannedpassengerochdfhq": {
"medias": [
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708596763/全车型混剪增加红旗车队.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969511280/车队.png",
"title": "蘑菇车联覆盖生活的方方面面"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708554279/红旗车队.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969553174/红旗重新排版.png",
"title": "蘑菇车联之红旗车队"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708499497/大运会合作解说版.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969536177/大运会.png",
"title": "蘑菇车联牵手成都大运会"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708409810/20210610重新排版3屏.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969579713/三屏.png",
"title": "多视角体验蘑菇车联自动驾驶"
}
]
},
"charterpassengerochm1": {
"medias": [
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708596763/全车型混剪增加红旗车队.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969511280/车队.png",
"title": "蘑菇车联覆盖生活的方方面面"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708554279/红旗车队.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969553174/红旗重新排版.png",
"title": "蘑菇车联之红旗车队"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708499497/大运会合作解说版.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969536177/大运会.png",
"title": "蘑菇车联牵手成都大运会"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708409810/20210610重新排版3屏.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969579713/三屏.png",
"title": "多视角体验蘑菇车联自动驾驶"
}
]
}
},
"saas": {
"shuttlepassengerochjl": {
"medias": [
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357256102/1.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "1"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"fileType": 1,
"coverImageUrl": "",
"title": "2"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357557335/3.mp4",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"title": "3"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "4"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357834634/5.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "5"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676358660379/6.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "6"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360154589/7.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "7"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360185500/8.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "8"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"fileType": 1,
"coverImageUrl": "",
"title": "9"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360274126/10.mp4",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"title": "10"
}
]
},
"buspassengerochjl": {
"medias": [
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357256102/1.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "1"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"fileType": 1,
"coverImageUrl": "",
"title": "2"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357557335/3.mp4",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"title": "3"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "4"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357834634/5.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "5"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676358660379/6.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "6"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360154589/7.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "7"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360185500/8.jpg",
"fileType": 1,
"coverImageUrl": "",
"title": "8"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"fileType": 1,
"coverImageUrl": "",
"title": "9"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360274126/10.mp4",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"title": "10"
}
]
},
"shuttlepassengerochm2": {
"medias": [
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681716116231/6923474a99a1983c9a0410ad3357888d.mov",
"fileType": 2,
"coverImageUrl": "",
"title": "1"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681716116231/6923474a99a1983c9a0410ad3357888d.mov",
"fileType": 2,
"coverImageUrl": "",
"title": "2"
}
]
},
"taxiunmannedpassengerochdfhq": {
"medias": [
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708596763/全车型混剪增加红旗车队.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969511280/车队.png",
"title": "蘑菇车联覆盖生活的方方面面"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708554279/红旗车队.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969553174/红旗重新排版.png",
"title": "蘑菇车联之红旗车队"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708499497/大运会合作解说版.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969536177/大运会.png",
"title": "蘑菇车联牵手成都大运会"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708409810/20210610重新排版3屏.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969579713/三屏.png",
"title": "多视角体验蘑菇车联自动驾驶"
}
]
},
"charterpassengerochm1": {
"medias": [
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708596763/全车型混剪增加红旗车队.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969511280/车队.png",
"title": "蘑菇车联覆盖生活的方方面面"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708554279/红旗车队.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969553174/红旗重新排版.png",
"title": "蘑菇车联之红旗车队"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708499497/大运会合作解说版.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969536177/大运会.png",
"title": "蘑菇车联牵手成都大运会"
},
{
"fileUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708409810/20210610重新排版3屏.m4v",
"fileType": 2,
"coverImageUrl": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969579713/三屏.png",
"title": "多视角体验蘑菇车联自动驾驶"
}
]
}
}
}

View File

@@ -1,490 +0,0 @@
{
"mogo": {
"shuttlepassengerochjl": {
"ads": [
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357256102/1.jpg",
"type": 0,
"cacheImgPath": "",
"title": "1"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"type": 0,
"cacheImgPath": "",
"title": "2"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357557335/3.mp4",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"title": "3"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"type": 0,
"cacheImgPath": "",
"title": "4"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357834634/5.m4v",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "5"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676358660379/6.m4v",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "6"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360154589/7.jpg",
"type": 0,
"cacheImgPath": "",
"title": "7"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360185500/8.jpg",
"type": 0,
"cacheImgPath": "",
"title": "8"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"type": 0,
"cacheImgPath": "",
"title": "9"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360274126/10.mp4",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"title": "10"
}
]
},
"buspassengerochjl": {
"ads": [
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357256102/1.jpg",
"type": 0,
"cacheImgPath": "",
"title": "1"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"type": 0,
"cacheImgPath": "",
"title": "2"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357557335/3.mp4",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"title": "3"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"type": 0,
"cacheImgPath": "",
"title": "4"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357834634/5.m4v",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "5"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676358660379/6.m4v",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "6"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360154589/7.jpg",
"type": 0,
"cacheImgPath": "",
"title": "7"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360185500/8.jpg",
"type": 0,
"cacheImgPath": "",
"title": "8"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"type": 0,
"cacheImgPath": "",
"title": "9"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360274126/10.mp4",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"title": "10"
}
]
},
"shuttlepassengerochm2": {
"ads": [
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681716116231/6923474a99a1983c9a0410ad3357888d.mov",
"type": 1,
"cacheImgPath": "",
"title": "1"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681716116231/6923474a99a1983c9a0410ad3357888d.mov",
"type": 1,
"cacheImgPath": "",
"title": "2"
}
]
}
},
"dali": {
"shuttlepassengerochjl": {
"ads": [
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357256102/1.jpg",
"type": 0,
"cacheImgPath": "",
"title": "1"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"type": 0,
"cacheImgPath": "",
"title": "2"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357557335/3.mp4",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"title": "3"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"type": 0,
"cacheImgPath": "",
"title": "4"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357834634/5.m4v",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "5"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676358660379/6.m4v",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "6"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360154589/7.jpg",
"type": 0,
"cacheImgPath": "",
"title": "7"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360185500/8.jpg",
"type": 0,
"cacheImgPath": "",
"title": "8"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"type": 0,
"cacheImgPath": "",
"title": "9"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360274126/10.mp4",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"title": "10"
}
]
},
"buspassengerochjl": {
"ads": [
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357256102/1.jpg",
"type": 0,
"cacheImgPath": "",
"title": "1"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"type": 0,
"cacheImgPath": "",
"title": "2"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357557335/3.mp4",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"title": "3"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"type": 0,
"cacheImgPath": "",
"title": "4"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357834634/5.m4v",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "5"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676358660379/6.m4v",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "6"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360154589/7.jpg",
"type": 0,
"cacheImgPath": "",
"title": "7"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360185500/8.jpg",
"type": 0,
"cacheImgPath": "",
"title": "8"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"type": 0,
"cacheImgPath": "",
"title": "9"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360274126/10.mp4",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"title": "10"
}
]
},
"shuttlepassengerochm2": {
"ads": [
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681716116231/6923474a99a1983c9a0410ad3357888d.mov",
"type": 1,
"cacheImgPath": "",
"title": "1"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681716116231/6923474a99a1983c9a0410ad3357888d.mov",
"type": 1,
"cacheImgPath": "",
"title": "2"
}
]
}
},
"yantai": {
"shuttlepassengerochjl": {
"ads": [
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681210971943/yangmadou.mp4",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1680774790614/yangmadao_photo.jpg",
"title": "1"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681210971943/yangmadou.mp4",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1680774790614/yangmadao_photo.jpg",
"title": "2"
}
]
},
"buspassengerochjl": {
"ads": [
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681210971943/yangmadou.mp4",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1680774790614/yangmadao_photo.jpg",
"title": "1"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681210971943/yangmadou.mp4",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1680774790614/yangmadao_photo.jpg",
"title": "2"
}
]
},
"shuttlepassengerochm2": {
"ads": [
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681716116231/6923474a99a1983c9a0410ad3357888d.mov",
"type": 1,
"cacheImgPath": "",
"title": "1"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681716116231/6923474a99a1983c9a0410ad3357888d.mov",
"type": 1,
"cacheImgPath": "",
"title": "2"
}
]
}
},
"saas": {
"shuttlepassenger": {
"ads": [
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357256102/1.jpg",
"type": 0,
"cacheImgPath": "",
"title": "1"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"type": 0,
"cacheImgPath": "",
"title": "2"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357557335/3.mp4",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"title": "3"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"type": 0,
"cacheImgPath": "",
"title": "4"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357834634/5.m4v",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "5"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676358660379/6.m4v",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "6"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360154589/7.jpg",
"type": 0,
"cacheImgPath": "",
"title": "7"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360185500/8.jpg",
"type": 0,
"cacheImgPath": "",
"title": "8"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"type": 0,
"cacheImgPath": "",
"title": "9"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360274126/10.mp4",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"title": "10"
}
]
},
"buspassenger": {
"ads": [
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357256102/1.jpg",
"type": 0,
"cacheImgPath": "",
"title": "1"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"type": 0,
"cacheImgPath": "",
"title": "2"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357557335/3.mp4",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
"title": "3"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"type": 0,
"cacheImgPath": "",
"title": "4"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357834634/5.m4v",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "5"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676358660379/6.m4v",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
"title": "6"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360154589/7.jpg",
"type": 0,
"cacheImgPath": "",
"title": "7"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360185500/8.jpg",
"type": 0,
"cacheImgPath": "",
"title": "8"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"type": 0,
"cacheImgPath": "",
"title": "9"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360274126/10.mp4",
"type": 1,
"cacheImgPath": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
"title": "10"
}
]
},
"shuttlepassengerm2": {
"ads": [
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681716116231/6923474a99a1983c9a0410ad3357888d.mov",
"type": 1,
"cacheImgPath": "",
"title": "1"
},
{
"path": "https://img.zhidaohulian.com/fileServer/online_car_hailing/1681716116231/6923474a99a1983c9a0410ad3357888d.mov",
"type": 1,
"cacheImgPath": "",
"title": "2"
}
]
}
}
}

View File

@@ -46,8 +46,8 @@ object ConfigStartUp {
FunctionBuildConfig.urlJson = GsonUtils.fromJson(BuildConfig.URLs, UrlConfig::class.java)
//不能启动自动驾驶的档位
FunctionBuildConfig.unableLaunchAutopilotGear = BuildConfig.UNABLE_LAUNCH_AUTOPILOT_GEAR
// 临时配置json
FunctionBuildConfig.tempConfig = BuildConfig.tempConfig
// 各车型宣传视频本地配置json
FunctionBuildConfig.mediaUrlConfig = BuildConfig.mediaUrlConfig
//是否支持Patch升级
FunctionBuildConfig.isSupportPatchUpgrade = BuildConfig.IS_SUPPORT_PATCH_UPGRADE

View File

@@ -109,13 +109,12 @@ object FunctionBuildConfig {
var appIdentityMode = "Taxi_Driver_Base"
/**
* 临时配置json
* 各车型宣传视频本地配置
* 广告json
*
*/
@Volatile
@JvmField
var tempConfig = ""
var mediaUrlConfig = ""
/**

View File

@@ -152,11 +152,11 @@ NOOP_DRIVER_VERSION=3.2.0
# 公交模式司机端版本号
BUS_DRIVER_VERSION=6.2.4
# 公交模式乘客端端版本号
BUS_PASSENGER_VERSION=5.2.4
BUS_PASSENGER_VERSION=5.2.5
# 接驳模式司机端版本号
SHUTTLE_DRIVER_VERSION=6.2.4
# 接驳模式乘客端端版本号
SHUTTLE_PASSENGER_VERSION=5.2.4
SHUTTLE_PASSENGER_VERSION=5.2.5
# 出租车模式司机端版本号
TAXI_DRIVER_VERSION=6.2.4
# 出租车模式乘客端端版本号
@@ -165,12 +165,12 @@ TAXI_PASSENGER_VERSION=5.2.4
# 出租车模式司机端版本号
TAXIUNMANNED_DRIVER_VERSION=6.2.4
# 出租车模式乘客端端版本号
TAXIUNMANNED_PASSENGER_VERSION=5.2.4
TAXIUNMANNED_PASSENGER_VERSION=5.2.5
# 包车模式司机端版本号
CHARTER_DRIVER_VERSION=6.2.4
# 包车模式乘客端端版本号
CHARTER_PASSENGER_VERSION=5.2.4
CHARTER_PASSENGER_VERSION=5.2.5
# 支持云控清扫车模式司机端版本号
SWEEPERCLOUD_DRIVER_VERSION=6.2.4
# 清扫车模式司机端版本号