|
2 | 2 | // @name XHS-Downloader |
3 | 3 | // @namespace xhs_downloader |
4 | 4 | // @homepage https://github.com/JoeanAmier/XHS-Downloader |
5 | | -// @version 2.4.2 |
| 5 | +// @version 2.4.3 |
6 | 6 | // @tag 小红书 |
7 | 7 | // @tag RedNote |
8 | 8 | // @tag XiaoHongShu |
@@ -130,6 +130,13 @@ KS-Downloader(快手、KuaiShou):https://github.com/JoeanAmier/KS-Download |
130 | 130 | scriptServerSwitchDesc: '启用后,可以把作品下载任务推送至服务器', |
131 | 131 | imageDownloadFormatLabel: '图片下载格式', |
132 | 132 | imageDownloadFormatDesc: '图文作品文件下载格式', |
| 133 | + videoPreferenceLabel: '视频下载偏好', |
| 134 | + videoPreferenceDesc: '视频作品文件下载策略', |
| 135 | + videoPreferenceOptions: { |
| 136 | + resolution: '分辨率优先', |
| 137 | + bitrate: '码率优先', |
| 138 | + size: '文件大小优先', |
| 139 | + }, |
133 | 140 | fileNameFormatLabel: '作品文件名称格式', |
134 | 141 | fileNameFormatDesc: '点击可选字段添加,拖拽已选字段调整顺序', |
135 | 142 | fileNameSelectedLabel: '已选字段', |
@@ -286,6 +293,13 @@ Discord Community: https://discord.com/invite/ZYtmgKud9Y |
286 | 293 | scriptServerSwitchDesc: 'When enabled, download tasks can be pushed to the server', |
287 | 294 | imageDownloadFormatLabel: 'Image Download Format', |
288 | 295 | imageDownloadFormatDesc: 'Preferred file format for downloading images', |
| 296 | + videoPreferenceLabel: 'Video download preferences', |
| 297 | + videoPreferenceDesc: 'Video Notes File Download Strategy', |
| 298 | + videoPreferenceOptions: { |
| 299 | + resolution: 'Resolution priority', |
| 300 | + bitrate: 'Bitrate priority', |
| 301 | + size: 'File size priority', |
| 302 | + }, |
289 | 303 | fileNameFormatLabel: 'Note File Name Format', |
290 | 304 | fileNameFormatDesc: 'Click available fields to add them. Drag selected fields to reorder.', |
291 | 305 | fileNameSelectedLabel: 'Selected Fields', |
@@ -420,6 +434,7 @@ Discord Community: https://discord.com/invite/ZYtmgKud9Y |
420 | 434 | linkCheckboxSwitch: GM_getValue("linkCheckboxSwitch", true), |
421 | 435 | imageCheckboxSwitch: GM_getValue("imageCheckboxSwitch", true), |
422 | 436 | imageDownloadFormat: GM_getValue("imageDownloadFormat", "jpeg"), |
| 437 | + videoPreference: GM_getValue("videoPreference", "resolution"), |
423 | 438 | scriptServerURL: GM_getValue("scriptServerURL", defaultsWebSocketURL), |
424 | 439 | scriptServerSwitch: GM_getValue("scriptServerSwitch", false), |
425 | 440 | fileNameFormatKeys: storedFileNameFormatKeys, |
@@ -560,6 +575,11 @@ Discord Community: https://discord.com/invite/ZYtmgKud9Y |
560 | 575 | GM_setValue("imageDownloadFormat", config.imageDownloadFormat); |
561 | 576 | } |
562 | 577 |
|
| 578 | + const updateVideoPreference = (value) => { |
| 579 | + config.videoPreference = value; |
| 580 | + GM_setValue("videoPreference", value); |
| 581 | + }; |
| 582 | + |
563 | 583 | // 更新文件名格式配置。 |
564 | 584 | const updateFileNameFormat = (value) => { |
565 | 585 | config.fileNameFormatKeys = parseFileNameFormat(value); |
@@ -592,13 +612,21 @@ Discord Community: https://discord.com/invite/ZYtmgKud9Y |
592 | 612 | } |
593 | 613 | } |
594 | 614 |
|
| 615 | + const preferenceKey = { |
| 616 | + resolution: "height", |
| 617 | + bitrate: "videoBitrate", |
| 618 | + size: "size", |
| 619 | + }; |
| 620 | + |
595 | 621 | const generateVideoUrl = note => { |
596 | 622 | try { |
597 | 623 | const key = note.video?.consumer?.originVideoKey; |
598 | 624 | if (key) return [`https://sns-video-bd.xhscdn.com/${key}`]; |
599 | 625 | const allStreams = Object.values(note.video.media.stream).flat(); |
600 | | - sortArray(allStreams, "height"); |
601 | | - return [allStreams[0].backupUrls[0] || allStreams[0].masterUrl]; |
| 626 | + if (allStreams.length === 0) return []; |
| 627 | + sortArray(allStreams, preferenceKey[config.videoPreference]); |
| 628 | + const stream = allStreams[0]; |
| 629 | + return [stream.backupUrls[0] || stream.masterUrl]; |
602 | 630 | } catch (error) { |
603 | 631 | console.error("Error deal video URL:", error); |
604 | 632 | return []; |
@@ -1442,7 +1470,8 @@ Discord Community: https://discord.com/invite/ZYtmgKud9Y |
1442 | 1470 | box-shadow: 0 0 4px rgba(33, 150, 243, 0.3); |
1443 | 1471 | } |
1444 | 1472 | .select-input { |
1445 | | - width: 100px; |
| 1473 | + min-width: 130px; |
| 1474 | + width: auto; |
1446 | 1475 | padding: 8px 12px; |
1447 | 1476 | border: 1px solid #ddd; |
1448 | 1477 | border-radius: 4px; |
@@ -1919,8 +1948,11 @@ Discord Community: https://discord.com/invite/ZYtmgKud9Y |
1919 | 1948 | item.style.opacity = disabled ? 0.6 : 1; |
1920 | 1949 |
|
1921 | 1950 | // 生成选项HTML |
1922 | | - const optionsHtml = options.map( |
1923 | | - option => `<option value="${option}" ${option === value ? 'selected' : ''}>${option}</option>`).join(''); |
| 1951 | + const optionsHtml = options.map(option => { |
| 1952 | + const optionValue = typeof option === 'object' ? option.value : option; |
| 1953 | + const optionLabel = typeof option === 'object' ? option.label : option; |
| 1954 | + return `<option value="${optionValue}" ${optionValue === value ? 'selected' : ''}>${optionLabel}</option>`; |
| 1955 | + }).join(''); |
1924 | 1956 |
|
1925 | 1957 | item.innerHTML = ` |
1926 | 1958 | <label> |
@@ -2033,6 +2065,17 @@ Discord Community: https://discord.com/invite/ZYtmgKud9Y |
2033 | 2065 | .toUpperCase(), |
2034 | 2066 | }); |
2035 | 2067 |
|
| 2068 | + const videoPreference = createSelectItem({ |
| 2069 | + label: t.videoPreferenceLabel, |
| 2070 | + description: t.videoPreferenceDesc, |
| 2071 | + options: Object.entries(t.videoPreferenceOptions) |
| 2072 | + .map(([value, label]) => ({ |
| 2073 | + value, |
| 2074 | + label, |
| 2075 | + })), |
| 2076 | + value: config.videoPreference, |
| 2077 | + }); |
| 2078 | + |
2036 | 2079 | const nameFormat = createFileNameFormatEditor({ |
2037 | 2080 | label: t.fileNameFormatLabel, |
2038 | 2081 | description: t.fileNameFormatDesc, |
@@ -2068,7 +2111,7 @@ Discord Community: https://discord.com/invite/ZYtmgKud9Y |
2068 | 2111 | // 组合内容 |
2069 | 2112 | body.appendChild(createSettingsGroup( |
2070 | 2113 | t.downloadSettingsGroup, |
2071 | | - [filePack, imageCheckboxSwitch, imageDownloadFormat, nameFormat], |
| 2114 | + [filePack, imageCheckboxSwitch, imageDownloadFormat, videoPreference, nameFormat], |
2072 | 2115 | true |
2073 | 2116 | )); |
2074 | 2117 | body.appendChild(createSettingsGroup(t.extractSettingsGroup, [autoScroll, scrollCount, linkCheckboxSwitch])); |
@@ -2105,6 +2148,7 @@ Discord Community: https://discord.com/invite/ZYtmgKud9Y |
2105 | 2148 | updateScriptServerURL(scriptServerURL.querySelector('.text-input').value.trim() || defaultsWebSocketURL); |
2106 | 2149 | updateScriptServerSwitch(scriptServerSwitch.querySelector('input').checked); |
2107 | 2150 | updateImageDownloadFormat(imageDownloadFormat.querySelector('select').value.trim() || "jpeg"); |
| 2151 | + updateVideoPreference(videoPreference.querySelector('select').value); |
2108 | 2152 | updateFileNameFormat(nameFormat.getFileNameFormatKeys()); |
2109 | 2153 | closeSettingsModal(); |
2110 | 2154 | }); |
|
0 commit comments