Skip to content

Commit bd8f0c9

Browse files
Add support for upcoming livestream trailers
1 parent c213904 commit bd8f0c9

File tree

4 files changed

+80
-34
lines changed

4 files changed

+80
-34
lines changed

src/renderer/helpers/api/local.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,15 +255,19 @@ export async function getLocalVideoInfo(id) {
255255
return info
256256
}
257257

258-
if (hasTrailer) {
259-
/** @type {import('youtubei.js').YTNodes.PlayerLegacyDesktopYpcTrailer} */
258+
if (hasTrailer && info.playability_status.status !== 'OK') {
259+
/** @type {import('youtubei.js').YTNodes.PlayerLegacyDesktopYpcTrailer | import('youtubei.js').YTNodes.YpcTrailer} */
260260
const trailerScreen = info.playability_status.error_screen
261261

262262
const trailerInfo = new Mixins.MediaInfo([{ data: trailerScreen.trailer.player_response }])
263263

264+
// don't override the timestamp of when the video will premiere for upcoming videos
265+
if (info.playability_status.status !== 'LIVE_STREAM_OFFLINE') {
266+
info.basic_info.start_timestamp = trailerInfo.basic_info.start_timestamp
267+
}
268+
264269
info.playability_status = trailerInfo.playability_status
265270
info.streaming_data = trailerInfo.streaming_data
266-
info.basic_info.start_timestamp = trailerInfo.basic_info.start_timestamp
267271
info.basic_info.duration = trailerInfo.basic_info.duration
268272
info.captions = trailerInfo.captions
269273
info.storyboards = trailerInfo.storyboards

src/renderer/views/Watch/Watch.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ export default defineComponent({
129129
infoAreaSticky: true,
130130
blockVideoAutoplay: false,
131131
autoplayInterruptionTimeout: null,
132+
playabilityStatus: '',
132133

133134
onMountedRun: false,
134135

@@ -542,6 +543,7 @@ export default defineComponent({
542543
this.videoChapters = chapters
543544

544545
const playabilityStatus = result.playability_status
546+
this.playabilityStatus = playabilityStatus.status
545547

546548
// The apostrophe is intentionally that one (char code 8217), because that is the one YouTube uses
547549
const BOT_MESSAGE = 'Sign in to confirm you’re not a bot'
@@ -683,7 +685,9 @@ export default defineComponent({
683685
this.upcomingTimeLeft = null
684686
this.premiereDate = undefined
685687
}
686-
} else {
688+
}
689+
690+
if (!this.isUpcoming || (this.isUpcoming && this.playabilityStatus === 'OK')) {
687691
this.videoLengthSeconds = result.basic_info.duration
688692
if (result.streaming_data) {
689693
this.streamingDataExpiryDate = result.streaming_data.expires

src/renderer/views/Watch/Watch.scss

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,41 @@
2121
}
2222
}
2323

24+
.premiereDate {
25+
align-items: center;
26+
background-color: rgb(0 0 0 / 80%);
27+
border-radius: 5px;
28+
inset-block-end: 12px;
29+
color: #fff;
30+
display: flex;
31+
block-size: 60px;
32+
inset-inline-start: 12px;
33+
padding-block: 0;
34+
padding-inline: 12px;
35+
36+
.premiereIcon {
37+
float: inline-start;
38+
font-size: 25px;
39+
margin-block: 0;
40+
margin-inline: 12px;
41+
}
42+
43+
.premiereText {
44+
margin-block: 0;
45+
margin-inline: 12px;
46+
min-inline-size: 200px;
47+
48+
.premiereTextTimestamp {
49+
font-size: 0.85em;
50+
font-weight: bold;
51+
}
52+
}
53+
}
54+
55+
.trailer.premiereDate {
56+
margin-block-start: 8px;
57+
}
58+
2459
.videoLayout {
2560
@include dual-column-template;
2661

@@ -52,35 +87,7 @@
5287
}
5388

5489
.premiereDate {
55-
align-items: center;
56-
background-color: rgb(0 0 0 / 80%);
57-
border-radius: 5px;
58-
inset-block-end: 12px;
59-
color: #fff;
60-
display: flex;
61-
block-size: 60px;
62-
inset-inline-start: 12px;
63-
padding-block: 0;
64-
padding-inline: 12px;
6590
position: absolute;
66-
67-
.premiereIcon {
68-
float: inline-start;
69-
font-size: 25px;
70-
margin-block: 0;
71-
margin-inline: 12px;
72-
}
73-
74-
.premiereText {
75-
margin-block: 0;
76-
margin-inline: 12px;
77-
min-inline-size: 200px;
78-
79-
.premiereTextTimestamp {
80-
font-size: 0.85em;
81-
font-weight: bold;
82-
}
83-
}
8491
}
8592

8693
.errorContainer {

src/renderer/views/Watch/Watch.vue

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
>
1818
<div class="videoAreaMargin">
1919
<ft-shaka-video-player
20-
v-if="!isLoading && !isUpcoming && !errorMessage"
20+
v-if="!isLoading && (!isUpcoming || playabilityStatus === 'OK') && !errorMessage"
2121
ref="player"
2222
:manifest-src="manifestSrc"
2323
:manifest-mime-type="manifestMimeType"
@@ -50,7 +50,38 @@
5050
@playback-rate-updated="updatePlaybackRate"
5151
/>
5252
<div
53-
v-if="!isLoading && (isUpcoming || errorMessage)"
53+
v-if="!isLoading && isUpcoming && playabilityStatus === 'OK'"
54+
class="trailer premiereDate"
55+
>
56+
<font-awesome-icon
57+
:icon="['fas', 'satellite-dish']"
58+
class="premiereIcon"
59+
/>
60+
<p
61+
v-if="upcomingTimestamp !== null"
62+
class="premiereText"
63+
>
64+
<span
65+
class="premiereTextTimeLeft"
66+
>
67+
{{ $t("Video.Premieres") }} {{ upcomingTimeLeft }}
68+
</span>
69+
<br>
70+
<span
71+
class="premiereTextTimestamp"
72+
>
73+
{{ upcomingTimestamp }}
74+
</span>
75+
</p>
76+
<p
77+
v-else
78+
class="premiereText"
79+
>
80+
{{ $t("Video.Starting soon, please refresh the page to check again") }}
81+
</p>
82+
</div>
83+
<div
84+
v-else-if="!isLoading && (isUpcoming || errorMessage)"
5485
class="videoPlayer"
5586
>
5687
<img

0 commit comments

Comments
 (0)