如何在列表 exoplayer 中自动播放下一个视频 android

how to play next video automatically in list exoplayer android

我正在 android 工作室创建电影流媒体应用程序,我使用过 recyclerview 和 exoplayer。一切都很完美,最后一点就是剧集创作。我想在视频中添加剧集并在当前视频完成后自动播放它们,就像 youtube 播放器一样。 我正在添加我的 json 文件,主要 activity 视频播放器 activity 以供参考。

我知道的是 我可以在电影 activity 中创建另一个回收器(我会在 recyclerview 中显示我所有的剧集列表)

我需要为这个剧集列表创建一个模型和新的适配器文件,我想我必须为此创建单独的 JSon 数据,因为它与 rest

不同且特定

主要Activity。 java 计划

package com.threeminutesfix.gospelvideos;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.widget.NestedScrollView;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager.widget.ViewPager;

import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import com.threeminutesfix.gospelvideos.Utility.NetworkChangeListerner;
import com.threeminutesfix.gospelvideos.adapter.BannerMoviesPagerAdapter;
import com.threeminutesfix.gospelvideos.adapter.ItemRecyclerAdapter;
import com.threeminutesfix.gospelvideos.adapter.MainRecyclerAdapter;
import com.threeminutesfix.gospelvideos.model.AllCategory;
import com.threeminutesfix.gospelvideos.model.BannerMovies;
import com.threeminutesfix.gospelvideos.retrofit.RetrofitClient;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.tabs.TabLayout;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.observers.DisposableObserver;
import io.reactivex.schedulers.Schedulers;

public class MainActivity extends AppCompatActivity {

    BannerMoviesPagerAdapter bannerMoviesPagerAdapter;
    NetworkChangeListerner networkChangeListerner = new NetworkChangeListerner();

    TabLayout IndicatorTab, categoryTab;
    ViewPager bannerMoviesViewpager;
    List<BannerMovies> homeBannerList;
    List<BannerMovies> tvBannerList;
    List<BannerMovies> songBannerList;
    List<BannerMovies> audioBannerList;
    NestedScrollView nestedScrollView;
    AppBarLayout appBarLayout;
    MainRecyclerAdapter mainRecyclerAdapter;
    RecyclerView mainRecycler;
    List<AllCategory> allCategoryList;
    ItemRecyclerAdapter itemRecyclerAdapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Objects.requireNonNull(getSupportActionBar()).setLogo(R.drawable.main_logo);
        getSupportActionBar().setDisplayUseLogoEnabled(true);
        IndicatorTab = findViewById(R.id.tab_indicator);
        categoryTab = findViewById(R.id.tabLayout);
        nestedScrollView = findViewById(R.id.nested_scroll);
        appBarLayout = findViewById(R.id.appbar);
        homeBannerList = new ArrayList<>();
        tvBannerList = new ArrayList<>();
        songBannerList = new ArrayList<>();
        audioBannerList = new ArrayList<>();
        getBannerData();
        getAllMoviesData(1);

