javayoutubeyoutube-apiyoutube-data-apiyoutube-channels

Determine a YouTube channel's upload rate using YouTube Data API v3


I am writing a Java application that uses YouTube Data API v3. I want to be able to determine a channel's upload rate. For example, if a channel is one week old, and has published 2 videos, I want some way to determine that the channel's upload rate is 2 videos/week. How would I do this using the YouTube API?

import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.Channel;
import com.google.api.services.youtube.model.ChannelListResponse;

import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.util.Collection;
import java.util.Collections;
import java.util.Properties;

public class ApiExample {
    public static void main(String[] args)
            throws GeneralSecurityException, IOException, GoogleJsonResponseException {
        Properties properties = new Properties();
        try {
            InputStream in = ApiExample.class.getResourceAsStream("/" + "youtube.properties");
            properties.load(in);

        } catch (IOException e) {
            System.err.println("There was an error reading " + "youtube.properties" + ": " + e.getCause()
                    + " : " + e.getMessage());
            System.exit(1);
        }
        YouTube youtubeService = new YouTube.Builder(new NetHttpTransport(), new JacksonFactory(), new HttpRequestInitializer() {
            public void initialize(HttpRequest request) throws IOException {
            }
        }).setApplicationName("API Demo").build();
        // Define and execute the API request
        YouTube.Channels.List request = youtubeService.channels()
                .list("snippet,contentDetails,statistics");
        String apiKey = properties.getProperty("youtube.apikey");
        request.setKey(apiKey);
        ChannelListResponse response = request.setId("UC_x5XG1OV2P6uZZ5FSM9Ttw").execute();
        for (Channel channel : response.getItems()) {
            /* What do I do here to get the individual channel's upload rate? /
        }
    }
}

The above example uses the YouTube Developers channel, but I want to be able to do this with any channel.


Solution

  • According to the official docs, once you invoke the Channels.list API endpoint -- that returns the specified channel's meta-data, a Channels resource --, you have at your disposal the following property:

    statistics.videoCount (unsigned long)
    The number of public videos uploaded to the channel.

    Therefore, things are almost obvious: make the value returned by this property persistent (e.g. save it into a file) and arrange your program such that to be issued weekly for to compute your desired upload rate.


    Now, for what concerns your code above, you should first get rid of:

    for (Channel channel : response.getItems()) {
        /* What do I do here to get the individual channel's upload rate? /
    }
    

    since the items property will contain at most one item. A good practice would be to assert this condition:

    assert response.getItems().size() <= 1;
    

    The value of the needed videoCount property will be accessible under the method getVideoCount of ChannelStatistics class:

    response.getItems().get(0).getStatistics().getVideoCount().

    Of course, since is always good to ask from the API only the info that is really of use, I would also recommend you to use the parameter fields (the method setFields) in the form of:

    request.setFields("items(statistics(videoCount))"),

    inserted, for example, after request.setKey(apiKey).

    This way the API will send back to you only the property that you need.


    Addendum

    I also have to mention that the assertion above is correct only when you pass to the API endpoint (as you currently do within your code above) one channel ID only. If in the future you'll want to compute in one go the upload rate of N channels (with N <= 50), then the condition above will look like size() <= N.

    The call of Channels.list in one go on multiple channels is possible, since this endpoint's id property is allowed to be specified as a comma-separated list of channel IDs.