如何在ViewPager,Android中的片段中播放Youtube视频

时间:2017-06-08 05:52:43

标签: android video youtube android-viewpager fragment

现在我正尝试使用YouTubePlayerSupportFragment在ViewPager的片段中播放Youtube视频。 我使用SmartFragmentStatePagerAdapter作为viewpager适配器。 但我得到了这个错误:

W / YouTubeAndroidPlayerAPI:YouTube视频播放因播放器顶部未经授权的覆盖而停止。 YouTubePlayerView未包含在其祖先android.support.v4.view.ViewPager {41a53898 VFED .... ......我。 0,84-480,730#7f0c00b8 app:id / viewPager}。祖先边缘与YouTubePlayerView边缘之间的距离为:left:480,top:0,right:-480,bottom:376(这些都应为正数)。

我该如何解决这个问题。 此致

这是FragmentPageAdapter代码

public class VideoPagerAdapter extends SmartFragmentStatePagerAdapter 

{
    private UserInfo usrInfo;

public VideoPagerAdapter(FragmentManager fragmentManager, UserInfo userInfo){
    super(fragmentManager);
    usrInfo = userInfo;
}

@Override
public Fragment getItem(int position) {
    VideoDetailFragment videoDetailFragment = new VideoDetailFragment();
    videoDetailFragment.video = usrInfo.videoList.get(position);
    return videoDetailFragment;
}

@Override
public int getCount() {
    return usrInfo.videoList.size();
}

}

我在VideoDetailFragment中实现了代码。

private YouTubePlayer mYoutubePlayer;
private YouTubePlayerSupportFragment mYoutubeFragment;

private void initYoutubeVideo(){
    mYoutubeFragment = YouTubePlayerSupportFragment.newInstance();
    FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
    transaction.replace(R.id.youtube_layout, mYoutubeFragment).commit();

    mYoutubeFragment.initialize(DEVELOPER_KEY, this);
}

@Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean b) {
    mYoutubePlayer = youTubePlayer;
    if (!b){
        youTubePlayer.setPlayerStyle(YouTubePlayer.PlayerStyle.DEFAULT);
        youTubePlayer.loadVideo(VIDEO_ID);
    }
}



@Override
public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) {
    Log.d(TAG, "*** Youtube Player error : " + youTubeInitializationResult.toString());
    String errorMessage = String.format(getString(R.string.error_youtube_player), youTubeInitializationResult.toString());

    Utils.showAlert(mActivity, errorMessage);
}

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

    if (!isVisibleToUser && mYoutubePlayer != null) {
        mYoutubePlayer.release();
    }
    if (isVisibleToUser && mYoutubeFragment != null) {
        mYoutubeFragment.initialize(DEVELOPER_KEY, this);
    }
}

我在真实设备中测试了它

