Reputation: 81
Now I am trying to play Youtube video in a fragment of ViewPager using YouTubePlayerSupportFragment. I am using SmartFragmentStatePagerAdapter as a viewpager adapter. But I got this error :
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{41a53898 VFED.... ......I. 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).
How can I solve this issue. Regards
This is FragmentPageAdapter code
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();
}
}
and I have implemented code in 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);
}
}
and I have tested it in real device
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).
this is log in Android studio. I have attached the screenshots. This is the screenshot
Upvotes: 1
Views: 3447
Reputation: 79
It's not possible. Because YouTubePlayerView requires its activity to extend YoutubeBaseActivity. YouTubePlayerView provides limited functionality.
Upvotes: 1
Reputation: 1
So basically, the problem is that one of your videos is being loaded outside the visible screen causing the error of overlay. In the case of a viewpager, the already loaded pages also load the video but those videos are not on screen causing the error.
SOLUTION (for viewpager): Load one video at a time, i.e. the video to be played. Do this by loading the video whenever the page is visible.
Upvotes: 0
Reputation: 11
This answer maybe to late, but I found a possible solution.
I' run into similar problem, I also try to play multiple videos in viewpager. If there's only one youtube fragment in viewpager, and it's ok, but when there's more then one, video won't play, and show that error message
YouTube video playback stopped due to unauthorized overlay on top of player.
First "unauthorized overlay" is not come from my current fragment which is on the visible page of view pager. it come from the page that view pager create "next" to the current fragment.
View pager create pages before they are slide into visible window, so the youtube fragment are create before it is visible, and if you initialize that fragment, then youtube player detect that strange overlay error and stop the video, and the youtube player stop, even stop the video which is showing normally in the visible page.
In your case, you can see the error message
left: 480, top: 0, right: -480, bottom: 376
which the negative number is a window wide, so it's probability same as the issue I got.
So my solution
1. No't initialize the youtube at onCreate(), don't do the initialize before that fragment is the visible of the viewpager.
in my case, I use a interface between adapter and fragment, and in the parent page of the viewpager, add a OnPageChangeListener to viewpager, youtube fragment only initialize after viewpager's page is change to that youtube fragment.
page change > notify adapter > interface > youtubefragment > start initialize
After first step, first video should play normally even if there's 2 or more youtube fragment in viewpager, but when I swipe to 2nd page, video won't play and show the same error, so move to 2nd step
2. release youtube player when youtube fragment is slide to invisible part of view pager
the reason of 2nd video not playing is same, first page has a youtubeplayer and it out side the visible range, and it got an error message, which stop all youtubeplayer for a reason I don'y know why.
I use the same interface, when page is changed. adapter will use the interface to notify the youtube fragment which is slide away, to release youtubeplayer, and the interface implement like this, which mPlayer will be the youtubeplayer return by initialize method.
mInitializeListener = new InitializeListener() {
@Override
public void startVideo() {
initialize();
}
@Override
public void stopVideo() {
mPlayer.release();
}
};
there's still some questions I can't answer, like why youtubeplayer in one pager will effect others..?
but when I did the changes at my adapter and fragment, youtube video can play normally, hope this helps you
below are codes I use in my app
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);
Adapter
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 Fragment
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();
}
}
I also handle full screen event with my own activity, and this viewpager contents not only youtube video, but also picture, so please ignore those part.
because I use view pager in fragment, so I use getChildFragmentManger, and I also use this adapter in Activity, but It creates another problem, that first video won't play at the first time viewpager isload , because the listener is call before getItem() in the adapter, So I made some changes that if adapter is first load(first youtube page is load at first time), listener will be call right after getItem return the fragment, other's are all the same.
Upvotes: 0