(articleNode, videoElem)
| 728 | } |
| 729 | |
| 730 | async function fetchVideoURL(articleNode, videoElem) { |
| 731 | let poster = videoElem.getAttribute("poster"); |
| 732 | let timeNodes = articleNode.querySelectorAll("time"); |
| 733 | // special thanks 孙年忠 (https://greasyfork.org/en/scripts/406535-instagram-download-button/discussions/120159) |
| 734 | let posterUrl = |
| 735 | timeNodes[timeNodes.length - 1].parentNode.parentNode.href; |
| 736 | const posterPattern = /\/([^\/?]*)\?/; |
| 737 | let posterMatch = poster.match(posterPattern); |
| 738 | let postFileName = posterMatch[1]; |
| 739 | let resp = await fetch(posterUrl); |
| 740 | let content = await resp.text(); |
| 741 | // special thanks to 孙年忠 for the pattern (https://greasyfork.org/zh-TW/scripts/406535-instagram-download-button/discussions/116675) |
| 742 | const pattern = new RegExp( |
| 743 | `${postFileName}.*?video_versions.*?url":("[^"]*")`, |
| 744 | "s" |
| 745 | ); |
| 746 | let match = content.match(pattern); |
| 747 | let videoUrl = JSON.parse(match[1]); |
| 748 | videoUrl = videoUrl.replace( |
| 749 | /^(?:https?:\/\/)?(?:[^@\/\n]+@)?(?:www\.)?([^:\/?\n]+)/g, |
| 750 | "https://scontent.cdninstagram.com" |
| 751 | ); |
| 752 | videoElem.setAttribute("videoURL", videoUrl); |
| 753 | return videoUrl; |
| 754 | } |
| 755 | |
| 756 | // ================================ |
| 757 | // ==== Story & Highlight ==== |
no test coverage detected