2017-08-03 386 views
1

我已经实现了播放器,现在有一个问题。当视频播放时,如果应用程序关闭并恢复,视频屏幕会冻结。我甚至看到Google的ExoPlayer演示活动,以便更好地理解,但我无法通过它在我的应用中实现。我已经在这里附加了Player Activity和完整的代码,我将共享所有文件的GitHub存储库。ExoPlayer onResume()恢复播放状态

RecipeStepDetailFragment.java

package com.example.android.recipe.ui; 

import android.content.Context; 
import android.content.res.Configuration; 
import android.net.Uri; 
import android.os.Bundle; 
import android.os.Handler; 
import android.support.v4.app.Fragment; 
import android.support.v4.content.ContextCompat; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Button; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 
import android.widget.TextView; 
import android.widget.Toast; 
import com.example.android.recipe.R; 
import com.example.android.recipe.pojo.Recipe; 
import com.example.android.recipe.pojo.Step; 
import com.google.android.exoplayer2.LoadControl; 
import com.google.android.exoplayer2.SimpleExoPlayer; 
import com.google.android.exoplayer2.source.ExtractorMediaSource; 
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; 
import com.google.android.exoplayer2.ui.SimpleExoPlayerView; 
import java.util.ArrayList; 
import java.util.List; 
import com.google.android.exoplayer2.DefaultLoadControl; 
import com.google.android.exoplayer2.ExoPlayerFactory; 
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory; 
import com.google.android.exoplayer2.source.MediaSource; 
import com.google.android.exoplayer2.trackselection.AdaptiveVideoTrackSelection; 
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; 
import com.google.android.exoplayer2.trackselection.TrackSelection; 
import com.google.android.exoplayer2.upstream.BandwidthMeter; 
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter; 
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; 
import com.google.android.exoplayer2.util.Util; 
import com.squareup.picasso.Picasso; 

import static com.example.android.recipe.ui.RecipeActivity.SELECTED_INDEX; 
import static com.example.android.recipe.ui.RecipeActivity.SELECTED_RECIPES; 
import static com.example.android.recipe.ui.RecipeActivity.SELECTED_STEPS; 

