media icon indicating copy to clipboard operation
media copied to clipboard

Exoplayer.release did not free memory? Is it a Known issues??2.11.8 and 2.19.1

Open mikelhm opened this issue 1 year ago • 1 comments

Version

2.11.8 and 2.19.1

More version details

### Our project use ExoPlayer 2.11.8 : SimpleExoPlayer.release() did not free memory ,and i update to 2.19.1, it is also the same: not free memory.

Is it a Known issues?? I did not press the gc button in Android Studio Profile, But should the memory restore to normal level without gc manually????

Here is my code 2.11.8 version :

public class VideoTestFragment extends Fragment {
    public static VideoTestFragment build() {
        return new VideoTestFragment();
    }

    private Context mContext;
    private SimpleExoPlayer mSimpleExoPlayer;
    private VideoPlayTask mCurVideoPlayTask;

    @Override
    public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
        mContext = getActivity();
        View rootView = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_video_item, null, true);
        initUI(rootView);
        return rootView;
    }

    private void initUI(View rootView) {
        SimpleExoPlayerView simpleExoPlayerView = rootView.findViewById(R.id.video_view);
        mCurVideoPlayTask = new VideoPlayTask(simpleExoPlayerView, "\"https://vfx.mtime.cn/Video/2019/01/15/mp4/190115161611510728_480.mp4");
    }

    public void startPlay() {
        stopPlay();
        if(mCurVideoPlayTask == null) {
            Log.e("Video_Play_TAG", "start play task is null");
            return;
        }

        //创建带宽对象
        BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
        //根据当前宽带来创建选择磁道工厂对象
        TrackSelection.Factory videoTrackSelectionFactory =
                new AdaptiveTrackSelection.Factory(bandwidthMeter);
        //传入工厂对象,以便创建选择磁道对象
        TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
        LoadControl loadControl = new DefaultLoadControl();
        mSimpleExoPlayer = ExoPlayerFactory.newSimpleInstance(mContext, trackSelector, loadControl);
        //设置是否循环播放
        mSimpleExoPlayer.setRepeatMode(Player.REPEAT_MODE_ONE);

        //配置数据源
        DataSource.Factory mediaDataSourceFactory = new DefaultDataSourceFactory(mContext,
                Util.getUserAgent(mContext, "Exo_Video_Play"));
        DefaultExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();

        //获取代理url
        String proxyUrl = getProxy().getProxyUrl(mCurVideoPlayTask.getVideoUrl());
        Log.d("Video_Play_TAG", "start play orginal url = " + mCurVideoPlayTask.getVideoUrl() + " , proxy url = " + proxyUrl);
        Uri proxyUri = Uri.parse(proxyUrl);

        //配置数据源
        MediaSource mediaSource = new ExtractorMediaSource(proxyUri, mediaDataSourceFactory, extractorsFactory, null, null);
        mSimpleExoPlayer.prepare(mediaSource);

        //隐藏播放工具
        mCurVideoPlayTask.getSimpleExoPlayerView().setUseController(false);
        //设置播放视频的宽高为Fit模式
        mCurVideoPlayTask.getSimpleExoPlayerView().setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIT);
        //绑定player和playerView
        mCurVideoPlayTask.getSimpleExoPlayerView().setPlayer(mSimpleExoPlayer);
        mSimpleExoPlayer.setPlayWhenReady(true);
    }

    /**
     * 停止播放
     */
    public void stopPlay() {
        if(mSimpleExoPlayer != null) {
            mSimpleExoPlayer.release();
            mSimpleExoPlayer = null;
        }
    }

    public void resumePlay() {
        if(mSimpleExoPlayer != null) {
            mSimpleExoPlayer.setPlayWhenReady(true);
        } else {
            startPlay();
        }
    }

    public void pausePlay() {
        if(mSimpleExoPlayer != null) {
            mSimpleExoPlayer.setPlayWhenReady(false);
        }
    }


    private HttpProxyCacheServer mHttpProxyCacheServer;
    public HttpProxyCacheServer getProxy() {
        if(mHttpProxyCacheServer == null) {
            mHttpProxyCacheServer = newProxy();
        }
        return mHttpProxyCacheServer;
    }

    private HttpProxyCacheServer newProxy() {
        //缓存大小512M,缓存文件20
        return new HttpProxyCacheServer.Builder(mContext.getApplicationContext())
                .maxCacheSize(512 * 1024 * 1024)
                .maxCacheFilesCount(20)
                .fileNameGenerator(new VideoFileNameGenerator())
                .cacheDirectory(new File(mContext.getFilesDir() + "/videoCache/"))
                .build();
    }


    @Override
    public void onDestroyView() {
        super.onDestroyView();
        stopPlay();
    }

    @Override
    public void onResume() {
        super.onResume();
        resumePlay();
    }

    @Override
    public void onStop() {
        super.onStop();
        pausePlay();
    }
}

Here is my code 2.19.1 version :

public class VideoTestFragment extends Fragment {
    public static VideoTestFragment build() {
        return new VideoTestFragment();
    }

    private Context mContext;
    private SimpleExoPlayer mSimpleExoPlayer;
    private PlayerView playerView;

    @Override
    public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
        mContext = getActivity();
        View rootView = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_video_item, null, true);
        initUI(rootView);
        return rootView;
    }

    private void initUI(View rootView) {
        mSimpleExoPlayer = new SimpleExoPlayer.Builder(getActivity()).build();
        // 准备要播放的媒体资源
        MediaItem mediaItem = MediaItem.fromUri("https://vfx.mtime.cn/Video/2019/01/15/mp4/190115161611510728_480.mp4");
        mSimpleExoPlayer.setMediaItem(mediaItem);
        // 将ExoPlayer关联到要显示视频的View
        playerView = rootView.findViewById(R.id.player_view);
        playerView.setPlayer(mSimpleExoPlayer);
    }

    public void startPlay() {
        // 准备播放器
        mSimpleExoPlayer.prepare();
        mSimpleExoPlayer.play();
    }

    /**
     * 停止播放
     */
    public void stopPlay() {
        if(mSimpleExoPlayer != null) {
            mSimpleExoPlayer.release();
            mSimpleExoPlayer = null;
        }
    }

    public void resumePlay() {
        if(mSimpleExoPlayer != null) {
            mSimpleExoPlayer.setPlayWhenReady(true);
        } else {
            startPlay();
        }
    }

    public void pausePlay() {
        if(mSimpleExoPlayer != null) {
            mSimpleExoPlayer.setPlayWhenReady(false);
        }
    }
    

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        stopPlay();
    }

    @Override
    public void onResume() {
        super.onResume();
        resumePlay();
    }

    @Override
    public void onStop() {
        super.onStop();
        pausePlay();
    }
}

Devices that reproduce the issue

Oppo findx5 android 12

Devices that do not reproduce the issue

No response

Reproducible in the demo app?

Yes

Reproduction steps

As i show the code, when i close the video fragment , the memory did not free image

Expected result

Is new version solve the problem?? which exoplayer version solve the problem??

Actual result

null

Media

null

Bug Report

  • [ ] You will email the zip file produced by adb bugreport to [email protected] after filing this issue.

You can reproduce by yourself, call Player.release did not free the memory.

mikelhm avatar Feb 21 '24 09:02 mikelhm

Same story

tsviatoslav avatar Aug 20 '24 14:08 tsviatoslav