06-08 19:02:47.012 2562-2562/com.videofeed.tickit W/YouTubeAndroidPlayerAPI: Cannot load modern controls UI. Upgrade to the latest version of the Android YouTube API.
06-08 19:02:47.082 2562-2562/com.videofeed.tickit D/dalvikvm: DexOpt: couldn't find field Landroid/view/accessibility/CaptioningManager$CaptionStyle;.windowColor
06-08 19:02:47.082 2562-2562/com.videofeed.tickit W/dalvikvm: VFY: unable to resolve instance field 10579
06-08 19:02:47.082 2562-2562/com.videofeed.tickit D/dalvikvm: VFY: replacing opcode 0x52 at 0x0019
06-08 19:02:47.082 2562-2562/com.videofeed.tickit W/YouTubeAndroidPlayerAPI: Forcefully created overlay:vtd@41fd4d28 helper:Lazy@41fd5898 view:null status: ...... {...}
06-08 19:02:47.372 2562-2562/com.videofeed.tickit W/YouTubeAndroidPlayerAPI: Cannot load modern controls UI. Upgrade to the latest version of the Android YouTube API.
06-08 19:02:47.442 2562-2562/com.videofeed.tickit W/YouTubeAndroidPlayerAPI: Forcefully created overlay:vtd@42c9fe20 helper:Lazy@42c9fe98 view:null status: ...... {...}
06-08 19:02:47.462 2562-2562/com.videofeed.tickit I/Choreographer: Skipped 40 frames!  The application may be doing too much work on its main thread.
06-08 19:02:47.602 2562-2562/com.videofeed.tickit W/YouTubeAndroidPlayerAPI: Cannot load modern controls UI. Upgrade to the latest version of the Android YouTube API.
06-08 19:02:47.692 2562-2562/com.videofeed.tickit W/YouTubeAndroidPlayerAPI: Forcefully created overlay:vtd@42d8f2a8 helper:Lazy@42d8f320 view:null status: ...... {...}
06-08 19:02:51.912 2562-2604/com.videofeed.tickit D/dalvikvm: GC_FOR_ALLOC freed 15971K, 69% free 7899K/25052K, paused 35ms, total 37ms
06-08 19:02:58.202 2562-2562/com.videofeed.tickit W/YouTubeAndroidPlayerAPI: YouTube video playback stopped due to unauthorized overlay on top of player. The YouTubePlayerView is not contained inside its ancestor android.support.v4.view.ViewPager{42c4a610 VFED.... ......ID 0,84-480,730 #7f0c00b8 app:id/viewPager}. The distances between the ancestor's edges and that of the YouTubePlayerView is: left: -480, top: 0, right: 480, bottom: 376 (these should all be positive).
06-08 19:02:58.222 2562-2562/com.videofeed.tickit W/YouTubeAndroidPlayerAPI: YouTube video playback stopped due to unauthorized overlay on top of player. The YouTubePlayerView is not contained inside its ancestor android.support.v4.view.ViewPager{42c4a610 VFED.... ......ID 0,84-480,730 #7f0c00b8 app:id/viewPager}. The distances between the ancestor's edges and that of the YouTubePlayerView is: left: 480, top: 0, right: -480, bottom: 376 (these should all be positive).

这是登录Android工作室。 我附上了截图。 This is the screenshot

3 个答案:

答案 0 :(得分:0)

这个答案可能要迟到,但我找到了一个可能的解决方案。

我遇到了类似的问题,我也尝试在viewpager中播放多个视频。 如果viewpager中只有一个youtube片段,并且没关系,但是当有多个时,视频将无法播放,并显示错误消息

  

YouTube视频播放因播放器顶部未经授权的覆盖而停止。

首先“未经授权的覆盖”不是来自我当前的片段 视图寻呼机的可见页面。它来自查看寻呼机创建“next”到当前片段的页面。

查看分页器在页面滑入可见窗口之前创建页面,因此youtube片段在可见之前创建,如果初始化该片段,则youtube播放器检测到奇怪的重叠错误并停止视频和youtube播放器停止,甚至停止在可见页面中正常显示的视频。

在您的情况下,您可以看到错误消息

  

左:480,上:0,右:-480,下:376

负数是一个窗口宽,所以它的概率与我得到的问题相同。

所以我的解决方案

<强> 1。不要在onCreate()处初始化youtube,不要在该片段是viewpager可见之前进行初始化。

就我而言,我使用了适配器和片段之间的接口,并且在viewpager的父页面中,向viewpager添加了一个OnPageChangeListener,youtube片段仅在viewpager的页面更改为该youtube片段后初始化。

页面更改&gt;通知适配器&gt;界面&gt; youtubefragment&gt;开始初始化

第一步后,即使在viewpager中有2个或更多youtube片段,第一个视频也应该正常播放,但是当我滑到第2页时,视频将无法播放并显示相同的错误,因此转到第2步

<强> 2。当youtube片段滑动到视图寻呼机的不可见部分时,释放youtube播放器

第二个视频没有播放的原因是相同的,第一页有一个youtubeplayer,它在可见范围外,它收到一条错误信息,因为我不知道为什么会停止所有youtubeplayer。

当页面被更改时,我使用相同的界面。适配器将使用该接口通知滑动的youtube片段,释放youtubeplayer,以及这样的接口工具,mPlayer将是youtubeplayer通过initialize方法返回。

scss

还有一些我无法回答的问题, 比如为什么youtubeplayer在一个寻呼机中会影响其他人..?

但是当我对我的适配器和片段进行更改时, youtube视频可以正常播放,希望这有助于你

下面是我在我的应用中使用的代码

      mInitializeListener = new InitializeListener() {
        @Override
        public void startVideo() {
            initialize();
        }

        @Override
        public void stopVideo() {
                mPlayer.release();
        }
    };

适配器

    MediaFragmentViewPager adapter =
        new MediaFragmentViewPager(getChildFragmentManager(), getActivity(), true);
List<MediaData> mediaDataList = new ArrayList<>();

adapter.setmResources(mediaDataList);

imageViewPager.setAdapter(adapter);

ViewPager.OnPageChangeListener pagerchangeListener = new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }
    @Override
    public void onPageSelected(int position) {
        adapter.onPageChanged(position);
    }
    @Override
    public void onPageScrollStateChanged(int state) {

    }
};