        categoryTab.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                switch (tab.getPosition()) {
                    case 1:

                        setBannerMoviesPagerAdapter(tvBannerList);
                        getAllMoviesData(2);


                        return;
                    case 2:

                        setBannerMoviesPagerAdapter(songBannerList);
                        getAllMoviesData(3);

                        return;

                    case 3:

                        setBannerMoviesPagerAdapter(audioBannerList);
                        getAllMoviesData(4);
                        return;
                    default:

                        setBannerMoviesPagerAdapter(homeBannerList);
                        getAllMoviesData(1);


                }

            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });


        //titles
        allCategoryList = new ArrayList<>();


    }



    private void setBannerMoviesPagerAdapter(List<BannerMovies> bannerMoviesList) {
        bannerMoviesViewpager = findViewById(R.id.banner_viewPager);
        bannerMoviesPagerAdapter = new BannerMoviesPagerAdapter(this, bannerMoviesList);
        bannerMoviesViewpager.setAdapter(bannerMoviesPagerAdapter);
        IndicatorTab.setupWithViewPager(bannerMoviesViewpager);


    }


    public void setMainRecycler(List<AllCategory> allCategoryList) {
        mainRecycler = findViewById(R.id.main_recycler);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
        mainRecycler.setLayoutManager(layoutManager);
        mainRecyclerAdapter = new MainRecyclerAdapter(this, allCategoryList);
        mainRecycler.setAdapter(mainRecyclerAdapter);
        mainRecyclerAdapter.notifyDataSetChanged();
    }

    private void getBannerData() {
        CompositeDisposable compositeDisposable = new CompositeDisposable();
        compositeDisposable.add(RetrofitClient.getRetroFitClient().getAllBanners()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeWith(new DisposableObserver<List<BannerMovies>>() {
                    @Override
                    public void onNext(List<BannerMovies> bannerMovies) {
                        for (int i = 0; i < bannerMovies.size(); i++) {
                            if (bannerMovies.get(i).getBannerCategoryId().toString().equals("1")) {
                                homeBannerList.add(bannerMovies.get(i));

                            } else if (bannerMovies.get(i).getBannerCategoryId().toString().equals("2")) {
                                tvBannerList.add(bannerMovies.get(i));

                            } else if (bannerMovies.get(i).getBannerCategoryId().toString().equals("3")) {
                                songBannerList.add(bannerMovies.get(i));

                            } else if (bannerMovies.get(i).getBannerCategoryId().toString().equals("4")) {
                                audioBannerList.add(bannerMovies.get(i));

                            } else {
                                homeBannerList.add(bannerMovies.get(i));
                            }


                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d("bannerData", "" + e);
                    }

                    @Override
                    public void onComplete() {
                        setBannerMoviesPagerAdapter(homeBannerList);
                    }
                })

        );
    }

    private void getAllMoviesData(Integer categoryId) {
        CompositeDisposable compositeDisposable = new CompositeDisposable();
        compositeDisposable.add(RetrofitClient.getRetroFitClient().getAllCategoryMovies(categoryId)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeWith(new DisposableObserver<List<AllCategory>>() {
                    @Override
                    public void onNext(List<AllCategory> allCategoryList) {
                        for (int i = 0; i < allCategoryList.size(); i++) {
                            setMainRecycler(allCategoryList);
                        }


                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d("bannerData", "" + e);
                    }

                    @Override
                    public void onComplete() {

                    }
                })

        );
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main_menu,menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        int id = item.getItemId();
        switch (id){
            case R.id.refresh_folders:
                finish();
                startActivity(getIntent());
                break;
            case R.id.share_app:
                Intent share_intent= new Intent();
                share_intent.setAction(Intent.ACTION_SEND);
                share_intent.putExtra(Intent.EXTRA_TEXT,"check this app via \n"+"https://play.google.com/store/apps/details?id="+getApplicationContext().getPackageName());
                share_intent.setType("text/plain");
                startActivity(Intent.createChooser(share_intent,"Share App via"));
                break;
        }
        return true;
    }

    private boolean doubleBackToExitPressedOnce = false;

    @Override
    protected void onResume() {
        super.onResume();
        // .... other stuff in my onResume ....
        this.doubleBackToExitPressedOnce = false;
    }

    @Override
    public void onBackPressed() {
        if (doubleBackToExitPressedOnce) {
            super.onBackPressed();
            return;
        }
        this.doubleBackToExitPressedOnce = true;
        Toast.makeText(this, R.string.exit_press_back_twice_message, Toast.LENGTH_SHORT).show();

    }

    @Override
    protected void onStart() {
        IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver(networkChangeListerner,filter);

        super.onStart();
    }

    @Override
    protected void onStop() {
        unregisterReceiver(networkChangeListerner);
        super.onStop();
    }

}

电影Details.java

package com.threeminutesfix.gospelvideos;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.widget.NestedScrollView;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.threeminutesfix.gospelvideos.Utility.NetworkChangeListerner;
import com.threeminutesfix.gospelvideos.adapter.SimilarRecyclerAdapter;
import com.threeminutesfix.gospelvideos.model.AllCategory;
import com.threeminutesfix.gospelvideos.retrofit.RetrofitClient;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.observers.DisposableObserver;
import io.reactivex.schedulers.Schedulers;

