现在我正试着用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代码
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 studio的日志。我已经附上了截图。This is the screenshot
发布于 2017-08-17 03: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。
mInitializeListener = new InitializeListener() {
@Override
public void startVideo() {
initialize();
}
@Override
public void stopVideo() {
mPlayer.release();
}
};
还有一些我不能回答的问题,比如为什么你在一个寻呼机里的播放器会影响其他人…?
但当我在适配器和片段上做了更改时,youtube视频可以正常播放,希望这能对你有所帮助
以下是我在应用程序中使用的代码
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);
适配器
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片段
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返回片段之后立即调用,其他的都是一样的。
发布于 2017-11-04 19:51:54
所以基本上,问题是你的一个视频被加载到了可见屏幕之外,导致了覆盖错误。在查看器的情况下,已加载的页面也会加载视频,但这些视频不在屏幕上,从而导致错误。
解决方案( viewpager):一次加载一个视频,即需要播放的视频。这可以通过在页面可见时加载视频来实现。
发布于 2017-11-05 12:01:52
这不可能。因为YouTubePlayerView需要它的活动来扩展YoutubeBaseActivity。YouTubePlayerView提供的功能有限。
https://stackoverflow.com/questions/44427611
复制相似问题