首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何在ViewPager中以片段的形式播放Youtube视频

如何在ViewPager中以片段的形式播放Youtube视频
EN

Stack Overflow用户
提问于 2017-06-08 13:52:43
回答 3查看 3.1K关注 0票数 0

现在我正试着用YouTubePlayerSupportFragment播放一段ViewPager格式的Youtube视频。我使用SmartFragmentStatePagerAdapter作为查看器适配器。但是我得到了这个错误:

W/YouTubeAndroidPlayerAPI: YouTube视频播放不能正常播放,原因是播放器顶部覆盖了未授权的内容。YouTubePlayerView未包含在其祖先android.support.v4.view.ViewPager{41a53898vfed.........I。0,84-480,730 #7f0c00b8应用程序:id/viewPager.祖先的边和YouTubePlayerView的边之间的距离是:左: 480,上: 0,右:-480,下: 376 (这些都应该是正数)。

我该如何解决这个问题。问候

这是FragmentPageAdapter代码

代码语言:javascript
代码运行次数:0
运行
复制
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实现了代码。

代码语言:javascript
代码运行次数:0
运行
复制
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);
    }
}

我已经在真实的设备上测试过了

代码语言:javascript
代码运行次数:0
运行
复制
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 studio的日志。我已经附上了截图。This is the screenshot

EN

回答 3

Stack Overflow用户

发布于 2017-08-17 11:43:21

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

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

YouTube视频播放已停止,原因是播放器上存在未经授权的覆盖。

第一个“未经授权的覆盖”不是来自我的当前片段,它位于视图分页的可见页面上。它来自视图分页程序在当前片段旁边创建“下一个”页面。

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

在您的示例中,您可以看到错误消息

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

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

所以我的解决方案

1.不要在onCreate()上初始化youtube,不要在该片段可见之前进行初始化。

在我示例中,我使用了适配器和片段之间的接口,并在viewpager的父页面中,将一个OnPageChangeListener添加到viewpager,youtube片段仅在viewpager的页面更改为该youtube片段后才会初始化。

页面更改>通知适配器>界面> youtubefragment >开始初始化

在第一步之后,即使在viewpager中有2个或更多的youtube片段,第一个视频也可以正常播放,但是当我滑动到第二页时,视频不会播放并显示相同的错误,所以请转到第二步

2.当youtube片段滑到视图分页程序不可见部分时,释放youtube player

第二个视频没有播放的原因是一样的,第一个页面有一个youtubeplayer,它在可见范围之外,它得到了一个错误消息,这停止了所有youtubeplayer的原因,我不知道为什么。

当页面改变时,我使用相同的界面。适配器将使用接口通知youtube的片段已经滑走,释放youtubeplayer,接口实现如下,初始化方法返回的youtubeplayer是哪个mPlayer。

代码语言:javascript
代码运行次数:0
运行
复制
      mInitializeListener = new InitializeListener() {
        @Override
        public void startVideo() {
            initialize();
        }

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

还有一些我不能回答的问题,比如为什么你在一个寻呼机里的播放器会影响其他人…?

但当我在适配器和片段上做了更改时,youtube视频可以正常播放,希望这能对你有所帮助

以下是我在应用程序中使用的代码

代码语言:javascript
代码运行次数:0
运行
复制
    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);

适配器

代码语言:javascript
代码运行次数:0
运行
复制
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;
    }


}

Youtube片段

代码语言:javascript
代码运行次数:0
运行
复制
public class MediaYoutubeFragment extends YouTubePlayerSupportFragment
        implements YouTubePlayer.OnInitializedListener, YouTubePlayer.OnFullscreenListener {
    private static final String KEY_VIDEO_ID = "VIDEO_ID";

    public String apiKey = "yor apiKey";
    private String mVideoId;
    private YouTubePlayer mPlayer;
    boolean mIsFullScreen;
    private InitializeListener mInitializeListener;
    private MediaFullScreenListener fullScreenListener;

    public InitializeListener getmInitializeListener() {
        return mInitializeListener;
    }

    public void setmInitializeListener(InitializeListener mInitializeListener) {
        this.mInitializeListener = mInitializeListener;
    }

    public void setFullScreenListener(MediaFullScreenListener fullScreenListener) {
        this.fullScreenListener = fullScreenListener;
    }

    public interface MediaFullScreenListener{
        void startFullScreen();
    }

    public interface InitializeListener{
        void startVideo();
        void stopVideo();
    }

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

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

    private void initialize() {
        initialize(apiKey, this);
    }

    public static MediaYoutubeFragment newInstance(String videoId, MediaFullScreenListener listener) {
        MediaYoutubeFragment frag = new MediaYoutubeFragment();

        Bundle args = new Bundle();
        args.putString(KEY_VIDEO_ID, videoId);

        frag.setArguments(args);
        frag.setFullScreenListener(listener);
        return frag;
    }

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

        if (getArguments() != null) {
            mVideoId = getArguments().getString(KEY_VIDEO_ID);
        }
    }

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

    @Override
    public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean wasRestored) {
        mPlayer = youTubePlayer;

        mPlayer.setFullscreenControlFlags(FULLSCREEN_FLAG_CUSTOM_LAYOUT);
        mPlayer.setOnFullscreenListener(this);
        mPlayer.setFullscreen(false);
        mPlayer.setShowFullscreenButton(true);

        if (!wasRestored) {
            // load your video
            mPlayer.loadVideo(mVideoId);
        }
        else
        {
            mPlayer.play();
        }
    }

    @Override
    public void onInitializationFailure(YouTubePlayer.Provider provider,
                                        YouTubeInitializationResult youTubeInitializationResult) {

    }

    @Override
    public void onFullscreen(boolean fullscreen) {
        Log.i("tag3", "onFullscreen" + String.valueOf(fullscreen));
        mPlayer.setFullscreen(false);
        fullScreenListener.startFullScreen();
    }

}

我还用自己的活动处理全屏活动,这个浏览页不仅包含youtube视频,还包含图片,所以请忽略这些部分。

因为我在片段中使用视图分页程序,所以我使用getChildFragmentManger,而且我在活动中也使用这个适配器,但它产生了另一个问题,第一个视频不会在第一次视图分页程序加载时播放,因为在适配器中侦听器是在getItem()之前调用的,所以我做了一些更改,如果适配器是第一次加载(第一个youtube页面是第一次加载),侦听器将在getItem返回片段之后立即调用,其他的都是一样的。

票数 0
EN

Stack Overflow用户

发布于 2017-11-05 03:51:54

所以基本上,问题是你的一个视频被加载到了可见屏幕之外,导致了覆盖错误。在查看器的情况下,已加载的页面也会加载视频,但这些视频不在屏幕上,从而导致错误。

解决方案( viewpager):一次加载一个视频,即需要播放的视频。这可以通过在页面可见时加载视频来实现。

票数 0
EN

Stack Overflow用户

发布于 2017-11-05 20:01:52

这不可能。因为YouTubePlayerView需要它的活动来扩展YoutubeBaseActivity。YouTubePlayerView提供的功能有限。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44427611

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档