public class MovieDetails extends AppCompatActivity
{
    RecyclerView mainRecycler;
    TextView video_timer;
    ImageView movieImage;
    ImageView MovieThumb;
    TextView movieName;
    TextView movieDesc;
    TextView Language;
    TextView Singers;
    Button playButton;
    List<AllCategory> allCategoryList;
    NestedScrollView nestedScrollView;
     ImageView Trailer;
    String mName;
    String mImage;
    String mId;
    String mFileUrl;
    String subFileUrl;
    String Msmall;
    String Mdesc;
    String Mlang;
    String Msinger;
    String Vtimer;
    String Turl;
    int CatId;
    NetworkChangeListerner networkChangeListerner = new NetworkChangeListerner();
   SimilarRecyclerAdapter similarRecyclerAdapter;
    @SuppressLint("CutPasteId")
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_movie_details);
        movieImage = findViewById(R.id.movie_image);
        movieName = findViewById(R.id.movie_name);
        movieDesc=findViewById(R.id.desc);
        playButton = findViewById(R.id.play_button);
        Trailer=findViewById(R.id.Trailer);
        video_timer= findViewById(R.id.video_timer);
        MovieThumb=findViewById(R.id.smallThumb);
        Language=findViewById(R.id.Language);
        Singers=findViewById(R.id.Singer);
        nestedScrollView= findViewById(R.id.scroll_movie);
        mName = getIntent().getStringExtra("movieName");
        mImage = getIntent().getStringExtra("movieImageUrl");
        mFileUrl = getIntent().getStringExtra("movieFile");
        Msmall=getIntent().getStringExtra("smallThumb");
        Mdesc=getIntent().getStringExtra("MovieDesc");
        Mlang=getIntent().getStringExtra("Language");
        Msinger=getIntent().getStringExtra("Singers");
        Turl=getIntent().getStringExtra("TrailerUrl");
        subFileUrl=getIntent().getStringExtra("SrtUrl");
        Vtimer= getIntent().getStringExtra("VideoTiming");
        setTitle(mName);
        Glide.with(this).load(mImage).placeholder(R.drawable.film).into(movieImage);
        Glide.with(this).load(Msmall).placeholder(R.drawable.thumb).into(MovieThumb);
        Glide.with(this).load(mImage).placeholder(R.drawable.thumb).into(Trailer);
        movieName.setText(mName);
        movieDesc.setText(Mdesc);
        Language.setText(Mlang);
        Singers.setText(Msinger);
        video_timer.setText(Vtimer);
        CatId = getIntent().getIntExtra("categoryId", 0);
        getMovies(CatId);
        allCategoryList = new ArrayList<>();

        playButton.setOnClickListener(v -> {
            if(mFileUrl==null) {
                Toast.makeText(this, "Error Occurred while fetching this video. try again later or restart this app", Toast.LENGTH_LONG).show();
            }
            else{
                Intent i = new Intent(MovieDetails.this, VideoPlayerActivity
                        .class);
                i.putExtra("movieId", mId);
                i.putExtra("url", mFileUrl);
                i.putExtra("movieName", mName);
                i.putExtra("MovieThumb", Msmall);
                i.putExtra("SrtUrl",subFileUrl);
                startActivity(i);

            }
        });
        Trailer.setOnClickListener(v -> {
            if (Turl == null)
            {
                Toast.makeText(this, "Trailer not available or not added by original owners", Toast.LENGTH_LONG).show();
            }
            else{
            Intent i = new Intent(MovieDetails.this, TrailerActivity.class);
            i.putExtra("url", Turl);
            i.putExtra("movieName",mName);
            startActivity(i);
            }
 });

}


    @Override
    protected void onStart() {
        IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver(networkChangeListerner,filter);
        super.onStart();
    }

    @Override
    protected void onStop() {
        unregisterReceiver(networkChangeListerner);
        super.onStop();
    }
    public void setMainRecycler(List<AllCategory> allCategoryList) {
        mainRecycler = findViewById(R.id.Similar_rv);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
        mainRecycler.setLayoutManager(layoutManager);
        similarRecyclerAdapter = new SimilarRecyclerAdapter(this, allCategoryList);
        mainRecycler.setAdapter(similarRecyclerAdapter);
        similarRecyclerAdapter.notifyDataSetChanged();
    }

    private void getMovies(Integer categoryId) {
        CompositeDisposable compositeDisposable = new CompositeDisposable();
        compositeDisposable.add(RetrofitClient.getRetroFitClient2().getMovies(categoryId)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeWith(new DisposableObserver<List<AllCategory>>() {
                    @Override
                    public void onNext(List<AllCategory> allCategoryList) {
                        for (int i = 0; i < allCategoryList.size(); i++) {
                            setMainRecycler(allCategoryList);
                        }


                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d("bannerData", "" + e);
                    }

                    @Override
                    public void onComplete() {

                    }
                })

        );
    }


}

