1 Câu hỏi: Cách sửa video ExoPlayer Đóng băng 2.9.6

câu hỏi được tạo ra tại Mon, May 6, 2019 12:00 AM

Tôi sử dụng mã này để phát video toàn màn hình nhưng tôi gặp sự cố khi phát video và chuyển từ hoạt động chính sang hoạt động toàn màn hình xảy ra đóng băng video trong 2-3 giây Sự cố này chỉ xảy ra với các bản phát hành chỉ sau 2.8.3 nhưng với 2.8.0 hoạt động Video rất mượt

mã đầy đủ: https://github.com/MATPOCKIH/ExoPlayerFullscreen

PlayerViewManager

public class PlayerViewManager {

private static final String TAG = "ExoPlayerViewManager";

public static final String EXTRA_VIDEO_URI = "video_uri";

private static Map<String, PlayerViewManager> instances = new HashMap<>();
private Uri videoUri;

public boolean isPlayerPlaying;
private boolean isMustPlaying;

private UniversalPlayerView universalPlayer;


public static PlayerViewManager getInstance(String videoUri) {
    PlayerViewManager instance = instances.get(videoUri);
    if (instance == null) {
        instance = new PlayerViewManager(videoUri);
        instances.put(videoUri, instance);
    }
    return instance;
}

private PlayerViewManager(String videoUri) {
    this.videoUri = Uri.parse(videoUri);
}

public void preparePlayer(PlayerHolderView playerHolderView) {
    if (playerHolderView == null) {
        return;
    }

    if (universalPlayer == null) {
        universalPlayer = createPlayer(playerHolderView.getContext());
        isPlayerPlaying = true;
        isMustPlaying = true;
    }

    universalPlayer.initialize(videoUri, playerHolderView);
}

public void releaseVideoPlayer() {
    if (universalPlayer != null) {
        universalPlayer.release();
    }
    universalPlayer = null;
}

public void goToBackground() {
    if (universalPlayer != null /*&& !isMustPlaying*/) {
        //isPlayerPlaying = player.getPlayWhenReady();
        universalPlayer.pause();
    }
}

public void goToForeground() {
    if (universalPlayer != null && isMustPlaying) {
        universalPlayer.play();
    }
}

public void pausePlayer(){
    if (universalPlayer != null) {
        universalPlayer.pause();
        isPlayerPlaying = false;
        isMustPlaying = false;
    }
}

public void playPlayer(){
    if (universalPlayer != null) {
        universalPlayer.play();
        isPlayerPlaying = true;
        isMustPlaying = true;
    }
}

private UniversalPlayerView createPlayer(Context context){
    if (videoUri.getScheme().startsWith("http")){
        return new FaceterExoPlayerView(context);
    }
    return new FaceterExoPlayerView(context);
}
}

FaceterExoPlayerView

public class FaceterExoPlayerView extends UniversalPlayerView {

private Uri videoUri;
private DefaultDataSourceFactory dataSourceFactory;
private SimpleExoPlayer player;
private PlayerView exoPlayerView;
private Context context;

public FaceterExoPlayerView(Context context) {
    this.context = context;
}

@Override
public void initialize(Uri videoUri, PlayerHolderView playerHolderView) {

    if (playerHolderView == null || videoUri == null)
        return;

    exoPlayerView = playerHolderView.findViewById(R.id.exo_player);


    if (player == null) {
        player = ExoPlayerFactory.newSimpleInstance(context, new DefaultTrackSelector());

        dataSourceFactory = new DefaultDataSourceFactory(context,
                Util.getUserAgent(context, "faceter"));

        MediaSource videoSource = buildMediaSource(videoUri, null);
        player.prepare(videoSource);
    }

    player.clearVideoSurface();
    player.setVideoTextureView((TextureView) exoPlayerView.getVideoSurfaceView());
    exoPlayerView.setPlayer(player);
    exoPlayerView.hideController();
    setResizeModeFill(playerHolderView.isResizeModeFill());
}

@Override
public void play() {
    player.setPlayWhenReady(true);
}

@Override
public void pause() {
    player.setPlayWhenReady(false);
}

@SuppressWarnings("unchecked")
private MediaSource buildMediaSource(Uri uri, @Nullable String overrideExtension) {
    int type = Util.inferContentType(uri, overrideExtension);
    switch (type) {
        /*case C.TYPE_DASH:
            return new DashMediaSource.Factory(
                    new DefaultDashChunkSource.Factory(mediaDataSourceFactory),
                    buildDataSourceFactory(false))
                    .setManifestParser(
                            new FilteringManifestParser<>(
                                    new DashManifestParser(), (List<RepresentationKey>) getOfflineStreamKeys(uri)))
                    .createMediaSource(uri);
        case C.TYPE_SS:
            return new SsMediaSource.Factory(
                    new DefaultSsChunkSource.Factory(mediaDataSourceFactory),
                    buildDataSourceFactory(false))
                    .setManifestParser(
                            new FilteringManifestParser<>(
                                    new SsManifestParser(), (List<StreamKey>) getOfflineStreamKeys(uri)))
                    .createMediaSource(uri);*/
        case C.TYPE_HLS:
            return new HlsMediaSource.Factory(dataSourceFactory)
                    /*.setPlaylistParser(
                            new FilteringManifestParser<>(
                                    new HlsPlaylistParser(), (List<RenditionKey>) getOfflineStreamKeys(uri)))*/
                    .createMediaSource(uri);
        case C.TYPE_OTHER:
            return new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
        default: {
            throw new IllegalStateException("Unsupported type: " + type);
        }
    }
}

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

@Override
public void setResizeModeFill(boolean isResizeModeFill) {
    if (isResizeModeFill) {
        exoPlayerView.setResizeMode(RESIZE_MODE_FILL);
    } else {
        exoPlayerView.setResizeMode(RESIZE_MODE_FIT);
    }
}
}

