再次更新。在我看来,到目前为止,我已经确定了 6 种情况可以满足(我编造了这些名称):
普通网址
https://www.youtube.com/watch?v=12345678901
分享网址
https://youtu.be/12345678901
分享网址与开始时间
https://youtu.be/12345678901?t=6
手机浏览器网址
https://m.youtube.com/watch?v=12345678901&list=RD12345678901&start_radio=1
长网址
https://www.youtube.com/watch?v=12345678901&list=RD12345678901&start_radio=1&rv=smKgVuS
带有开始时间的长网址
https://www.youtube.com/watch?v=12345678901&list=RD12345678901&start_radio=1&rv=12345678901&t=38
我最初根据 Jitendras 的答案提供了一个扩展的答案,因为这似乎有一些差距。例如,如果您在末尾添加字符,则使用较短的共享 URL(例如 https://youtu.be/abcdefgh_ij),Jitendras 没有捕捉到它。此外,如果用户在已经存在错误的情况下删除了文本字段中的值,则不会将其删除。
但是,我假设原始发帖人实际上想在 iframe 嵌入中使用 URL,而这里的答案都不适用于此。嵌入的url格式不同,需要处理。
以下是我正在执行的操作,以获取用户输入、对其进行验证、将其替换为格式正确的可嵌入 url,然后将其分配给 iframe 以在 UI 上显示。
可能对某人有好处....
function validateVideoLink() {
var UserInputField = document.getElementById("UserInputField");
var InputFieldText = UserInputField.value;
var FieldValidationPara = document.getElementById("FieldValidationPara");
if ((InputFieldText.includes("watch?v=") || InputFieldText.includes("https://m.youtube") || InputFieldText.includes("watch?app=desktop&v=")) && !InputFieldText == "") {
var endOfString = InputFieldText.split(/=(.*)/)[1];
var stringLength = endOfString.length;
var p = /^(?:https?:\/\/)?(?:m\.|www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
if (!InputFieldText.match(p)) {
FieldValidationPara.style.display = 'block';
document.getElementById('CardDynamicVideo').src = '';
} else {
FieldValidationPara.style.display = 'none';
var processedUrl = processVideoUrl(InputFieldText, true);
document.getElementById('CardDynamicVideo').src = processedUrl;
$("#UserInputField").val(processedUrl);
}
if (stringLength > 11) {
FieldValidationPara.style.display = 'block';
document.getElementById('CardDynamicVideo').src = '';
}
} else if (InputFieldText.includes("embed") && !InputFieldText== "") {
//This else if block is needed in case the user adds extra characters on the end of the correctly processed embed url.
var endOfString = InputFieldText.split('/')[4];
var stringLength = endOfString.length;
console.log('StringLength: ' + stringLength);
var p = /^(?:https?:\/\/)?(?:m\.|www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
if (!InputFieldText.match(p)) {
FieldValidationPara.style.display = 'block';
document.getElementById('CardDynamicVideo').src = '';
} else {
FieldValidationPara.style.display = 'none';
var processedUrl = processVideoUrl(InputFieldText, true);
document.getElementById('CardDynamicVideo').src = processedUrl;
$("#UserInputField").val(processedUrl);
}
if (stringLength > 11) {
FieldValidationPara.style.display = 'block';
document.getElementById('CardDynamicVideo').src = '';
} else if (InputFieldText.includes("tu.be") && !InputFieldText == "") {
var endOfString = InputFieldText.split('/')[3];
var stringLength = endOfString.length;
var p = /^(?:https?:\/\/)?(?:m\.|www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
if (!InputFieldText.match(p)) {
FieldValidationPara.style.display = 'block';
document.getElementById('CardDynamicVideo').src = '';
} else {
FieldValidationPara.style.display = 'none';
document.getElementById('CardDynamicVideo').src = VideoLinkText;
var processedUrl = processVideoUrl(InputFieldText, false);
document.getElementById('CardDynamicVideo').src = processedUrl;
$("#UserInputField").val(processedUrl);
}
if (stringLength > 11) {
FieldValidationPara.style.display = 'block';
document.getElementById('CardDynamicVideo').src = '';
}
} else {
var p = /^(?:https?:\/\/)?(?:m\.|www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
if (!InputFieldText.match(p) && !InputFieldText == "") {
FieldValidationPara.style.display = 'block';
document.getElementById('CardDynamicVideo').src = '';
} else {
FieldValidationPara.style.display = 'none';
document.getElementById('CardDynamicVideo').src = InputFieldText;
}
}
}
function processVideoUrl(rawUrl, fullUrl) {
if (fullUrl) {
var processed = rawUrl.replace('watch?v=', 'embed/')
if (processed.includes("https://m.youtube")) {
processed = rawUrl.replace('m.youtube', 'www.youtube');
if (processed.includes("&list=")) {
processed = processed.split('&list=')[0];
return processed;
console.log('Processed 1: ' + processed);
}
} else if (processed.includes("watch?app=desktop&v=")) {
processed = rawUrl.replace('watch?app=desktop&v=', 'embed/');
if (processed.includes("&list=")) {
processed = processed.split('&list=')[0];
return processed;
console.log('Processed 1: ' + processed);
}
} else if (processed.includes("&list=")) {
processed = processed.split('&list=')[0];
return processed;
console.log('Processed 1: ' + processed);
}
console.log('Processed 2: ' + processed);
return processed;
} else {
var processed = rawUrl.replace('https://youtu.be/', 'https://www.youtube.com/embed/')
if (processed.includes("?t=")) {
processed = processed.split('?t=')[0];
return processed;
}
console.log('Processed 3: ' + processed);
return processed;
}
}
以及对应的HTML:
<iframe class="embed-responsive-item" src="" id="CardDynamicVideo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<div class="row">
<input asp-for="YouTubeLink" class="form-control" id="UserInputField" onkeypress="validateVideoLink()" onkeyup="validateVideoLink()">
</div>
<div class="row">
<p class="font-danger hide" id="FieldValidationPara">That is not a valid YouTube Link</p>
</div>
注意 1:仍有一些边缘情况需要解决。例如,如果您输入一些奇怪的 watch?v= 或 tu.be 组合,它还不会处理它们。但我认为以上内容作为一个起点已经足够扎实了。
注意 2:请注意您用于测试的视频。 YouTube 不允许嵌入带有受版权保护的背景音乐的视频,它们将显示为不可用。