support for linkedin videos

This commit is contained in:
Steve Berdy 2024-01-17 16:25:59 -05:00
parent dcb3cf3673
commit 26ea2b12c0
7 changed files with 57 additions and 3 deletions

View file

@ -16,6 +16,7 @@ this list is not final and keeps expanding over time. if support for a service y
| bilibili.com | ✅ | ✅ | ✅ | | |
| instagram posts & stories | ✅ | ✅ | ✅ | | |
| instagram reels | ✅ | ✅ | ✅ | | |
| linkedin videos | ✅ | ❌ | ❌ | ✅ | ✅ |
| pinterest | ✅ | ✅ | ✅ | | |
| reddit | ✅ | ✅ | ✅ | ❌ | ❌ |
| rutube | ✅ | ✅ | ✅ | ✅ | ✅ |

View file

@ -34,6 +34,7 @@
"express-rate-limit": "^6.3.0",
"ffmpeg-static": "^5.1.0",
"hls-parser": "^0.10.7",
"libxmljs": "^1.0.11",
"nanoid": "^4.0.2",
"node-cache": "^5.1.2",
"psl": "1.9.0",

View file

@ -24,6 +24,7 @@ import pinterest from "./services/pinterest.js";
import streamable from "./services/streamable.js";
import twitch from "./services/twitch.js";
import rutube from "./services/rutube.js";
import linkedin from "./services/linkedin.js";
export default async function(host, patternMatch, url, lang, obj) {
assert(url instanceof URL);
@ -158,6 +159,12 @@ export default async function(host, patternMatch, url, lang, obj) {
isAudioOnly: isAudioOnly
});
break;
case "linkedin":
r = await linkedin({
url,
id: patternMatch.id
});
break;
default:
return apiJSON(0, { t: errorUnsupported(lang) });
}

View file

@ -0,0 +1,27 @@
import libxmljs from "libxmljs";
export default async function(obj) {
const htmlContent = await fetch(obj.url.href).then((r) => {
return r.status === 200 ? r.text() : false
}).catch(() => { return false });
const htmlDoc = await libxmljs.parseHtmlAsync(htmlContent)
.then((d) => { return d });
const rawData = htmlDoc.find("//script[@type='application/ld+json']")[0];
const json = JSON.parse(rawData.text());
let fileMetadata = {
title: json.video.name,
author: json.author.name
}
return {
urls: json.video.contentUrl,
filenameAttributes: {
service: "linkedin",
id: obj.id,
title: fileMetadata.title,
author: fileMetadata.author,
extension: "mp4"
}
}
}

View file

@ -106,6 +106,12 @@
"tld": "ru",
"patterns": ["video/:id", "play/embed/:id"],
"enabled": true
},
"linkedin": {
"alias": "linkedin posts",
"subdomains": ["m"],
"patterns": ["posts/:id"],
"enabled": true
}
}
}

View file

@ -5,7 +5,10 @@ export const testers = {
"instagram": (patternMatch) =>
patternMatch.postId?.length <= 12
|| (patternMatch.username?.length <= 30 && patternMatch.storyId?.length <= 24),
"linkedin": (patternMatch) =>
patternMatch.id?.length >= 0,
"ok": (patternMatch) =>
patternMatch.id?.length <= 16,
@ -19,12 +22,12 @@ export const testers = {
patternMatch.id?.length === 32,
"soundcloud": (patternMatch) =>
(patternMatch.author?.length <= 255 && patternMatch.song?.length <= 255)
(patternMatch.author?.length <= 255 && patternMatch.song?.length <= 255)
|| patternMatch.shortLink?.length <= 32,
"streamable": (patternMatch) =>
patternMatch.id?.length === 6,
"tiktok": (patternMatch) =>
patternMatch.postId?.length <= 21 || patternMatch.id?.length <= 13,

View file

@ -1171,5 +1171,14 @@
"code": 200,
"status": "stream"
}
}],
"linkedin": [{
"name": "video post",
"url": "https://www.linkedin.com/posts/hadiyarajesh_kotlin-android-coroutines-activity-7144537175857037312-JKmR",
"params": {},
"expected": {
"code": 200,
"status": "stream"
}
}]
}