/* * Copyright (C) 2020 Stefan Schüller * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ package net.schueller.peertube.fragment; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.IBinder; import android.preference.PreferenceManager; import android.util.Log; import android.view.GestureDetector; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.Surface; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import com.github.se_bastiaan.torrentstream.StreamStatus; import com.github.se_bastiaan.torrentstream.Torrent; import com.github.se_bastiaan.torrentstream.TorrentOptions; import com.github.se_bastiaan.torrentstream.TorrentStream; import com.github.se_bastiaan.torrentstream.listeners.TorrentListener; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.decoder.DecoderCounters; import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; import com.google.android.exoplayer2.ui.PlayerView; import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.video.VideoRendererEventListener; import com.mikepenz.iconics.Iconics; import net.schueller.peertube.R; import net.schueller.peertube.helper.APIUrlHelper; import net.schueller.peertube.helper.ErrorHelper; import net.schueller.peertube.model.File; import net.schueller.peertube.model.Video; import net.schueller.peertube.network.GetVideoDataService; import net.schueller.peertube.network.RetrofitInstance; import net.schueller.peertube.service.VideoPlayerService; import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; import androidx.fragment.app.Fragment; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import static net.schueller.peertube.helper.VideoHelper.canEnterPipMode; public class VideoPlayerFragment extends Fragment implements VideoRendererEventListener { private String mVideoUuid; private ProgressBar progressBar; private PlayerView simpleExoPlayerView; private Intent videoPlayerIntent; private Boolean mBound = false; private Boolean isFullscreen = false; private VideoPlayerService mService; private TorrentStream torrentStream; private LinearLayout torrentStatus; private float aspectRatio; private static final String TAG = "VideoPlayerFragment"; private GestureDetector mDetector; private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName className, IBinder service) { Log.d(TAG, "onServiceConnected"); VideoPlayerService.LocalBinder binder = (VideoPlayerService.LocalBinder) service; mService = binder.getService(); // 2. Create the player simpleExoPlayerView.setPlayer(mService.player); mBound = true; loadVideo(); } @Override public void onServiceDisconnected(ComponentName componentName) { Log.d(TAG, "onServiceDisconnected"); simpleExoPlayerView.setPlayer(null); mBound = false; } }; private AspectRatioFrameLayout.AspectRatioListener aspectRatioListerner = new AspectRatioFrameLayout.AspectRatioListener() { @Override public void onAspectRatioUpdated( float targetAspectRatio, float naturalAspectRatio, boolean aspectRatioMismatch ) { aspectRatio = targetAspectRatio; } }; @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_video_player, container, false); } public void start(String videoUuid) { // start service Context context = getContext(); Activity activity = getActivity(); mVideoUuid = videoUuid; assert activity != null; progressBar = activity.findViewById(R.id.torrent_progress); progressBar.setMax(100); assert context != null; simpleExoPlayerView = new PlayerView(context); simpleExoPlayerView = activity.findViewById(R.id.video_view); simpleExoPlayerView.setControllerShowTimeoutMs(1000); simpleExoPlayerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIT); mDetector = new GestureDetector(context, new MyGestureListener()); simpleExoPlayerView.setOnTouchListener(touchListener); simpleExoPlayerView.setAspectRatioListener( aspectRatioListerner ); torrentStatus = activity.findViewById(R.id.exo_torrent_status); // Full screen Icon TextView fullscreenText = activity.findViewById(R.id.exo_fullscreen); FrameLayout fullscreenButton = activity.findViewById(R.id.exo_fullscreen_button); fullscreenText.setText(R.string.video_expand_icon); new Iconics.Builder().on(fullscreenText).build(); fullscreenButton.setOnClickListener(view -> { Log.d(TAG, "Fullscreen"); fullScreenToggle(); }); if (!mBound) { videoPlayerIntent = new Intent(context, VideoPlayerService.class); activity.bindService(videoPlayerIntent, mConnection, Context.BIND_AUTO_CREATE); } } private void loadVideo() { Context context = getContext(); // get video details from api String apiBaseURL = APIUrlHelper.getUrlWithVersion(context); GetVideoDataService service = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(context)).create(GetVideoDataService.class); Call