Skip to content

Commit 4f6d934

Browse files
committed
feat: Ajouter le support partiel de France tv.
1 parent 242615f commit 4f6d934

File tree

4 files changed

+130
-0
lines changed

4 files changed

+130
-0
lines changed

src/core/scraper/francetv.js

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* @module
3+
*/
4+
/* eslint-disable require-await */
5+
6+
import { matchPattern } from "../../tools/matchpattern.js";
7+
8+
/**
9+
* L'expression rationnelle pour extraire l'identifiant de la vidéo.
10+
*
11+
* @constant {RegExp}
12+
*/
13+
const UUID_REGEXP = /"videoId":"([0-9a-f-]+)"/u;
14+
15+
/**
16+
* L'URL de l'API de France tv.
17+
*
18+
* @constant {string}
19+
*/
20+
const API_URL = "https://player.webservices.francetelevisions.fr/v1/videos/";
21+
22+
/**
23+
* Extrait les informations nécessaire pour lire une vidéo sur Kodi.
24+
*
25+
* @param {URL} _url L'URL d'une page de France tv.
26+
* @param {HTMLDocument} doc Le contenu HTML de la page.
27+
* @returns {Promise.<?string>} Une promesse contenant le lien du
28+
* <em>fichier</em> ou <code>null</code>.
29+
*/
30+
const action = async function (_url, doc) {
31+
for (const script of doc.querySelectorAll("script:not([src])")) {
32+
const result = UUID_REGEXP.exec(script.text);
33+
if (null === result) {
34+
continue;
35+
}
36+
37+
const url = API_URL + result[1] + "?device_type=desktop" +
38+
"&browser=firefox";
39+
const response = await fetch(url);
40+
const json = await response.json();
41+
return json.streamroot.content_id;
42+
}
43+
return null;
44+
};
45+
export const extract = matchPattern(action, "*://www.france.tv/*");

src/core/scrapers.js

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import * as devtube from "./scraper/devtube.js";
1414
import * as dumpert from "./scraper/dumpert.js";
1515
import * as dailymotion from "./scraper/dailymotion.js";
1616
import * as flickr from "./scraper/flickr.js";
17+
import * as francetv from "./scraper/francetv.js";
1718
import * as full30 from "./scraper/full30.js";
1819
import * as gamekult from "./scraper/gamekult.js";
1920
// eslint-disable-next-line import/no-cycle
@@ -60,6 +61,7 @@ const SCRAPERS = [
6061
dumpert,
6162
dailymotion,
6263
flickr,
64+
francetv,
6365
full30,
6466
gamekult,
6567
kcaastreaming,

test/integration/scraper/francetv.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import assert from "assert";
2+
import { extract } from "../../../src/core/scrapers.js";
3+
4+
describe("Scraper: France tv", function () {
5+
it("should return URL when it's not a video", async function () {
6+
const url = "https://www.france.tv/spectacles-et-culture/";
7+
const options = { "depth": 0, "incognito": false };
8+
const expected = url;
9+
10+
const file = await extract(new URL(url), options);
11+
assert.strictEqual(file, expected);
12+
});
13+
14+
it("should return video URL", async function () {
15+
const url = "https://www.france.tv/france-2/journal-20h00" +
16+
"/1133923-journal-20h00.html";
17+
const options = { "depth": 0, "incognito": false };
18+
const expected = "https://replayftv-vh.akamaihd.net/i" +
19+
"/streaming-adaptatif/2020/S01/J3/220156965-5e0cf4f0c0f35-" +
20+
",standard1,standard2,standard3,standard4,standard5,.mp4.csmil" +
21+
"/master.m3u8" +
22+
"?caption=%2F2020%2F01%2F01%2F220156965" +
23+
"-5e0cf4f0c0f35-1577907730.m3u8%3Afra%3AFrancais" +
24+
"&audiotrack=0%3Afra%3AFrancais";
25+
26+
const file = await extract(new URL(url), options);
27+
assert.strictEqual(file, expected);
28+
});
29+
});

test/unit/core/scraper/francetv.js

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import assert from "assert";
2+
import { extract } from "../../../../src/core/scraper/francetv.js";
3+
4+
describe("core/scraper/francetv.js", function () {
5+
describe("extract()", function () {
6+
it("should return null when it's a unsupported URL", async function () {
7+
const url = "https://www.francetelevisions.fr/et-vous/programme-tv";
8+
const expected = null;
9+
10+
const file = await extract(new URL(url));
11+
assert.strictEqual(file, expected);
12+
});
13+
14+
it("should return null when it's not a video", async function () {
15+
const url = "https://www.france.tv/foo";
16+
const doc = new DOMParser().parseFromString(`
17+
<html>
18+
<body>
19+
<script></script>
20+
</body>
21+
</html>`, "text/html");
22+
const expected = null;
23+
24+
const file = await extract(new URL(url), doc);
25+
assert.strictEqual(file, expected);
26+
});
27+
28+
it("should return video URL", async function () {
29+
const url = "https://www.france.tv/foo";
30+
const doc = new DOMParser().parseFromString(`
31+
<html>
32+
<body>
33+
<script>
34+
var FTVPlayerVideos = [{
35+
"contentId":1143295,
36+
"videoId":"4744326d-6440-48f5-a0ed-68a11113a0b6"
37+
}];
38+
</script>
39+
</body>
40+
</html>`, "text/html");
41+
const expected = "https://replayftv-vh.akamaihd.net/i" +
42+
"/streaming-adaptatif_france-dom-tom/2020/S03/J2" +
43+
"/221005052-5e1ed67f8e9fb-" +
44+
",standard1,standard2,standard3,standard4,.mp4.csmil" +
45+
"/master.m3u8" +
46+
"?caption=%2F2020%2F01%2F15%2F221005052-5e1ed67f8e9fb" +
47+
"-1579080386.m3u8%3Afra%3AFrancais" +
48+
"&audiotrack=0%3Afra%3AFrancais";
49+
50+
const file = await extract(new URL(url), doc);
51+
assert.strictEqual(file, expected);
52+
});
53+
});
54+
});

0 commit comments

Comments
 (0)