public class RecipeStepDetailFragment extends Fragment { 
    private SimpleExoPlayerView simpleExoPlayerView; 
    private SimpleExoPlayer player; 
    private BandwidthMeter bandwidthMeter; 
    private ArrayList<Step> steps = new ArrayList<>(); 
    private int selectedIndex; 
    private Handler mainHandler; 
    ArrayList<Recipe> recipe; 
    String recipeName; 
    public RecipeStepDetailFragment() { } 
    private ListItemClickListener itemClickListener; 
    public interface ListItemClickListener { 
     void onListItemClick(List<Step> allSteps,int Index,String recipeName); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     TextView textView; 
     mainHandler = new Handler(); 
     bandwidthMeter = new DefaultBandwidthMeter(); 
     itemClickListener =(RecipeDetailActivity)getActivity(); 
     recipe = new ArrayList<>(); 
     if(savedInstanceState != null) { 
      steps = savedInstanceState.getParcelableArrayList(SELECTED_STEPS); 
      selectedIndex = savedInstanceState.getInt(SELECTED_INDEX); 
      recipeName = savedInstanceState.getString("Title"); 
     } 
     else { 
      steps =getArguments().getParcelableArrayList(SELECTED_STEPS); 
      if (steps!=null) { 
       steps =getArguments().getParcelableArrayList(SELECTED_STEPS); 
       selectedIndex=getArguments().getInt(SELECTED_INDEX); 
       recipeName=getArguments().getString("Title"); 
      } 
      else { 
       recipe =getArguments().getParcelableArrayList(SELECTED_RECIPES); 
       steps=(ArrayList<Step>)recipe.get(0).getSteps(); 
       selectedIndex=0; 
      } 
     } 
     View rootView = inflater.inflate(R.layout.recipe_step_detail_fragment_body_part, container, false); 
     textView = (TextView) rootView.findViewById(R.id.recipe_step_detail_text); 
     textView.setText(steps.get(selectedIndex).getDescription()); 
     textView.setVisibility(View.VISIBLE); 
     simpleExoPlayerView = (SimpleExoPlayerView) rootView.findViewById(R.id.playerView); 
     simpleExoPlayerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIT); 
     String videoURL = steps.get(selectedIndex).getVideoURL(); 
     if (rootView.findViewWithTag("sw600dp-port-recipe_step_detail")!=null) { 
      recipeName=((RecipeDetailActivity) getActivity()).recipeName; 
      ((RecipeDetailActivity) getActivity()).getSupportActionBar().setTitle(recipeName); 
     } 
     String imageUrl=steps.get(selectedIndex).getThumbnailURL(); 
     if (imageUrl!="") { 
      Uri builtUri = Uri.parse(imageUrl).buildUpon().build(); 
      ImageView thumbImage = (ImageView) rootView.findViewById(R.id.thumbImage); 
      Picasso.with(getContext()).load(builtUri).into(thumbImage); 
     } 
     if (!videoURL.isEmpty()) { 
      initializePlayer(Uri.parse(steps.get(selectedIndex).getVideoURL())); 
      if (rootView.findViewWithTag("sw600dp-land-recipe_step_detail")!=null) { 
       getActivity().findViewById(R.id.fragment_container2).setLayoutParams(new LinearLayout.LayoutParams(-1,-2)); 
       simpleExoPlayerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIXED_WIDTH); 
      } 
      else if (isInLandscapeMode(getContext())){ 
       textView.setVisibility(View.GONE); 
      } 
     } 
     else { 
      player=null; 
      simpleExoPlayerView.setForeground(ContextCompat.getDrawable(getContext(), R.drawable.ic_visibility_off_white_36dp)); 
      simpleExoPlayerView.setLayoutParams(new LinearLayout.LayoutParams(300, 300)); 
     } 
     Button mPrevStep = (Button) rootView.findViewById(R.id.previousStep); 
     Button mNextstep = (Button) rootView.findViewById(R.id.nextStep); 

     mPrevStep.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View view) { 
      if (steps.get(selectedIndex).getId() > 0) { 
       if (player!=null){ 
        player.stop(); 
       } 
       itemClickListener.onListItemClick(steps,steps.get(selectedIndex).getId() - 1,recipeName); 
      } 
      else { 
       Toast.makeText(getActivity(),"You already are in the First step of the recipe", Toast.LENGTH_SHORT).show(); 
      } 
     }}); 

     mNextstep.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View view) { 
      int lastIndex = steps.size()-1; 
      if (steps.get(selectedIndex).getId() < steps.get(lastIndex).getId()) { 
       if (player!=null){ 
        player.stop(); 
       } 
       itemClickListener.onListItemClick(steps,steps.get(selectedIndex).getId() + 1,recipeName); 
      } 
      else { 
       Toast.makeText(getContext(),"You already are in the Last step of the recipe", Toast.LENGTH_SHORT).show(); 
      } 
     }}); 
     return rootView; 
    } 

    private void initializePlayer(Uri mediaUri) { 
     if (player == null) { 
      TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveVideoTrackSelection.Factory(bandwidthMeter); 
      DefaultTrackSelector trackSelector = new DefaultTrackSelector(mainHandler, videoTrackSelectionFactory); 
      LoadControl loadControl = new DefaultLoadControl(); 
      player = ExoPlayerFactory.newSimpleInstance(getContext(), trackSelector, loadControl); 
      simpleExoPlayerView.setPlayer(player); 
      String userAgent = Util.getUserAgent(getContext(), "Baking App"); 
      MediaSource mediaSource = new ExtractorMediaSource(mediaUri, new DefaultDataSourceFactory(getContext(), userAgent), new DefaultExtractorsFactory(), null, null); 
      player.prepare(mediaSource); 
      player.setPlayWhenReady(true); 
     } 
    } 

    @Override 
    public void onSaveInstanceState(Bundle currentState) { 
     super.onSaveInstanceState(currentState); 
     currentState.putParcelableArrayList(SELECTED_STEPS,steps); 
     currentState.putInt(SELECTED_INDEX,selectedIndex); 
     currentState.putString("Title",recipeName); 
    } 

    public boolean isInLandscapeMode(Context context) { 
     return (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE); 
    } 

    @Override 
    public void onDetach() { 
     super.onDetach(); 
     if (player!=null) { 
      player.stop(); 
      player.release(); 
     } 
    } 

    @Override 
    public void onDestroyView() { 
     super.onDestroyView(); 
     if (player!=null) { 
      player.stop(); 
      player.release(); 
      player=null; 
     } 
    } 

    @Override 
    public void onStop() { 
     super.onStop(); 
     if (player!=null) { 
      player.stop(); 
      player.release(); 
     } 
    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
     if (player!=null) { 
      player.stop(); 
      player.release(); 
     } 
    } 
} 

