Anthony
Anthony

Reputation: 742

Youtube Data API - How to get my private and unlisted videos

Last year I was able to retrieve videos of all statuses (upon authenticating via OAuth) via Playlistitems > list specifying the playlist containing all uploads.

As of today, the same code only gives me public uploads:

import os
import google_auth_oauthlib.flow
import googleapiclient.discovery
import googleapiclient.errors

scopes = ["https://www.googleapis.com/auth/youtube.readonly"]

def main():
    # Disable OAuthlib's HTTPS verification when running locally.
    # *DO NOT* leave this option enabled in production.
    os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"

    api_service_name = "youtube"
    api_version = "v3"
    client_secrets_file = "CLIENT_SECRETS.json"

    # Get credentials and create an API client
    flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file(
        client_secrets_file, scopes)
    credentials = flow.run_console()
    youtube = googleapiclient.discovery.build(
        api_service_name, api_version, credentials=credentials)

    request = youtube.playlistItems().list(part="snippet", maxResults=50, playlistId="__PLAYLIST__ID")    
    response = request.execute()
    total = response['pageInfo']['totalResults']
    print("total number of videos is " + str(total));
    exit();

if __name__ == "__main__":
    main()

I am aware that others have asked this question but they are either really old posts or not answered comprehensively.

The only other possibile method seems to be Search > list specifying the channel ID but this too only returned public videos despite authenticating via OAuth:

import os
import google_auth_oauthlib.flow
import googleapiclient.discovery
import googleapiclient.errors

scopes = ["https://www.googleapis.com/auth/youtube.force-ssl"]

def main():
    # Disable OAuthlib's HTTPS verification when running locally.
    # *DO NOT* leave this option enabled in production.
    os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"

    api_service_name = "youtube"
    api_version = "v3"
    client_secrets_file = "YOUR_CLIENT_SECRET_FILE.json"

    # Get credentials and create an API client
    flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file(
        client_secrets_file, scopes)
    credentials = flow.run_console()
    youtube = googleapiclient.discovery.build(
        api_service_name, api_version, credentials=credentials)

    request = youtube.search().list(
        part="snippet",
        channelId="___CHANNEL__ID___",
        type="video"
    )
    response = request.execute()

    print(response)

if __name__ == "__main__":
    main()

The documentation claims that setting the forMine parameter:

[...] can only be used in a properly authorized request. The forMine parameter restricts the search to only retrieve videos owned by the authenticated user. If you set this parameter to true, then the type parameter's value must also be set to video.

However, this resulted in an invalid request when I included forMine set to true.

Any advice on how to currently get private / unlisted YouTube video data would be much appreciated.

Upvotes: 1

Views: 1810

Answers (2)

Asd_pr
Asd_pr

Reputation: 1

You can find the "Uploads" playlist. Use "mine=True".

youtube = googleapiclient.discovery.build('youtube', 'v3', credentials=credentials)
r = youtube.channels().list(
    part='contentDetails',
    mine=True).execute()
uploads_playlist_id = r['items'][0]['contentDetails']['relatedPlaylists']['uploads']

Next, you can get all videos in this playlist

r = youtube.playlistItems().list(playlistId=uploads_playlist_id, 
part=snippet, maxResults=50).execute()
for item in r['items']:
    #...

Upvotes: 0

stvar
stvar

Reputation: 6985

I would not rely much on totalResults; this property is not reliable by its very specification (the emphasis below is mine):

pageInfo.totalResults (integer)

The total number of results in the result set. Please note that the value is an approximation and may not represent an exact value. In addition, the maximum value is 1,000,000.

You should not use this value to create pagination links. Instead, use the nextPageToken and prevPageToken property values to determine whether to show pagination links.

If only needing the number of items of a given playlist, identified by its ID PLAYLIST_ID, I'd recommend querying the Playlists.list API endpoint with id=PLAYLIST_ID and looking for the property contentDetails.itemCount.

But, otherwise, if upon paginating (using the PlaylistItems.list endpoint), the API wouldn't provide you all the private and unlisted videos (assuming that you passed on to the endpoint a valid access token), then most likely that's a bug of the API that needs to be reported.

Also, do note that, according to YouTube's staff, there's an upper 20000 limit set by design for the number of items returned via PlaylistItems.list endpoint (nota bene: the design itself changes over time: as far as I know, not long ago this limit did not existed).

Upvotes: 1

Related Questions