PlayerHolderView.java

public class PlayerHolderView extends FrameLayout {

private String videoUrl;

private boolean isResizeModeFill = true;

private OnUserInteractionListener onUserInteractionListener;

public PlayerHolderView(@NonNull Context context) {
    super(context);
    init();
}

public PlayerHolderView(@NonNull Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    init();
}

public PlayerHolderView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();
}

private void init() {
    LayoutInflater.from(getContext()).inflate(R.layout.layout_player, this, true);

    View controlView = this.findViewById(R.id.exo_controller);

    controlView.findViewById(R.id.exo_play)
            .setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    PlayerViewManager.getInstance(videoUrl).playPlayer();
                }
            });

    controlView.findViewById(R.id.exo_pause)
            .setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    PlayerViewManager.getInstance(videoUrl).pausePlayer();
                }
            });

    controlView.findViewById(R.id.exo_fullscreen_button)
            .setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(getContext(), FullscreenVideoActivity.class);
                    intent.putExtra(PlayerViewManager.EXTRA_VIDEO_URI, videoUrl);
                    getContext().startActivity(intent);
                }
            });

MainActivity

public class MainActivity extends AppCompatActivity {

    private List<PlayerHolderView> playerHolders = new ArrayList<>();
    private List<TextView> links = new ArrayList<>();

    private List<String> mVideoUrls = new ArrayList<>(
            Arrays.asList(
                    //"http://10.110.3.30/api/Playlists/6a3ecad7-e744-446f-9341-0e0ba834de63?from=2018-09-20&to=2018-09-21"
                    "https://commondatastorage.googleapis.com/gtv-videos-bucket/CastVideos/hls/TearsOfSteel.m3u8",
                    "http://redirector.c.youtube.com/videoplayback?id=604ed5ce52eda7ee&itag=22&source=youtube&sparams=ip,ipbits,expire,source,id&ip=0.0.0.0&ipbits=0&expire=19000000000&signature=513F28C7FDCBEC60A66C86C9A393556C99DC47FB.04C88036EEE12565A1ED864A875A58F15D8B5300&key=ik0",
                    "https://html5demos.com/assets/dizzy.mp4"
                    //"https://cdn.faceter.io/hls/ab196789-8876-4854-82f3-087e5682d013",
                      //"https://cdn.faceter.io/hls/65d1c673-6a63-44c8-836b-132449c9462a"
            )
    );

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        playerHolders.add((PlayerHolderView) findViewById(R.id.holder1));
        playerHolders.add((PlayerHolderView) findViewById(R.id.holder2));
        playerHolders.add((PlayerHolderView) findViewById(R.id.holder3));