完整的项目库:https://github.com/mtp2697/Udacity-AndroidDeveloperNanodegree-BakingApp

帮助与视频播放器的状态进行的onPause()和的onResume()

感谢, 普利文瑟尔默根恢复。

回答

2

我在提交用于烘烤应用面临着同样的问题,我做了这样的事情:

private void initPlayer() { 
    // Exoplayer 


    // 1. Create a default TrackSelector 
    // Handler mainHandler = new Handler(); 
    videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter); 
    trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory); 
    RenderersFactory render = new DefaultRenderersFactory(getContext()); 
    mainHandler = new Handler(); 
    if (CookieHandler.getDefault() != DEFAULT_COOKIE_MANAGER) { 
     CookieHandler.setDefault(DEFAULT_COOKIE_MANAGER); 
    } 

    // 2. Create a default LoadControl 
    LoadControl loadControl = new DefaultLoadControl(); 

    // 3. Create the player 
    recipeVideoPlayer = ExoPlayerFactory.newSimpleInstance(render, trackSelector, loadControl); 

    // exoPlayerView = (SimpleExoPlayerView) v.findViewById(R.id.exoplayer_recipe); 

    // Set media controller 
    mExoplayer.setUseController(true); 
    mExoplayer.setControllerVisibilityListener(this); 

    mExoplayer.requestFocus(); 


    // Bind the player to the view. 

    mExoplayer.setPlayer(recipeVideoPlayer); 

    if (TextUtils.isEmpty(mSteps.getVideoURL())) { 

     mExoplayer.setVisibility(View.GONE); 


    } else { 

     mExoplayer.setVisibility(View.VISIBLE); 
     Uri video = Uri.parse(mSteps.getVideoURL()); 
     DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(getContext(), Util.getUserAgent(getContext(), "recipes"), null); 
     ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory(); 

     MediaSource videoSource = new ExtractorMediaSource(video, dataSourceFactory, extractorsFactory, mainHandler, null); 
     boolean haveResumePosition = resumeWindow != C.INDEX_UNSET; 
     if (haveResumePosition) { 
      recipeVideoPlayer.seekTo(resumeWindow, resumePosition); 
     } 
     recipeVideoPlayer.prepare(videoSource, !haveResumePosition, false); 

     recipeVideoPlayer.setPlayWhenReady(true); 


     recipeVideoPlayer.addListener(new ExoPlayer.EventListener() { 
      @Override 
      public void onTimelineChanged(Timeline timeline, Object manifest) { 

      } 

      @Override 
      public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { 

       // Toast.makeText(getContext(), "Track changed" + trackSelections.length, Toast.LENGTH_SHORT).show(); 
       // 


      } 

      @Override 
      public void onLoadingChanged(boolean isLoading) { 

      } 

      @Override 
      public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { 


      } 


      @Override 
      public void onPlayerError(ExoPlaybackException error) { 
       clearResumePosition(); 
      } 

      @Override 
      public void onPositionDiscontinuity() { 
       // updateResumePosition(); 
      } 

      @Override 
      public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) { 

      } 


     }); 
    } 


} 

private void releasePlayer() { 
     if (recipeVideoPlayer != null) { 
      updateResumePosition(); 
      recipeVideoPlayer.stop(); 
      recipeVideoPlayer.release(); 
      recipeVideoPlayer = null; 
     } 
} 

@Override 
    public void onResume() { 
     super.onResume(); 
     if (recipeVideoPlayer == null) { 
      initPlayer(); 
     } 
} 

@Override 
    public void onPause() { 
     super.onPause(); 
     releasePlayer(); 

} 

you can refer my project here

+0

我会尝试实现它,如果这样工作,我会将答案标记为正确。 –

+0

当然,所有的都是最好的 –