4

I've started using YouTube API for Android a month ago. I'm trying to make an Android application which can play some videos which includes my uploaded videos. With the public videos, it works. But with the private videos, YoutubePlayerView shows: "Please sign in".

I couldn't figure out how to sign in and play these videos since YoutubeAndroidPlayerAPI seems not support authentication.

This is what I'm doing with "JurB9k3_Ws4" is my private video ID.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.playerview_demo);

    YouTubePlayerView youTubeView = (YouTubePlayerView) findViewById(R.id.youtube_view);
    youTubeView.initialize(DeveloperKey.DEVELOPER_KEY, new YouTubePlayer.OnInitializedListener() {

        @Override
        public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer,
                                            boolean b) {
            youTubePlayer.cueVideo("JurB9k3_Ws4");
        }

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

        }
    });
}
JAL
  • 41,701
  • 23
  • 172
  • 300
kid9591
  • 43
  • 1
  • 6

2 Answers2

5

This is not possible with the Android Player API. The only way to play private videos on a device is to implement a WebView in your app, have the user log into their YouTube account, and then play back the Private video in that specific browser session only. YouTube suggests marking videos as Unlisted rather than Private for playback on mobile devices.

More info in this Google Groups post about playing back private videos using the embedded player.

Playing back a private video in an embedded player will only work if you have a YouTube login cookie in your browser that corresponds to an account that is permissioned to watch that video. Otherwise, it will fail. Authentication with the Data API has nothing to do with whether you can play the video back in an embedded player.

...

There's no programmatic way to create a login cookie. The user actually has to login to YouTube.com using the same browser instance that's using the embed, and that can't be scripted.

JAL
  • 41,701
  • 23
  • 172
  • 300
  • Thanks a lot, you saved my day. Anyway, why don't Google provide us a way to authenticate using PlayerAPI? It's weird to use WebView in an Android application just to play youtube video :( – kid9591 Apr 07 '15 at 08:01
  • @user1992438 I don't know why they don't provide this "basic" feature. I would reach out to YouTube directly and voice your concern. If other developers want the same feature, they may implement it. – JAL Apr 08 '15 at 17:02
  • Thank JAL. I hope to see that useful feature someday. – kid9591 Apr 13 '15 at 15:37
0

As long as you app uses oath and is verified you can build and play private playlists as if you were the user of the account [for that account]. Using the youtube v3 api and the .player api. If not authenticated properly for whatever reason, you can run into situations where the api lets you create a private playlist as a user of the account but the list is empty within the player api.

also, you can actually play private video:

@SuppressLint("StaticFieldLeak")
private void loadUploadedVideos() {
    if (mChosenAccountName == null) {
        return;
    }

    Log.d(TAG, "loadUploads");

    showProgressDialog();
    new AsyncTask<Void, Void, List<VideoData>>() {
        @Override
        protected List<VideoData> doInBackground(Void... voids) {

            try {

                YouTube youtube = new YouTube.Builder(transport, jsonFactory,
                    credential).setApplicationName(Constants.APP_NAME)
                    .build();


                /*
                 * Now that the user is authenticated, the app makes a
                 * channels list request to get the authenticated user's
                 * channel. Returned with that data is the playlist id for
                 * the uploaded videos.
                 * https://developers.google.com/youtube
                 * /v3/docs/channels/list
                 */
                ChannelListResponse clr = youtube.channels()
                        .list("contentDetails").setMine(true).execute();

                // Get the user's uploads playlist's id from channel list
                // response
                String uploadsPlaylistId = clr.getItems().get(0)
                        .getContentDetails().getRelatedPlaylists()
                        .getUploads();

                List<VideoData> videos = new ArrayList<VideoData>();

                // Get videos from user's upload playlist with a playlist
                // items list request
                PlaylistItemListResponse pilr = youtube.playlistItems()
                        .list("id,contentDetails")
                        .setPlaylistId(uploadsPlaylistId)
                        .setMaxResults(50L).execute();
                List<String> videoIds = new ArrayList<String>();

                // Iterate over playlist item list response to get uploaded
                // videos' ids.
                for (PlaylistItem item : pilr.getItems()) {
                    videoIds.add(item.getContentDetails().getVideoId());
                }

                // Get details of uploaded videos with a videos list
                // request.
                VideoListResponse vlr = youtube.videos()
                        .list("id,snippet,status")
                        .setId(TextUtils.join(",", videoIds)).execute();

                // Add only the public videos to the local videos list.
                for (Video video : vlr.getItems()) {
                    //if ("public".equals(video.getStatus().getPrivacyStatus())) {
                        VideoData videoData = new VideoData();
                        videoData.setVideo(video);
                        videos.add(videoData);
                    //}
                }

                // Sort videos by title
                Collections.sort(videos, new Comparator<VideoData>() {
                    @Override
                    public int compare(VideoData videoData,
                                       VideoData videoData2) {
                        return videoData.getTitle().compareTo(
                                videoData2.getTitle());
                    }
                });

                return videos;

            } catch (final GooglePlayServicesAvailabilityIOException availabilityException) {
                showGooglePlayServicesAvailabilityErrorDialog(availabilityException
                        .getConnectionStatusCode());
            } catch (UserRecoverableAuthIOException userRecoverableException) {
                startActivityForResult(
                        userRecoverableException.getIntent(),
                        REQUEST_AUTHORIZATION);
            } catch (IOException e) {
                Utils.logAndShow(MainActivity.this, Constants.APP_NAME, e);
            }
            catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }

            return null;
        }

        @Override
        protected void onPostExecute(List<VideoData> videos) {

            if (videos == null) {
                hideProgressDialog();
                return;
            }

            if (mMyUploadsFragment != null)
                mMyUploadsFragment.setUploads(videos);
            hideProgressDialog();
        }

    }.execute((Void) null);
}

Also once authenticated, youtube prime features are available in the player api. Nice. The trick seems to be to log the Youtube user into the youtube app on the phone as well as using the same creds in your own app.

anyway any playlist the app is authenticated to play on android can be played this way:

 public void onPlaylistSelected(PlaylistData playlist) {
    
    try {
        mPlaylistData = playlist;
        //Intent intent = YouTubeIntents.createPlayPlaylistIntent(this, playlist.getId());
        Intent intent = YouTubeIntents.createOpenPlaylistIntent(this, playlist.getId());
        startActivity(intent);
    } catch (ActivityNotFoundException e) {
        Log.w(TAG,e.getMessage());
        Toast.makeText(this, R.string.warn_install_yt,Toast.LENGTH_LONG).show();
    }
}