1

我已經實現了播放器,現在有一個問題。當視頻播放時,如果應用程序關閉並恢復,視頻屏幕會凍結。我甚至看到Google的ExoPlayer演示活動,以便更好地理解,但我無法通過它在我的應用中實現。我在這裏附加了Player Activity和完整的代碼,我將共享GitHub存儲庫以獲取所用的完整文件集。ExoPlayer恢復狀態時恢復

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()

感謝, 普利文瑟爾默根恢復。

回答

6

您可以將播放器的位置上暫停:

position = player.getCurrentPosition(); //then, save it on the bundle. 

然後當你恢復它,如果它是存在的,你可以這樣做:

if (position != C.TIME_UNSET) player.seekTo(position); 

之前prepare()initializePlayer()方法。

好吧,我克隆了這個項目,並使其工作。我改變主要是:

我說什麼,我之前說的,然後:

position = C.TIME_UNSET; 
if (savedInstanceState != null) { 
    //...your code... 
    position = savedInstanceState.getLong(SELECTED_POSITION, C.TIME_UNSET); 
} 

我做了VIDEOURI全球

videoUri = Uri.parse(steps.get(selectedIndex).getVideoURL()); 

新增的onResume:

@Override 
public void onResume() { 
    super.onResume(); 
    if (videoUri != null) 
     initializePlayer(videoUri); 
} 

更新的onPause:

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

的onSaveInstanceState和:

currentState.putLong(SELECTED_POSITION, position); 

最後,我刪除onDetachonDestroyViewonStop

顯然這是「只是爲了使它工作」,你將不得不更多地努力。

+0

嗨Matias,位置已恢復,但視頻不播放,播放按鈕也不播放。唯一能看到的是黑屏,簡歷中沒有內容。 –

+0

怎麼樣:'player.prepare(mediaSource,false,false)'?你可能還必須存儲playerWindow(可以用'player.getCurrentWindowIndex()''來完成)。我稍後會檢查您的回購。 –

+0

@PraveenThirumurugan我也沒有看到代碼中的播放按鈕。版本庫是否已更新? –