├── .gitignore ├── static ├── css │ ├── common.css │ ├── reset.css │ ├── big-style.css │ └── small-style.css └── js │ ├── data.js │ └── main.js ├── images ├── image-20220206214458383.png ├── image-20220206214619203.png ├── image-20220208134901370.png └── image-20220706235635716.png ├── readme.md ├── index.html ├── .github └── workflows │ └── static.yml └── old_version └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | # webstorm 2 | .idea/* -------------------------------------------------------------------------------- /static/css/common.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #505050; 3 | font-size: 14px; 4 | } -------------------------------------------------------------------------------- /images/image-20220206214458383.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/here200/Watch-Video-By-Interface/HEAD/images/image-20220206214458383.png -------------------------------------------------------------------------------- /images/image-20220206214619203.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/here200/Watch-Video-By-Interface/HEAD/images/image-20220206214619203.png -------------------------------------------------------------------------------- /images/image-20220208134901370.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/here200/Watch-Video-By-Interface/HEAD/images/image-20220208134901370.png -------------------------------------------------------------------------------- /images/image-20220706235635716.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/here200/Watch-Video-By-Interface/HEAD/images/image-20220706235635716.png -------------------------------------------------------------------------------- /static/css/reset.css: -------------------------------------------------------------------------------- 1 | body, ul, li { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | li { 7 | list-style: none; 8 | } 9 | 10 | a { 11 | text-decoration: none; 12 | } -------------------------------------------------------------------------------- /static/js/data.js: -------------------------------------------------------------------------------- 1 | const routes = [ 2 | {name: 'M1907解析', url: 'https://z1.m1907.top/?jx='}, 3 | {name: '虾米解析', url: 'https://jx.xmflv.com/?url='}, 4 | {name: '影猫の仓库 ', url: 'https://ymck.pro/search.html?wd='}, 5 | ] 6 | 7 | const friends = [ 8 | {name: 'Here200\'s Bookmark', url: 'https://here200.github.io/Bookmark/'}, 9 | ] -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## VIP视频解析网站 2 | 3 | ### 特点 4 | 5 | 基于现公开的接口做了简易的界面,方便用户的使用. 6 | 7 | 接口支持绝大多数目前国内主流的视频网站. 8 | 9 | ### 使用 10 | 11 | - 复制想要观看的视频的链接 12 | - 将链接粘贴到该网站的输入框内,可以点击右边的**播放**按钮,或者直接敲击键盘的**Enter键**,即可进行解析. 13 | - 如果想清空输入框的内容,可以点击右边的**清空**按钮,或者直接敲击键盘的**Esc**键. 14 | - 可以在地址栏上?后面添加查询键值对url=你想要解析的地址,进行解析。 15 | - 该方式同时会在输入框附加上解析的地址。 16 | - 键值对url=,可以放在?后面的任何位置。 17 | - 支持选择线路 18 | - 适配手机端(目前,只使用了一台手机做了适配,其它手机的兼容性可能不是很好。如果有问题,请 issues me) 19 | 20 | ### 注意 21 | 22 | 1. 网站通过git page部署到github上,点击 [VIP视频解析](https://here200.github.io/Watch-Video-By-Interface/) 即可打开网站。 23 | 2. 如果无法打开以上网址,可以将该仓库的文件下载到本地后打开。 24 | 3. 如因接口问题导致无法解析,用户可以自行更换接口,也可以 issues me。 25 | 4. 接口可能暂时无法使用。为了应付此情况,故将其它的视频解析网站链接放置到友链中。以便用户根据需要进行选择。 26 | 27 | ### 图片(仅供参考,与实际可能不一致) 28 | 29 | ![image-20220206214458383](images/image-20220206214458383.png) 30 | 31 | ![image-20220206214619203](images/image-20220206214619203.png) 32 | 33 | ![image-20220706235635716](images/image-20220706235635716.png) 34 | 35 | ![image-20220208134901370](images/image-20220208134901370.png) -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | VIP视频解析 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /.github/workflows/static.yml: -------------------------------------------------------------------------------- 1 | # Simple workflow for deploying static content to GitHub Pages 2 | name: Deploy static content to Pages 3 | 4 | on: 5 | # Runs on pushes targeting the default branch 6 | push: 7 | branches: ["master"] 8 | 9 | # Allows you to run this workflow manually from the Actions tab 10 | workflow_dispatch: 11 | 12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 13 | permissions: 14 | contents: read 15 | pages: write 16 | id-token: write 17 | 18 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 19 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 20 | concurrency: 21 | group: "pages" 22 | cancel-in-progress: false 23 | 24 | jobs: 25 | # Single deploy job since we're just deploying 26 | deploy: 27 | environment: 28 | name: github-pages 29 | url: ${{ steps.deployment.outputs.page_url }} 30 | runs-on: ubuntu-latest 31 | steps: 32 | - name: Checkout 33 | uses: actions/checkout@v4 34 | - name: Setup Pages 35 | uses: actions/configure-pages@v5 36 | - name: Upload artifact 37 | uses: actions/upload-pages-artifact@v3 38 | with: 39 | # Upload entire repository 40 | path: '.' 41 | - name: Deploy to GitHub Pages 42 | id: deployment 43 | uses: actions/deploy-pages@v4 44 | -------------------------------------------------------------------------------- /static/css/big-style.css: -------------------------------------------------------------------------------- 1 | /* 导航条 */ 2 | .nav { 3 | display: flex; 4 | justify-content: center; 5 | height: 36px; 6 | margin-top: 50px; 7 | } 8 | 9 | /* 导航条-播放列表 */ 10 | .nav .route { 11 | display: flex; 12 | justify-content: center; 13 | align-items: center; 14 | position: relative; 15 | width: 130px; 16 | 17 | background-color: #ddd; 18 | } 19 | 20 | .nav .route .title { 21 | cursor: pointer; 22 | } 23 | 24 | .nav .route:hover .list { 25 | display: block; 26 | } 27 | 28 | .route .list { 29 | display: none; 30 | position: absolute; 31 | left: 0; 32 | right: 0; 33 | top: 36px; 34 | 35 | text-align: center; 36 | background-color: #0d0; 37 | } 38 | 39 | .route .list li { 40 | height: 25px; 41 | 42 | line-height: 25px; 43 | font-size: 15px; 44 | cursor: pointer; 45 | } 46 | 47 | .route .list li:hover { 48 | background-color: #ff0; 49 | } 50 | 51 | /* 导航条-输入框 */ 52 | .nav .search { 53 | width: 666px; 54 | margin: 0 5px; 55 | 56 | outline: none; 57 | font-size: 16px; 58 | } 59 | 60 | /* 导航条-按钮 */ 61 | .nav button { 62 | width: 50px; 63 | 64 | border-radius: 5px; 65 | cursor: pointer; 66 | outline: none; 67 | } 68 | 69 | .nav .clear { 70 | margin-left: 5px; 71 | } 72 | 73 | /* 播放器 */ 74 | .player { 75 | display: block; 76 | width: 1000px; 77 | height: 500px; 78 | margin: 30px auto; 79 | 80 | background-color: #ddd; 81 | border: none; 82 | overflow: hidden; 83 | } 84 | 85 | /* 友链 */ 86 | .friendLink { 87 | text-align: center; 88 | color: #ddd; 89 | } 90 | .friendLink a { 91 | margin-right: 5px; 92 | 93 | color: #ddd; 94 | } -------------------------------------------------------------------------------- /static/css/small-style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-size: 25px; 3 | } 4 | 5 | /* 导航条 */ 6 | .nav { 7 | display: flex; 8 | justify-content: center; 9 | height: 74px; 10 | margin-top: 5vh; 11 | } 12 | 13 | /* 导航条-播放列表 */ 14 | .nav .route { 15 | display: flex; 16 | justify-content: center; 17 | align-items: center; 18 | position: relative; 19 | width: 150px; 20 | 21 | background-color: #ddd; 22 | } 23 | 24 | .nav .route .title { 25 | cursor: pointer; 26 | } 27 | 28 | .nav .route:hover .list { 29 | display: block; 30 | } 31 | 32 | .route .list { 33 | display: none; 34 | position: absolute; 35 | left: 0; 36 | right: 0; 37 | top: 74px; 38 | 39 | text-align: center; 40 | background-color: #0d0; 41 | } 42 | 43 | .route .list li { 44 | height: 40px; 45 | 46 | line-height: 40px; 47 | cursor: pointer; 48 | font-size: 24px; 49 | } 50 | 51 | .route .list li:hover { 52 | background-color: #ff0; 53 | } 54 | 55 | /* 导航条-输入框 */ 56 | .nav .search { 57 | width: 50%; 58 | margin: 0 5px; 59 | 60 | outline: none; 61 | font-size: 22px; 62 | } 63 | 64 | /* 导航条-按钮 */ 65 | .nav button { 66 | width: 10%; 67 | 68 | border-radius: 20px; 69 | cursor: pointer; 70 | outline: none; 71 | font-size: 25px; 72 | } 73 | 74 | .nav .clear { 75 | margin-left: 5px; 76 | } 77 | 78 | /* 播放器 */ 79 | .player { 80 | display: block; 81 | margin: 20px auto; 82 | width: 94%; 83 | height: 60vh; 84 | 85 | background-color: #ddd; 86 | border: none; 87 | overflow: hidden; 88 | } 89 | 90 | /* 友链 */ 91 | .friendLink { 92 | text-align: center; 93 | color: #ddd; 94 | } 95 | .friendLink a { 96 | margin-right: 5px; 97 | 98 | color: #ddd; 99 | } -------------------------------------------------------------------------------- /static/js/main.js: -------------------------------------------------------------------------------- 1 | const routeEl = document.querySelector('.route') 2 | const routeListEl = routeEl.querySelector('.list') 3 | const routeTitleEl = routeEl.querySelector('.title') 4 | 5 | // 动态创建列表 6 | for (let index in routes) { 7 | const liEl = document.createElement('li') 8 | routeListEl.append(liEl) 9 | 10 | const item = routes[index] 11 | liEl.textContent = item.name 12 | liEl.onclick = function() { 13 | defaultRoute = index 14 | routeTitleEl.textContent = routes[defaultRoute].name 15 | 16 | // 如果搜索框存在内容,优先使用搜索框的内容。否则,使用缓存的内容 17 | if (searchEl.value) { 18 | enterURL = searchEl.value 19 | } 20 | 21 | play(enterURL) 22 | localStorage.setItem('default', defaultRoute) 23 | } 24 | } 25 | 26 | const friendEl = document.querySelector('.friendLink') 27 | for (const item of friends) { 28 | const aEl = document.createElement('a') 29 | friendEl.append(aEl) 30 | 31 | aEl.textContent = item.name 32 | aEl.href = item.url 33 | } 34 | 35 | // 获取默认路线 36 | const defaultValue = localStorage.getItem('default') || 0 37 | let defaultRoute = defaultValue < routes.length ? defaultValue : 0 38 | routeTitleEl.textContent = routes[defaultRoute].name 39 | 40 | // 播放功能 41 | const searchEl = document.querySelector('.search') 42 | const playerEl = document.querySelector('.player') 43 | const clickEl = document.querySelector('.click') 44 | const clearEl = document.querySelector('.clear') 45 | 46 | let enterURL = '' 47 | 48 | // 绑定按钮事件 49 | clickEl.onclick = parseURL 50 | clearEl.onclick = reset 51 | 52 | function play(url) { 53 | playerEl.src = routes[defaultRoute].url + url 54 | } 55 | 56 | // 当点击播放时 57 | function parseURL() { 58 | enterURL = searchEl.value 59 | play(enterURL) 60 | } 61 | 62 | // 当点击清空时 63 | function reset() { 64 | searchEl.value = '' 65 | } 66 | 67 | // 在选中输入框的情况下,按Enter触发解析动作,按Esc键触发输入内容清空动作。 68 | searchEl.onkeyup = function (event) { 69 | switch (event.key) { 70 | case 'Enter': { // 回车键 71 | parseURL() 72 | break 73 | } 74 | case 'Escape': { // ESC键 75 | reset() 76 | break 77 | } 78 | } 79 | } 80 | 81 | // 通过地址栏解析。提取?后面的url的值,并进行解析动作,如果不存在,则不进行解析 82 | const regex = /url=([^&]*)/ 83 | const queryString = location.search 84 | const result = queryString.match(regex) 85 | const url = result ? result[1] : null 86 | 87 | if (url) { 88 | enterURL = url 89 | play(url) 90 | searchEl.value = url 91 | } -------------------------------------------------------------------------------- /old_version/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | VIP视频解析 6 | 7 | 58 | 59 | 60 | 61 | 62 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 138 | 139 | 140 | --------------------------------------------------------------------------------