From 4c6601237247c05ad7b823728db0dcc492a4febd Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 22 Jul 2024 11:12:36 +0200 Subject: [PATCH] Fixed video player aspect ratio --- .../fragment/MediaViewerFragment.kt | 9 +++ .../ui/file_viewer/view/RatioTextureView.kt | 74 +++++++++++++++++++ .../file_viewer/viewmodel/MediaViewModel.kt | 8 ++ .../file_media_viewer_child_fragment.xml | 4 +- 4 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/org/linphone/ui/file_viewer/view/RatioTextureView.kt diff --git a/app/src/main/java/org/linphone/ui/file_viewer/fragment/MediaViewerFragment.kt b/app/src/main/java/org/linphone/ui/file_viewer/fragment/MediaViewerFragment.kt index d48ea451d..64370e8d4 100644 --- a/app/src/main/java/org/linphone/ui/file_viewer/fragment/MediaViewerFragment.kt +++ b/app/src/main/java/org/linphone/ui/file_viewer/fragment/MediaViewerFragment.kt @@ -86,6 +86,15 @@ class MediaViewerFragment : GenericMainFragment() { val fullScreenMode = viewModel.toggleFullScreen() sharedViewModel.mediaViewerFullScreenMode.value = fullScreenMode } + + viewModel.videoSizeChangedEvent.observe(viewLifecycleOwner) { + it.consume { pair -> + val width = pair.first + val height = pair.second + Log.i("$TAG Updating video texture ration to ${width}x$height") + binding.videoPlayer.setAspectRatio(width, height) + } + } } override fun onResume() { diff --git a/app/src/main/java/org/linphone/ui/file_viewer/view/RatioTextureView.kt b/app/src/main/java/org/linphone/ui/file_viewer/view/RatioTextureView.kt new file mode 100644 index 000000000..aa6bcc84b --- /dev/null +++ b/app/src/main/java/org/linphone/ui/file_viewer/view/RatioTextureView.kt @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2010-2024 Belledonne Communications SARL. + * + * This file is part of linphone-android + * (see https://www.linphone.org). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.linphone.ui.file_viewer.view + +import android.content.Context +import android.util.AttributeSet +import android.view.TextureView + +class RatioTextureView : TextureView { + companion object { + private const val TAG = "[Ratio TextureView]" + } + + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super( + context, + attrs, + defStyleAttr + ) + + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super( + context, + attrs, + defStyleAttr, + defStyleRes + ) + + private var ratioWidth = 0 + private var rationHeight = 0 + + fun setAspectRatio(width: Int, height: Int) { + if (width < 0 || height < 0) return + + ratioWidth = width + rationHeight = height + requestLayout() + } + + override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec) + val width = MeasureSpec.getSize(widthMeasureSpec) + val height = MeasureSpec.getSize(heightMeasureSpec) + + if (ratioWidth == 0 || rationHeight == 0) { + setMeasuredDimension(width, height) + } else { + if (width < height * ratioWidth / rationHeight) { + setMeasuredDimension(width, width * rationHeight / ratioWidth) + } else { + setMeasuredDimension(height * ratioWidth / rationHeight, height) + } + } + } +} diff --git a/app/src/main/java/org/linphone/ui/file_viewer/viewmodel/MediaViewModel.kt b/app/src/main/java/org/linphone/ui/file_viewer/viewmodel/MediaViewModel.kt index 5781d8901..f9aee49fc 100644 --- a/app/src/main/java/org/linphone/ui/file_viewer/viewmodel/MediaViewModel.kt +++ b/app/src/main/java/org/linphone/ui/file_viewer/viewmodel/MediaViewModel.kt @@ -31,6 +31,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.linphone.core.tools.Log import org.linphone.ui.GenericViewModel +import org.linphone.utils.Event import org.linphone.utils.FileUtils import org.linphone.utils.TimestampUtils @@ -59,6 +60,10 @@ class MediaViewModel @UiThread constructor() : GenericViewModel() { val position = MutableLiveData() + val videoSizeChangedEvent: MutableLiveData>> by lazy { + MutableLiveData>>() + } + lateinit var mediaPlayer: MediaPlayer private lateinit var filePath: String @@ -168,6 +173,9 @@ class MediaViewModel @UiThread constructor() : GenericViewModel() { // Leave full screen when playback is done fullScreenMode.postValue(false) } + setOnVideoSizeChangedListener { mediaPlayer, width, height -> + videoSizeChangedEvent.postValue(Event(Pair(width, height))) + } prepare() } diff --git a/app/src/main/res/layout/file_media_viewer_child_fragment.xml b/app/src/main/res/layout/file_media_viewer_child_fragment.xml index fd3610756..eeae9f024 100644 --- a/app/src/main/res/layout/file_media_viewer_child_fragment.xml +++ b/app/src/main/res/layout/file_media_viewer_child_fragment.xml @@ -25,9 +25,9 @@ android:visibility="@{viewModel.fullScreenMode ? View.GONE : viewModel.isAudio || viewModel.isVideo ? View.VISIBLE : View.GONE}" app:constraint_referenced_ids="play_pause_audio_playback, progress, duration" /> -