categoryItemlist.java(模型文件)

package com.threeminutesfix.gospelvideos.model;

import java.io.Serializable;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class AllCategory implements Serializable {

    @SerializedName("categoryId")
    @Expose
    private Integer categoryId;
    @SerializedName("categoryTitle")
    @Expose
    private String categoryTitle;
    @SerializedName("categoryImage")
    @Expose
    private String categoryImage;
    @SerializedName("categoryItemList")
    @Expose
    private List<CategoryItemList> categoryItemList = null;

    public Integer getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(Integer categoryId) {
        this.categoryId = categoryId;
    }

    public String getCategoryTitle() {
        return categoryTitle;
    }

    public void setCategoryTitle(String categoryTitle) {
        this.categoryTitle = categoryTitle;
    }

    public String getCategoryImage() {
        return categoryImage;
    }

    public void setCategoryImage(String categoryImage) {
        this.categoryImage = categoryImage;
    }

    public List<CategoryItemList> getCategoryItemList() {
        return categoryItemList;
    }

    public void setCategoryItemList(List<CategoryItemList> categoryItemList) {
        this.categoryItemList = categoryItemList;
    }

}
所有类别(模型文件)

package com.threeminutesfix.gospelvideos.model;

import java.io.Serializable;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class AllCategory implements Serializable {

    @SerializedName("categoryId")
    @Expose
    private Integer categoryId;
    @SerializedName("categoryTitle")
    @Expose
    private String categoryTitle;
    @SerializedName("categoryImage")
    @Expose
    private String categoryImage;
    @SerializedName("categoryItemList")
    @Expose
    private List<CategoryItemList> categoryItemList = null;

    public Integer getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(Integer categoryId) {
        this.categoryId = categoryId;
    }

    public String getCategoryTitle() {
        return categoryTitle;
    }

    public void setCategoryTitle(String categoryTitle) {
        this.categoryTitle = categoryTitle;
    }

    public String getCategoryImage() {
        return categoryImage;
    }

    public void setCategoryImage(String categoryImage) {
        this.categoryImage = categoryImage;
    }

    public List<CategoryItemList> getCategoryItemList() {
        return categoryItemList;
    }

    public void setCategoryItemList(List<CategoryItemList> categoryItemList) {
        this.categoryItemList = categoryItemList;
    }

}

Json data (backend of my app

准备好根据需要添加更多文件

按照以下步骤非常简单:-

1]将您的所有视频添加到列表并将该列表设置为您的 exo 播放器对象,如下所示

    for (i in videoList.indices){
        var songPath:String = videoList.get(i)
        val item: MediaItem = MediaItem.fromUri(songPath)
        exoPlayerManager.addMediaItem(item)
    }
  exoPlayerManager.prepare()
  exoPlayerManager.play()

2]Add/enable下一个,xml布局中的上一个开关

<com.google.android.exoplayer2.ui.PlayerView
    android:id="@+id/playerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:keepScreenOn="true"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="@id/playerViewFrameLayout"
    app:repeat_toggle_modes="all"
    app:controller_layout_id="@layout/exo_playback_control_view"
    app:resize_mode="fit"
    app:show_buffering="always"
    app:show_shuffle_button="true"
    />

3] 只需单击媒体控制器中的下一步按钮检查是否有效,那么您就完成了,现在视频将在当前视频播放完毕后自动播放。