-
Notifications
You must be signed in to change notification settings - Fork 52
/
Copy pathplaylistItems.php
106 lines (97 loc) · 3.88 KB
/
playlistItems.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<?php
header('Content-Type: application/json; charset=UTF-8');
$playlistItemsTests = [
// not precise...
// Preferably have only more than 200 different videos but that I own would be more robust
//['part=snippet&playlistId=PLKAl8tt2R8OfMnDRnEABZ2M-tI7yJYvl1', 'items/0/snippet/publishedAt', 1520963713]
];
include_once 'common.php';
if (isset($_GET['part'], $_GET['playlistId'])) {
$part = $_GET['part'];
if (!in_array($part, ['snippet'])) {
dieWithJsonMessage('Invalid part');
}
$playlistId = $_GET['playlistId'];
if (!isPlaylistId($playlistId)) {
dieWithJsonMessage('Invalid playlistId');
}
$continuationToken = '';
if (isset($_GET['pageToken'])) {
$continuationToken = $_GET['pageToken'];
if (!isContinuationToken($continuationToken)) {
dieWithJsonMessage('Invalid pageToken');
}
}
echo getAPI($playlistId, $continuationToken);
} else if(!test()) {
dieWithJsonMessage('Required parameters not provided');
}
function getAPI($playlistId, $continuationToken)
{
$continuationTokenProvided = $continuationToken != '';
$http = [];
$url = '';
if ($continuationTokenProvided) {
$url = 'https://www.youtube.com/youtubei/v1/browse?key=' . UI_KEY;
$rawData = [
'context' => [
'client' => [
'clientName' => 'WEB',
'clientVersion' => MUSIC_VERSION
]
],
'continuation' => $continuationToken
];
$http['method'] = 'POST';
$http['header'] = ['Content-Type: application/json'];
$http['content'] = json_encode($rawData);
} else {
$url = "https://www.youtube.com/playlist?list=$playlistId";
$http['header'] = ['Accept-Language: en'];
}
$httpOptions = [
'http' => $http
];
if ($continuationTokenProvided) {
$result = getJSON($url, $httpOptions);
} else {
$result = getJSONFromHTML($url, $httpOptions);
}
$answerItems = [];
$items = $continuationTokenProvided ? getContinuationItems($result) : getTabs($result)[0]['tabRenderer']['content']['sectionListRenderer']['contents'][0]['itemSectionRenderer']['contents'][0]['playlistVideoListRenderer']['contents'];
$itemsCount = count($items);
for ($itemsIndex = 0; $itemsIndex < $itemsCount - 1; $itemsIndex++) {
$item = $items[$itemsIndex];
$playlistVideoRenderer = $item['playlistVideoRenderer'];
$videoId = $playlistVideoRenderer['videoId'];
$title = $playlistVideoRenderer['title']['runs'][0]['text'];
$publishedAt = getPublishedAt($playlistVideoRenderer['videoInfo']['runs'][2]['text']);
$thumbnails = $playlistVideoRenderer['thumbnail']['thumbnails'];
$answerItem = [
'kind' => 'youtube#playlistItem',
'etag' => 'NotImplemented',
'snippet' => [
'publishedAt' => $publishedAt,
'title' => $title,
'thumbnails' => $thumbnails,
'resourceId' => [
'kind' => 'youtube#video',
'videoId' => $videoId
]
]
];
array_push($answerItems, $answerItem);
}
$nextContinuationToken = urldecode($items[100]['continuationItemRenderer']['continuationEndpoint']['continuationCommand']['token']); // it doesn't seem random but hard to reverse-engineer
$answer = [
'kind' => 'youtube#playlistItemListResponse',
'etag' => 'NotImplemented'
];
// order matter or could afterwards sort by an (official YT API) arbitrary order (not alphabetical)
// seems to be this behavior with the official API
if ($nextContinuationToken != '') {
$answer['nextPageToken'] = $nextContinuationToken;
}
$answer['items'] = $answerItems;
return json_encode($answer, JSON_PRETTY_PRINT);
}