imageViewPager.addOnPageChangeListener(pagerchangeListener);
pagerchangeListener.onPageSelected(0);

circlePageIndicator.setFillColor(getResources().getColor(R.color.colorAccent));
circlePageIndicator.setViewPager(imageViewPager);

Youtube Fragment

public class MediaFragmentViewPager  extends FragmentStatePagerAdapter
        implements MediaYoutubeFragment.MediaFullScreenListener {

    protected List<MediaData> mResources;
    private String apiKey = "your apiKey";
    protected Map<Integer, MediaYoutubeFragment.InitializeListener> listenerMap = new HashMap<>();
    private Context context;

    private boolean isFullScreen;

    public MediaFragmentViewPager(FragmentManager fm, Context context, boolean isFullScreen) {
        super(fm);
        this.context = context;
        this.isFullScreen = isFullScreen;
    }

    public int currentPosition = -1;


    @Override
    public void startFullScreen() {
        if (!isFullScreen){
            MediaViewPagerActivity.startActivity(context, itemID, companyId, currentPosition);
        }
    }

    @Override
    public Fragment getItem(int position) {

        if(mResources.get(position).isImage == true){
            Log.i("tag3", "getItem image" + String.valueOf(position));
            MediaImageFragment imageFragment = new MediaImageFragment();
            imageFragment.setImageUrl(mResources.get(position).getImageResource().getImage1080p());
            return  imageFragment;
        } else {
            Log.i("tag3", "getItem video" + String.valueOf(position));
            MediaYoutubeFragment youTubePlayerSupportFragment =
                    MediaYoutubeFragment.newInstance(mResources.get(position).getYoutubeUrl(), this);
            listenerMap.put(position, youTubePlayerSupportFragment.getmInitializeListener());
            return youTubePlayerSupportFragment;
        }
    }

    public void onPageChanged(int position){
        // current page it not null, realse youtubeplayer.
        if(currentPosition != -1){
            if(listenerMap.get(currentPosition) != null){
                listenerMap.get(currentPosition).stopVideo();
            }
        }
        // update current position
        currentPosition = position;
        Log.i("tag3", "onPageSelected " + String.valueOf(position));

        //start loading video
        MediaYoutubeFragment.InitializeListener listener = listenerMap.get(position);
        if(listener != null){
            Log.i("tag3", "startVideo " + String.valueOf(position));
            listener.startVideo();
        } else {
            Log.i("tag3", "startVideo listener is null " + String.valueOf(position));
        }
    }

    @Override
    public int getCount() {
        return mResources.size();
    }

    public List<MediaData> getmResources() {
        return mResources;
    }

    public void setmResources(List<MediaData> mResources) {
        this.mResources = mResources;
    }


}

我也用我自己的活动处理全屏事件,这个viewpager内容不仅包括YouTube视频,还包括图片,所以请忽略这些部分。

因为我在片段中使用了view pager,所以我使用了getChildFragmentManger,并且我也在Activity中使用了这个适配器,但是它产生了另一个问题,即第一次视频将无法在第一次播放viewpager isload时播放,因为监听器是调用的在适配器中的getItem()之前,所以我做了一些更改,如果适配器是第一次加载(第一次加载第一个youtube页面),听者将在getItem返回片段后立即调用,其他的都是相同的。

答案 1 :(得分:0)

基本上,问题是您的某个视频正在可见屏幕外加载,导致叠加错误。 对于viewpager,已加载的页面也会加载视频,但这些视频不在屏幕上导致错误。

解决方案(适用于viewpager): 一次加载一个视频,即要播放的视频。 通过在页面可见时加载视频来执行此操作。

答案 2 :(得分:0)

这是不可能的。因为YouTubePlayerView要求其活动扩展YoutubeBaseActivity。 YouTubePlayerView提供的功能有限。