Skip to content

Commit

Permalink
Fix #300: Update search?type=shorts following YouTube UI change
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjamin-Loison committed Sep 16, 2024
1 parent b38a475 commit 19c5bba
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 19 deletions.
5 changes: 5 additions & 0 deletions common.php
Original file line number Diff line number Diff line change
Expand Up @@ -591,4 +591,9 @@ function includeOnceProtos($protos) {
}
}

// Source: https://www.php.net/manual/en/function.base64-encode.php#103849
function base64url_encode($data) {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

?>
32 changes: 32 additions & 0 deletions proto/prototypes/browse_shorts.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
syntax = "proto3";

message BrowseShorts {
Sub0BrowseShorts two = 2;
int32 three = 3;
string four = 4;
}

message Sub0BrowseShorts {
string two = 2;
string three = 3;
}

message Sub1BrowseShorts {
Sub2BrowseShorts two = 2;
}

message Sub2BrowseShorts {
Sub3BrowseShorts eighteen = 18;
}

message Sub3BrowseShorts {
Sub4_7BrowseShorts seven = 7;
Sub4_9BrowseShorts nine = 9;
}

message Sub4_7BrowseShorts {
int32 twelve = 12;
}

message Sub4_9BrowseShorts {
}
57 changes: 38 additions & 19 deletions search.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@

include_once 'common.php';

includeOnceProtos([
'BrowseShorts',
'Sub0BrowseShorts',
'Sub1BrowseShorts',
'Sub2BrowseShorts',
'Sub3BrowseShorts',
'Sub4_7BrowseShorts',
'Sub4_9BrowseShorts',
]);

$realOptions = [
'id',
'snippet',
Expand Down Expand Up @@ -112,14 +122,32 @@ function getAPI($id, $order, $continuationToken)
'clientVersion' => MUSIC_VERSION
]
],
'query' => str_replace('"', '\"', $_GET['q'])
];
if(isset($_GET['type']) && $_GET['type'] === 'short') {
$sub1BrowseShorts = (new \Sub1BrowseShorts())
->setTwo((new \Sub2BrowseShorts())
->setEighteen((new \Sub3BrowseShorts())
->setSeven((new \Sub4_7BrowseShorts())
->setTwelve(26))
->setNine(new \Sub4_9BrowseShorts())));
$browseShorts = (new \BrowseShorts())
->setTwo((new \Sub0BrowseShorts())
->setTwo($_GET['q'])
->setThree(base64_encode($sub1BrowseShorts->serializeToString())))
->setThree(52047873)
->setFour('search-page');

$continuation = base64url_encode($browseShorts->serializeToString());
$rawData['continuation'] = $continuation;
} else {
$rawData['query'] = str_replace('"', '\"', $_GET['q']);
if($typeBase64 !== '') {
$rawData['params'] = $typeBase64;
}
}
if($continuationTokenProvided) {
$rawData['continuation'] = $continuationToken;
}
if($typeBase64 !== '') {
$rawData['params'] = $typeBase64;
}
$opts = [
'http' => [
'method' => 'POST',
Expand All @@ -130,15 +158,7 @@ function getAPI($id, $order, $continuationToken)
$json = getJSON('https://www.youtube.com/youtubei/v1/search?key=' . UI_KEY, $opts);
if(isset($_GET['type']) && $_GET['type'] === 'short')
{
$contents = $json['contents']['twoColumnSearchResultsRenderer']['primaryContents']['sectionListRenderer']['contents'][0]['itemSectionRenderer']['contents'];
foreach($contents as $content)
{
if(array_key_exists('reelShelfRenderer', $content))
{
$items = $content['reelShelfRenderer']['items'];
break;
}
}
$items = $json['onResponseReceivedCommands'][0]['reloadContinuationItemsCommand']['continuationItems'][0]['twoColumnSearchResultsRenderer']['primaryContents']['sectionListRenderer']['contents'][0]['itemSectionRenderer']['contents'];
}
else
{
Expand Down Expand Up @@ -178,13 +198,12 @@ function getAPI($id, $order, $continuationToken)
for ($itemsIndex = 0; $itemsIndex < $itemsCount - ($continuationTokenProvided || $_GET['hashtag'] ? 1 : 0); $itemsIndex++) { // check upper bound for hashtags
$item = $items[$itemsIndex];
$path = '';
$isShort = isset($_GET['type']) && $_GET['type'] === 'short';
if (isset($_GET['hashtag'])) {
$path = 'richItemRenderer/content/videoRenderer';
} elseif (isset($_GET['q'])) {
$path = $isShort ? 'reelItemRenderer' : 'videoRenderer';
$path = 'videoRenderer';
// Skip `People also watched`.
if(!$isShort && !array_key_exists($path, $item)) {
if(!array_key_exists($path, $item)) {
continue;
}
} else {
Expand All @@ -203,11 +222,11 @@ function getAPI($id, $order, $continuationToken)
];
}
if ($options['snippet']) {
$title = $isShort ? $gridVideoRenderer['headline']['simpleText'] : $gridVideoRenderer['title']['runs'][0]['text'];
$title = $gridVideoRenderer['title']['runs'][0]['text'];
$run = $gridVideoRenderer['ownerText']['runs'][0];
$browseEndpoint = $run['navigationEndpoint']['browseEndpoint'];
$channelId = $browseEndpoint['browseId'];
$views = call_user_func($isShort ? 'getIntValue' : 'getIntFromViewCount', $gridVideoRenderer['viewCountText']['simpleText'], 'view');
$views = getIntFromViewCount($gridVideoRenderer['viewCountText']['simpleText']);
$badges = $gridVideoRenderer['badges'];
$badges = !empty($badges) ? array_map(fn($badge) => $badge['metadataBadgeRenderer']['label'], $badges) : [];
$chapters = $gridVideoRenderer['expandableMetadata']['expandableMetadataRenderer']['expandedContent']['horizontalCardListRenderer']['cards'];
Expand All @@ -226,7 +245,7 @@ function getAPI($id, $order, $continuationToken)
'channelTitle' => $run['text'],
'channelHandle' => $channelHandle[0] === '@' ? $channelHandle : null,
'timestamp' => $gridVideoRenderer['publishedTimeText']['simpleText'],
'duration' => $isShort ? getIntValue(end(explode('- ', str_replace(' - play video', '', $gridVideoRenderer['accessibility']['accessibilityData']['label']))), 'second') : getIntFromDuration($gridVideoRenderer['lengthText']['simpleText']),
'duration' => getIntFromDuration($gridVideoRenderer['lengthText']['simpleText']),
'views' => $views,
'badges' => $badges,
'channelApproval' => $gridVideoRenderer['ownerBadges'][0]['metadataBadgeRenderer']['tooltip'],
Expand Down

0 comments on commit 19c5bba

Please sign in to comment.