        links.add((TextView) findViewById(R.id.title1));
        links.add((TextView) findViewById(R.id.title2));
        links.add((TextView) findViewById(R.id.title3));
    }


    @Override
    public void onResume() {
        super.onResume();
        int i = 0;
        for (final String videoUrl : mVideoUrls) {
            playerHolders.get(i).setupPlayerView(videoUrl);
            playerHolders.get(i).setOnUserInteractionListener(this);

            links.get(i).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    onVideoTitleClicked(videoUrl);
                }
            });

            i++;
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        for (String videoUrl : mVideoUrls) {
            PlayerViewManager.getInstance(videoUrl).goToBackground();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        for (String videoUrl : mVideoUrls) {
            PlayerViewManager.getInstance(videoUrl).releaseVideoPlayer();
        }
    }

    public void onVideoTitleClicked(String videoUrl) {
        Intent intent = new Intent(getBaseContext(), DetailActivity.class);
        intent.putExtra(PlayerViewManager.EXTRA_VIDEO_URI, videoUrl);
        startActivity(intent);
    }
}

FullscreenVideoActivity

public class FullscreenVideoActivity extends AppCompatActivity {

    /**
     * Some older devices needs a small delay between UI widget updates
     * and a change of the status and navigation bar.
     */
    private static final int UI_ANIMATION_DELAY = 300;
    private final Handler mHideHandler = new Handler();
    private View mContentView;
    private final Runnable mHidePart2Runnable = new Runnable() {
        @SuppressLint("InlinedApi")
        @Override
        public void run() {
            // Delayed removal of status and navigation bar

            // Note that some of these constants are new as of
            // API 19 (KitKat). It is safe to use them, as they are inlined
            // at compile-time and do nothing on earlier devices.
            mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
                    | View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
        }
    };
    private final Runnable mHideRunnable = new Runnable() {
        @Override
        public void run() {
            hide();
        }
    };

    private String mVideoUri;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_fullscreen_video);

        mContentView = findViewById(R.id.enclosing_layout);

        PlayerHolderView playerHolderView = findViewById(R.id.player_holder);
        playerHolderView.setResizeModeFill(false);

        mVideoUri = getIntent().getStringExtra(PlayerViewManager.EXTRA_VIDEO_URI);

        PlayerViewManager.getInstance(mVideoUri).preparePlayer(playerHolderView);
/*
        // Set the fullscreen button to "close fullscreen" icon
        View controlView = playerView.findViewById(R.id.exo_controller);
        ImageView fullscreenIcon = controlView.findViewById(R.id.exo_fullscreen_icon);
        fullscreenIcon.setImageResource(R.drawable.exo_controls_fullscreen_exit);
        controlView.findViewById(R.id.exo_fullscreen_button)
                .setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        finish();
                    }
                });
        controlView.findViewById(R.id.exo_play)
                .setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        PlayerViewManager.getInstance(mVideoUri).playPlayer();
                    }
                });
        controlView.findViewById(R.id.exo_pause)
                .setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        PlayerViewManager.getInstance(mVideoUri).pausePlayer();
                    }
                });*/
    }

    @Override
    public void onResume() {
        super.onResume();
        PlayerViewManager.getInstance(mVideoUri).goToForeground();
    }

    @Override
    public void onPause() {
        super.onPause();
        PlayerViewManager.getInstance(mVideoUri).goToBackground();
    }

    @Override
    public void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);

        // Trigger the initial hide() shortly after the activity has been
        // created, to briefly hint to the user that UI controls
        // are available.
        delayedHide();
    }

    private void hide() {
        // Schedule a runnable to remove the status and navigation bar after a delay
        mHideHandler.postDelayed(mHidePart2Runnable, UI_ANIMATION_DELAY);
    }

    /**
     * Schedules a call to hide() in delay milliseconds, canceling any
     * previously scheduled calls.
     */
    private void delayedHide() {
        mHideHandler.removeCallbacks(mHideRunnable);
        mHideHandler.postDelayed(mHideRunnable, 100);
    }
}
    
0
1 Câu trả lời                              1                         

Chỉ cần thử mã này cho vấn đề đóng băng video:

@Override
public void play() {
    player.setPlayWhenReady(true);
    player.getPlaybackState();
}

@Override
public void pause() {
    player.setPlayWhenReady(false);
    player.getPlaybackState();
}

Tại đây player.getPlaybackState(); là trợ giúp đầy đủ để đưa nó trở lại trạng thái.

    
2
2019-05-06 05: 58: 21Z
  1. Chấp nhận câu trả lời của tôi nếu nó hữu ích :)
    2019-05-06 06: 38: 30Z
  2. Cảm ơn bạn đã giúp đỡ Thật không may, mã không hoạt động với tôi
    2019-05-06 06: 41: 03Z
nguồn đặt đây