mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-07 06:56:04 +02:00
YouTube API
This commit is contained in:
@@ -147,6 +147,10 @@ namespace VRCX
|
|||||||
{
|
{
|
||||||
request.UserAgent = value;
|
request.UserAgent = value;
|
||||||
}
|
}
|
||||||
|
else if (string.Compare(key, "Referer", StringComparison.OrdinalIgnoreCase) == 0)
|
||||||
|
{
|
||||||
|
request.Referer = value;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
request.Headers.Add(key, value);
|
request.Headers.Add(key, value);
|
||||||
|
|||||||
+153
-24
@@ -4329,14 +4329,19 @@ speechSynthesis.getVoices();
|
|||||||
if (
|
if (
|
||||||
noty.type === 'Notification' ||
|
noty.type === 'Notification' ||
|
||||||
noty.type === 'LocationDestination'
|
noty.type === 'LocationDestination'
|
||||||
|
// skip unused entries
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// remove current user
|
if (noty.type === 'VideoPlay' && !noty.videoName) {
|
||||||
|
// skip videos without names
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
noty.type !== 'VideoPlay' &&
|
noty.type !== 'VideoPlay' &&
|
||||||
noty.displayName === API.currentUser.displayName
|
noty.displayName === API.currentUser.displayName
|
||||||
) {
|
) {
|
||||||
|
// remove current user
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
noty.isFriend = false;
|
noty.isFriend = false;
|
||||||
@@ -4864,11 +4869,7 @@ speechSynthesis.getVoices();
|
|||||||
this.speak(noty.data);
|
this.speak(noty.data);
|
||||||
break;
|
break;
|
||||||
case 'VideoPlay':
|
case 'VideoPlay':
|
||||||
var videoName = '';
|
this.speak(`Now playing: ${noty.videoName}`);
|
||||||
if (noty.videoName) {
|
|
||||||
videoName = `: ${noty.videoName}`;
|
|
||||||
}
|
|
||||||
this.speak(`Now playing video${videoName}`);
|
|
||||||
break;
|
break;
|
||||||
case 'BlockedOnPlayerJoined':
|
case 'BlockedOnPlayerJoined':
|
||||||
this.speak(`Blocked user ${noty.displayName} has joined`);
|
this.speak(`Blocked user ${noty.displayName} has joined`);
|
||||||
@@ -5051,13 +5052,9 @@ speechSynthesis.getVoices();
|
|||||||
AppApi.XSNotification('VRCX', noty.data, timeout, image);
|
AppApi.XSNotification('VRCX', noty.data, timeout, image);
|
||||||
break;
|
break;
|
||||||
case 'VideoPlay':
|
case 'VideoPlay':
|
||||||
var videoName = noty.videoUrl;
|
|
||||||
if (noty.videoName) {
|
|
||||||
videoName = noty.videoName;
|
|
||||||
}
|
|
||||||
AppApi.XSNotification(
|
AppApi.XSNotification(
|
||||||
'VRCX',
|
'VRCX',
|
||||||
`Now playing: ${videoName}`,
|
`Now playing: ${noty.videoName}`,
|
||||||
timeout,
|
timeout,
|
||||||
image
|
image
|
||||||
);
|
);
|
||||||
@@ -5238,11 +5235,11 @@ speechSynthesis.getVoices();
|
|||||||
AppApi.DesktopNotification('Event', noty.data, image);
|
AppApi.DesktopNotification('Event', noty.data, image);
|
||||||
break;
|
break;
|
||||||
case 'VideoPlay':
|
case 'VideoPlay':
|
||||||
var videoName = noty.videoUrl;
|
AppApi.DesktopNotification(
|
||||||
if (noty.videoName) {
|
'Now playing',
|
||||||
videoName = noty.videoName;
|
noty.videoName,
|
||||||
}
|
image
|
||||||
AppApi.DesktopNotification('Now playing', videoName, image);
|
);
|
||||||
break;
|
break;
|
||||||
case 'BlockedOnPlayerJoined':
|
case 'BlockedOnPlayerJoined':
|
||||||
AppApi.DesktopNotification(
|
AppApi.DesktopNotification(
|
||||||
@@ -7382,14 +7379,8 @@ speechSynthesis.getVoices();
|
|||||||
database.addGamelogPortalSpawnToDatabase(entry);
|
database.addGamelogPortalSpawnToDatabase(entry);
|
||||||
break;
|
break;
|
||||||
case 'video-play':
|
case 'video-play':
|
||||||
var entry = {
|
this.addGameLogVideo(gameLog, location, userId, pushToTable);
|
||||||
created_at: gameLog.dt,
|
return;
|
||||||
type: 'VideoPlay',
|
|
||||||
data: gameLog.videoUrl,
|
|
||||||
displayName: gameLog.displayName
|
|
||||||
};
|
|
||||||
database.addGamelogVideoPlayToDatabase(entry);
|
|
||||||
break;
|
|
||||||
case 'notification':
|
case 'notification':
|
||||||
var entry = {
|
var entry = {
|
||||||
created_at: gameLog.dt,
|
created_at: gameLog.dt,
|
||||||
@@ -7412,6 +7403,90 @@ speechSynthesis.getVoices();
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$app.methods.addGameLogVideo = async function (
|
||||||
|
gameLog,
|
||||||
|
location,
|
||||||
|
userId,
|
||||||
|
pushToTable
|
||||||
|
) {
|
||||||
|
var videoUrl = gameLog.videoUrl;
|
||||||
|
var youtubeVideoId = '';
|
||||||
|
var videoId = '';
|
||||||
|
var videoName = '';
|
||||||
|
var videoLength = '';
|
||||||
|
var displayName = '';
|
||||||
|
if (typeof gameLog.displayName !== 'undefined') {
|
||||||
|
displayName = gameLog.displayName;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var url = new URL(videoUrl);
|
||||||
|
var id1 = url.pathname;
|
||||||
|
var id2 = url.searchParams.get('v');
|
||||||
|
if (id1 && id1.length === 12) {
|
||||||
|
youtubeVideoId = id2.substring(1, 12);
|
||||||
|
}
|
||||||
|
if (id2 && id2.length === 11) {
|
||||||
|
youtubeVideoId = id2;
|
||||||
|
}
|
||||||
|
if (this.youTubeApi && youtubeVideoId) {
|
||||||
|
var data = await this.lookupYouTubeVideo(youtubeVideoId);
|
||||||
|
if (
|
||||||
|
data ||
|
||||||
|
(data.status === 200 && data.pageInfo.totalResults !== 0)
|
||||||
|
) {
|
||||||
|
videoId = 'YouTube';
|
||||||
|
videoName = data.items[0].snippet.title;
|
||||||
|
videoLength = this.convertYoutubeTime(
|
||||||
|
data.items[0].contentDetails.duration
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.error(`YouTube video lookup failed status: ${status}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
console.error(`Invalid URL: ${url}`);
|
||||||
|
}
|
||||||
|
var entry = {
|
||||||
|
created_at: gameLog.dt,
|
||||||
|
type: 'VideoPlay',
|
||||||
|
videoUrl,
|
||||||
|
videoId,
|
||||||
|
videoName,
|
||||||
|
videoLength,
|
||||||
|
location,
|
||||||
|
displayName,
|
||||||
|
userId
|
||||||
|
};
|
||||||
|
if (pushToTable) {
|
||||||
|
this.queueGameLogNoty(entry);
|
||||||
|
this.gameLogTable.data.push(entry);
|
||||||
|
}
|
||||||
|
database.addGamelogVideoPlayToDatabase(entry);
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.methods.lookupYouTubeVideo = async function (videoId) {
|
||||||
|
var data = {};
|
||||||
|
var apiKey = 'AIzaSyA-iUQCpWf5afEL3NanEOSxbzziPMU3bxY';
|
||||||
|
if (this.youTubeApiKey) {
|
||||||
|
apiKey = this.youTubeApiKey;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var response = await webApiService.execute({
|
||||||
|
url: `https://www.googleapis.com/youtube/v3/videos?id=${videoId}&part=snippet,contentDetails&key=${apiKey}`,
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'User-Agent': appVersion,
|
||||||
|
Referer: 'https://vrcx.pypy.moe'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
data = JSON.parse(response.data);
|
||||||
|
data.status = response.status;
|
||||||
|
} catch {
|
||||||
|
console.error(`YouTube video lookup failed for ${videoId}`);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
$app.methods.sweepGameLog = function () {
|
$app.methods.sweepGameLog = function () {
|
||||||
var {data} = this.gameLogTable;
|
var {data} = this.gameLogTable;
|
||||||
// 로그는 7일까지만 남김
|
// 로그는 7일까지만 남김
|
||||||
@@ -9092,6 +9167,9 @@ speechSynthesis.getVoices();
|
|||||||
this.updateVRConfigVars();
|
this.updateVRConfigVars();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$app.data.youTubeApi = configRepository.getBool('VRCX_youtubeAPI');
|
||||||
|
$app.data.youTubeApiKey = configRepository.getString('VRCX_youtubeAPIKey');
|
||||||
|
|
||||||
var downloadProgressStateChange = function () {
|
var downloadProgressStateChange = function () {
|
||||||
this.updateVRConfigVars();
|
this.updateVRConfigVars();
|
||||||
};
|
};
|
||||||
@@ -13872,6 +13950,57 @@ speechSynthesis.getVoices();
|
|||||||
this.VRChatConfigFile.screenshot_res_width = res.width;
|
this.VRChatConfigFile.screenshot_res_width = res.width;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// YouTube API
|
||||||
|
|
||||||
|
$app.data.youTubeApiKey = '';
|
||||||
|
|
||||||
|
$app.data.youTubeApiDialog = {
|
||||||
|
visible: false
|
||||||
|
};
|
||||||
|
|
||||||
|
API.$on('LOGOUT', function () {
|
||||||
|
$app.youTubeApiDialog.visible = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$app.methods.testYouTubeApiKey = async function () {
|
||||||
|
if (!this.youTubeApiKey) {
|
||||||
|
this.$message({
|
||||||
|
message: 'YouTube API key removed',
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
this.youTubeApiDialog.visible = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var data = await this.lookupYouTubeVideo('dQw4w9WgXcQ');
|
||||||
|
if (!data || data.status !== 200) {
|
||||||
|
this.youTubeApiKey = '';
|
||||||
|
this.$message({
|
||||||
|
message: `Invalid YouTube API key, error code: ${data.status}`,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
configRepository.setString(
|
||||||
|
'VRCX_youtubeAPIKey',
|
||||||
|
this.youTubeApiKey
|
||||||
|
);
|
||||||
|
this.$message({
|
||||||
|
message: 'YouTube API key valid!',
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.youTubeApiDialog.visible = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.methods.changeYouTubeApi = function () {
|
||||||
|
configRepository.setBool('VRCX_youtubeAPI', this.youTubeApi);
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.methods.showYouTubeApiDialog = function () {
|
||||||
|
this.$nextTick(() => adjustDialogZ(this.$refs.youTubeApiDialog.$el));
|
||||||
|
var D = this.youTubeApiDialog;
|
||||||
|
D.visible = true;
|
||||||
|
};
|
||||||
|
|
||||||
// Asset Bundle Cacher
|
// Asset Bundle Cacher
|
||||||
|
|
||||||
$app.methods.updateVRChatWorldCache = function () {
|
$app.methods.updateVRChatWorldCache = function () {
|
||||||
|
|||||||
+18
-2
@@ -904,8 +904,7 @@ html
|
|||||||
div.options-container-item
|
div.options-container-item
|
||||||
el-switch(v-model="worldAutoCacheGPSFilter" @change="saveOpenVROption" inactive-text="VIP" active-text="Everyone" :disabled="worldAutoCacheGPS === 'Never'")
|
el-switch(v-model="worldAutoCacheGPSFilter" @change="saveOpenVROption" inactive-text="VIP" active-text="Everyone" :disabled="worldAutoCacheGPS === 'Never'")
|
||||||
div.options-container-item
|
div.options-container-item
|
||||||
el-button-group
|
el-button(size="small" icon="el-icon-download" @click="showDownloadDialog") Download History
|
||||||
el-button(size="small" icon="el-icon-download" @click="showDownloadDialog") Download History
|
|
||||||
br
|
br
|
||||||
span.sub-header Automatically Manage Cache When Closing VRChat
|
span.sub-header Automatically Manage Cache When Closing VRChat
|
||||||
div.options-container-item
|
div.options-container-item
|
||||||
@@ -929,6 +928,13 @@ html
|
|||||||
el-button-group
|
el-button-group
|
||||||
el-button(size="small" icon="el-icon-s-operation" @click="showLaunchOptions()") Launch Options
|
el-button(size="small" icon="el-icon-s-operation" @click="showLaunchOptions()") Launch Options
|
||||||
el-button(size="small" icon="el-icon-s-operation" @click="showVRChatConfig()") VRChat config.json
|
el-button(size="small" icon="el-icon-s-operation" @click="showVRChatConfig()") VRChat config.json
|
||||||
|
div.options-container
|
||||||
|
span.header YouTube API
|
||||||
|
div.options-container-item
|
||||||
|
span.name Enabled
|
||||||
|
el-switch(v-model="youTubeApi" @change="changeYouTubeApi")
|
||||||
|
div.options-container-item
|
||||||
|
el-button(size="small" icon="el-icon-caret-right" @click="showYouTubeApiDialog") YouTube API Key
|
||||||
div.options-container(style="margin-top:45px;border-top:1px solid #eee;padding-top:30px")
|
div.options-container(style="margin-top:45px;border-top:1px solid #eee;padding-top:30px")
|
||||||
span.header Legal Notice
|
span.header Legal Notice
|
||||||
div.options-container-item
|
div.options-container-item
|
||||||
@@ -1732,6 +1738,16 @@ html
|
|||||||
el-button(size="small" @click="VRChatConfigDialog.visible = false") Cancel
|
el-button(size="small" @click="VRChatConfigDialog.visible = false") Cancel
|
||||||
el-button(type="primary" size="small" :disabled="VRChatConfigDialog.loading" @click="saveVRChatConfigFile") Save
|
el-button(type="primary" size="small" :disabled="VRChatConfigDialog.loading" @click="saveVRChatConfigFile") Save
|
||||||
|
|
||||||
|
//- dialog: YouTube Api Dialog
|
||||||
|
el-dialog.x-dialog(ref="youTubeApiDialog" :visible.sync="youTubeApiDialog.visible" title="YouTube API" width="400px")
|
||||||
|
div(style='font-size:12px;')
|
||||||
|
| Enter your YouTube API Key #[br]
|
||||||
|
el-input(type="textarea" v-model="youTubeApiKey" placeholder="YouTube API Key" maxlength="39" show-word-limit style="dispaly:block;margin-top:10px")
|
||||||
|
template(#footer)
|
||||||
|
div(style="display:flex")
|
||||||
|
el-button(size="small" @click="openExternalLink('https://rapidapi.com/blog/how-to-get-youtube-api-key/')") Guide
|
||||||
|
el-button(type="primary" size="small" @click="testYouTubeApiKey" style="margin-left:auto") Save
|
||||||
|
|
||||||
//- dialog: Cache Download
|
//- dialog: Cache Download
|
||||||
el-dialog.x-dialog(ref="downloadDialog" :visible.sync="downloadDialog.visible" title="Download History" width="770px")
|
el-dialog.x-dialog(ref="downloadDialog" :visible.sync="downloadDialog.visible" title="Download History" width="770px")
|
||||||
div(v-if="downloadInProgress && downloadCurrent.ref")
|
div(v-if="downloadInProgress && downloadCurrent.ref")
|
||||||
|
|||||||
+1
-5
@@ -400,11 +400,7 @@ speechSynthesis.getVoices();
|
|||||||
text = noty.data;
|
text = noty.data;
|
||||||
break;
|
break;
|
||||||
case 'VideoPlay':
|
case 'VideoPlay':
|
||||||
var videoName = noty.videoUrl;
|
text = `<strong>Now playing:</strong> ${noty.videoName}`;
|
||||||
if (noty.videoName) {
|
|
||||||
videoName = noty.videoName;
|
|
||||||
}
|
|
||||||
text = `<strong>Now playing:</strong> ${videoName}`;
|
|
||||||
break;
|
break;
|
||||||
case 'BlockedOnPlayerJoined':
|
case 'BlockedOnPlayerJoined':
|
||||||
text = `Blocked user <strong>${noty.displayName}</strong> has joined`;
|
text = `Blocked user <strong>${noty.displayName}</strong> has joined`;
|
||||||
|
|||||||
Reference in New Issue
Block a user