How to protect your child from debris on YouTube and make a custom player with a white list of channels
You can argue for a long time on whether to give small children access to tablets and smartphones. Someone says that it is harmful to the eyes or to the psyche, someone - that parents should play and read with the children themselves, and not try to isolate themselves from them with gadgets. Which is typical, most often this is said by people who do not have their children. And who do not know what kind of bliss is - when the child becomes silent for at least half an hour, stops smashing everything around, quietly lies on the sofa and watches cartoons. There is one more argument - children sensitively repeat everything after their parents, if the parents are constantly buried in the phone, it is very difficult to explain to the children why parents can and they don’t.
In general, you can shower me with rotten tomatoes, but my son, who is now without a couple of days for three years, from time to time lies with the tablet on the couch and looks at the mulika on YouTube.
Unfortunately, I very quickly realized that the kids YouTube is just a hell TRESH. About it even on Habré was already a translation of the article . Children's channels are some kind of bottomless cesspool, filled with vigorous eyes like "unfolding a hundred kinder surprises", "stupid rhymes with poor 3d graphics under noisy music" and "we are driving cars into Beam NG under foolish comments". For some reason, all this is very attractive for young children who rush to click on such videos as soon as they see them recommended. And YouTube does not allow to manage recommendations. Even after giving my son a tablet with the included "normal" cartoons, after a couple of minutes, I watch him again, after two clicks on the recommendations, again find these damn chocolate eggs and start sticking in them again.
Everything, I had enough, I decided. And he began to cut his application for viewing YouTube, allowing you to select a list of channels and showing only the video from these channels. How I did it - under the cut.
Here is one example of treshevideo with which we will fight. Shitty made meaningless 3D animation with stupid music - and 142 million views. For some reason, these videos of children just zombie, they are ready to revise them and revise.
To compare the scale - the coolest movie where Chris Hadfield sings with a guitar on the ISS has only 40 million views, and the wonderful OK GO clip with real weightlessness (no cables and chromakey, only fair weightlessness on board a special aircraft) - only 12 million, ten times less.
By the way, advertisers on YouTube are not happy about the popularity of children's channels , since showing ads on them is a waste of budgets. Children watch ads, sometimes even click, but do not buy anything, and millions of views quickly spend the budget.
Formulation of the problem
I must say that I did not set the task to make an application impenetrable for children. There are already such attempts, including here in Habré - everything is cut there so that the child cannot exit the application, buy something, open a browser, etc. There are options with hardware locks, disconnected ports, custom android shells and other difficulties (for example, here's an article for 2012, the project seems to be still alive). But it all makes sense for older children, who are already exploring the full potential of their gadgets. For children of 2-3 years no special protection is needed, they are quite happy to watch the video and from time to time to poke in thumbnails of other videos. The main thing is that these videos should be what you need, and not what YouTube will offer (and he will offer endless chocolate eggs and baby fingers).
From this was born the list of requirements:
- Custom channel list
- Protecting him from change (rather, from accidental, because tricky adult children already have a bunch of ways to recognize their passwords)
- The application itself is similar to YouTube, on the left is a video, on the right is a column of thumbnails that can be clicked.
- The main use-case is random poking through the video; in general, the child doesn’t care what it is to watch.
At the same time, the work of the application consists of two main parts: search and tuning channels using the YouTube Data API and then playing the video. Moreover, I currently have two options for playing video within my own application:
YouTube Android Player API
https://developers.google.com/youtube/android/player/
This is the official way to play videos in your android application. To work on the user's device, the official YouTube app should already be installed, which includes some service that can be used from other apps. So this Player API is a small library that interacts with a separately installed application.
At first I used it, but after some time of use, it turned out that he had a critical problem. It is impossible to properly customize the appearance of the player, in particular, to control the buttons (you can only hide everything as a whole, but then you will lose the buttons of the full-screen mode). And on the player control panel there is a bad button "go to viewing on YouTube", which opens the official application (which must be on the device), in which there is already no filtering. And the children easily (accidentally or not) click on it, go to the unfiltered application, and after a few minutes I hear the “baby finger, baby finger where are you” again and see some vigorous trachemical animations on the screen.
Another little trash that children find in a couple of clicks. Over 900 million views!
Therefore, I refused the official player, having found a replacement for it in the form of the next library.
Android YouTube Player
https://github.com/PierfrancescoSoffritti/android-youtube-player
The library looks like a wrapper around WebView that manages the web player through its JavaScript API. Of the benefits - the possibility of complete customization of the interface.
Initialization of the player is slightly unobvious, especially after switching from the official library:
- We get our com.pierfrancescosoffritti.androidyoutubeplayer.player.YouTubePlayerView view.
- Call it initialize (), passing a listener
- The onInitSuccess (@Nonnull final YouTubePlayer youTubePlayer) method is called on the listener, receiving an instance of the player object. This is the only way to get it. Up to this point, the initialization process was identical to that of the official client.
- We call the addListener () method on the player, passing another listener to it (more listeners to the listeners god!)
- The onReady () method is called for this listener - only after this point can you download and show video and use the player. If by mistake you try to load something into onInitSuccess, then the library will start spitting out strange errors.
Manage the life cycle of the player (stop playback in onPause () and stuff like that) can be manually or you can register our view as Lifecycle Observer (for which our Activity should be inherited from AppCompatActivity). In this case, the library will take over the entire routine.
Another strange nuance of the library is the lack of support for full-screen mode out of the box. The button for it is by default in the player, but does not do anything. In fact, you have to do the full-screen mode manually — hide the player, maximize the player window to full screen, and then restore everything back. This can be quite nontrivial if you have some kind of complex interface around the player. I only had a video list there that is easily hidden by hand.
In the library samples there is a class FullScreenHelper, from which you can take the necessary code. Its use looks something like this:
youTubePlayerView.addFullScreenListener(new YouTubePlayerFullScreenListener() {
privatefinal View rootLayout = findViewById(R.id.rootLayout);
@OverridepublicvoidonYouTubePlayerEnterFullScreen(){
fullScreenHelper.enterFullScreen();
rootLayout.setPadding(0, 0, 0, 0);
}
@OverridepublicvoidonYouTubePlayerExitFullScreen(){
fullScreenHelper.exitFullScreen();
rootLayout.setPadding(8, 8, 8, 8);
youTubePlayerView.getLayoutParams().height = LinearLayout.LayoutParams.MATCH_PARENT;
}
});
FullScreenHelper hides the extra interface and sets the screen display flags. I also had to pitch in the indentation (constants in the code is evil, I know), and for some reason, the height at the exit from fullscreen was lost if it was not corrected manually.
In general, a lot of minuses somehow turned out at this library, but everything covers the main plus - the ability to customize the player interface. It was enough for me to hide the "show on YouTube" button, while retaining the full-screen mode:
youTubePlayerView.getPlayerUIController().showFullscreenButton(true);
youTubePlayerView.getPlayerUIController().showYouTubeButton(false);
In general, there you can control all the buttons, display the current time, you can add your own View, etc. - in the end, according to the possibilities of customization, this library leaves its official competitor far behind.
Well, after working on setting up the player, the new video is loaded simply as youTubePlayer.loadVideo (url, startTime);
Getting video lists, working with YouTube Data API
You need to get the video URL from somewhere else. Fortunately, YouTube has a rich API that allows you to do all sorts of search queries and get information about the channels. To start using it, you need to connect it in your Developer Console and get the key.
For the application to work, we need two functions: search for channels and get a list of videos for this channel. The search looks something like this, we want to search for channels and playlists for the query "Peppa Pig". We are interested in id (to later download the video list for the channel by its id) and snippet it contains basic information about the entity: name, picture preview, description.
YouTube.Search.List searchListByKeywordRequest = youTube.search().list("snippet,id");
searchListByKeywordRequest.setMaxResults(10L);
searchListByKeywordRequest.setQ("Peppa Pig");
searchListByKeywordRequest.setType("channel,playlist");
searchListByKeywordRequest.setKey("<api key>");
SearchListResponse response = searchListByKeywordRequest.execute();
It is important to correctly set the list of those parts of the object (in this case, snippet and id) that we want to receive. The YouTube API uses a rather complex system for limiting requests: the default daily quota is a million units, but a single request can consume a lot of units. Most of the time, requests that write something (upload videos, or change playlists) are consumed, but reading requests can consume a lot too. Requests for reading data consume one quota unit by themselves, plus two units for each piece of data. Those. for example, this one, which is the query above, consumes 5 units (one for the query itself and 2 for each of the sinppet and id fragments). And a full request for all data on a channel that has 6 fragments would have eaten 13. 10 fragments are available for a video, so a full request will be eaten by 21 quota units.
The request for getting a list of videos from the channel looks like this:
YouTube.Search.List request = youTube.search().list("snippet,id");
request.setChannelId("<channel id>");
request.setType("video");
request.setMaxResults(50L);
request.setKey("<api key>");
SearchListResponse response = request.execute();
The answer is not clearly divided into pages, instead of explicitly specifying the page number and the number of results, the nextPageToken parameter may be present in the response; if it is, then there are still pages ahead, you need to put this parameter into the request object and execute the request again.
if (response.getNextPageToken() != null) {
request.setPageToken(response.getNextPageToken());
response = request.execute();
}
In general, the API is well documented, there are ready examples of code in many languages, examples of requests for launching in the browser, etc.
Experience of use
After the first version was ready, testing began. First on my family, then I put it on Google Play and started collecting feedback from users. Immediately clarified the nuances:
- In addition to channels, playlists were also needed. Since on one channel often normal videos were combined with hellish trash. For example, on Teremok TV there are some good cartoons about the princess and all the crap out of the world (Bibika or Doctor of the Machine Typewriter), because of which I didn’t want to add a channel entirely.
- And then - also separate videos. For example, there are channels where there are selections like "all series of the animated series in one video", and again I want to select individual videos, and not the entire channel.
- It took back to the previous video. For the hysterical child who accidentally jabbed his finger in the next video and can no longer go back to the one that he had just watched - this is not a joke.
- Now I realized that I also need a search. Because "I want a cartoon about cars and ghosts," while there is no search in the application, and poking a finger in the hope that it will randomly give out this damn cartoon for a long time.
- I already wrote above about disabling the browse button on YouTube.
- I also want to fasten Pinned Mode - starting with the fifth android, you can make it so that in order to minimize the application you had to press and hold several buttons at once.
If someone liked the idea - https://play.google.com/store/apps/details?id=ru.sundogs.youtubekiosk In the free version, you can add only three channels, write in a personal version - I’ll give you the key to remove the restriction. Well, who wants to support the development - maybe buy an unlock in the application itself. And while I'm slowly finishing new features for requests, well, I am glad that now I can be sure of the quality of what my son is watching.
And no, he doesn’t sit out for days on the tablet, but rather prefers walks and active games, hide-and-seek and drawing on everything (from wallpapers to toys), and in the evening he likes to listen to fairy tales. Tablet and cartoons are just one of the possible tools for entertaining a child, but at the same time one of the most difficult to manage. What is partly intended to fight my application.
UPD : A lot of people asked for keys, I could accidentally confuse and send one key to several people. So if you wrote that the key has already expired or not found - write, send a new one. The key must be entered in the Play Market in the "Promo" section
UPD2 : As I was warned in the comments, Google nailed my app and my developer account. Judging by the fact that they wrote on Habré, complain or try to figure out what's the matter with Google is absolutely useless.
UPD3 : Untied the application from google api, you can download the apk now here: https://channelwhitelist.tilda.ws . Get rid of Google!