├── .travis.yml ├── .gitignore ├── dist ├── src │ ├── SB.d.ts │ ├── GP.d.ts │ ├── Solidfiles.d.ts │ ├── Blog.d.ts │ ├── Solidfiles.js │ ├── GP.js │ ├── Blog.js │ └── SB.js ├── index.d.ts └── index.js ├── .drone.yml ├── .idea ├── vcs.xml ├── misc.xml ├── modules.xml ├── google-photos-etc.iml └── workspace.xml ├── now.json ├── src ├── Solidfiles.ts ├── GP.ts ├── Blog.ts └── SB.ts ├── .github └── workflows │ └── nodejs.yml ├── tsconfig.json ├── index.ts ├── LICENSE.txt ├── package.json ├── README.md ├── example └── index.js ├── old └── index.js └── yarn.lock /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json 3 | .yarn.lock 4 | .idea 5 | .env 6 | .vercel 7 | -------------------------------------------------------------------------------- /dist/src/SB.d.ts: -------------------------------------------------------------------------------- 1 | declare const _default: (url: string) => Promise; 2 | export default _default; 3 | -------------------------------------------------------------------------------- /.drone.yml: -------------------------------------------------------------------------------- 1 | kind: pipeline 2 | name: node8 3 | steps: 4 | -name: khalis 5 | image: node:8 6 | commands: 7 | -npm install 8 | -npm run dev -------------------------------------------------------------------------------- /dist/src/GP.d.ts: -------------------------------------------------------------------------------- 1 | declare const _default: (url: string) => Promise<{ 2 | source: undefined | string; 3 | }>; 4 | export default _default; 5 | -------------------------------------------------------------------------------- /dist/src/Solidfiles.d.ts: -------------------------------------------------------------------------------- 1 | declare class Solidfiles { 2 | get(uri: string): Promise; 3 | private parse; 4 | } 5 | declare const _default: Solidfiles; 6 | export default _default; 7 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /dist/index.d.ts: -------------------------------------------------------------------------------- 1 | export { default as Solidfiles } from './src/Solidfiles'; 2 | import { getBlogList, getSourceVideo } from './src/Blog'; 3 | import GP from './src/GP'; 4 | import SB from './src/SB'; 5 | export { getBlogList, getSourceVideo, GP, SB }; 6 | -------------------------------------------------------------------------------- /now.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "name":"khalis", 4 | "alias":["khalis-khalis411.now.sh"], 5 | "builds":[ 6 | { "src": "/example/index.js", "use": "@now/node" } 7 | ], 8 | "routes":[ 9 | { "src":".*","dest":"/example/index.js" } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/google-photos-etc.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /dist/src/Blog.d.ts: -------------------------------------------------------------------------------- 1 | interface source { 2 | thumbnail: string; 3 | iframe_id: string; 4 | allow_resize: boolean; 5 | streams: Array<{ 6 | play_url: string; 7 | format_id: number; 8 | }>; 9 | } 10 | interface list { 11 | id: string; 12 | source: source; 13 | } 14 | export declare const getBlogList: (url: string) => Promise; 15 | export declare const getSourceVideo: (url: string | any) => Promise | undefined>; 16 | export {}; 17 | -------------------------------------------------------------------------------- /src/Solidfiles.ts: -------------------------------------------------------------------------------- 1 | import cheerio from 'cheerio'; 2 | import axios from 'axios'; 3 | 4 | class Solidfiles { 5 | public async get(uri:string){ 6 | const url = await axios.get(uri); 7 | return JSON.parse(this.parse(url.data)) 8 | } 9 | 10 | private parse($:any):any{ 11 | const item = cheerio.load($)('body > script:nth-child(16)').html()?.replace("angular.module('sf.viewer').constant('viewerOptions', ","").replace(");",''); 12 | return item 13 | } 14 | } 15 | 16 | export default new Solidfiles() -------------------------------------------------------------------------------- /src/GP.ts: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import cheerio from "cheerio"; 3 | 4 | export default async (url: string): Promise<{ source: undefined | string }> => { 5 | try { 6 | const fetch = await axios.get(url); 7 | const $ = cheerio.load(fetch.data); 8 | const item: any = $('body > script').eq(5).html()?.match(/\bhttps?:\/\/[^,\s()<>]+/gi); 9 | let source: string | undefined = undefined; 10 | for (let i = 0;i < item.length;i++) { 11 | const result: string = item[i]; 12 | if (result.indexOf('video-downloads') != -1) { 13 | source = result 14 | } 15 | } 16 | return { 17 | source 18 | }; 19 | } catch (e) { 20 | return e; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.SB = exports.GP = exports.getSourceVideo = exports.getBlogList = exports.Solidfiles = void 0; 7 | var Solidfiles_1 = require("./src/Solidfiles"); 8 | Object.defineProperty(exports, "Solidfiles", { enumerable: true, get: function () { return __importDefault(Solidfiles_1).default; } }); 9 | const Blog_1 = require("./src/Blog"); 10 | Object.defineProperty(exports, "getBlogList", { enumerable: true, get: function () { return Blog_1.getBlogList; } }); 11 | Object.defineProperty(exports, "getSourceVideo", { enumerable: true, get: function () { return Blog_1.getSourceVideo; } }); 12 | const GP_1 = __importDefault(require("./src/GP")); 13 | exports.GP = GP_1.default; 14 | const SB_1 = __importDefault(require("./src/SB")); 15 | exports.SB = SB_1.default; 16 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Node CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | strategy: 11 | matrix: 12 | node-version: [8.x, 10.x, 12.x] 13 | 14 | steps: 15 | - uses: actions/checkout@master 16 | - name: Use Node.js 12 17 | uses: actions/setup-node@v1 18 | with: 19 | node-version: 12 20 | registry-url: https://registry.npmjs.org/ 21 | - name: npm install, publish 22 | run: | 23 | npm install 24 | npm publish 25 | env: 26 | NODE_AUTH_TOKEN: ${{secrets.npm_token}} 27 | CI: true 28 | publish-gpr: 29 | needs: build 30 | runs-on: ubuntu-latest 31 | steps: 32 | - uses: actions/checkout@master 33 | - uses: actions/setup-node@v1 34 | with: 35 | node-version: 12 36 | registry-url: https://npm.pkg.github.com/ 37 | scope: '@khalisafkari' 38 | - run: npm publish 39 | env: 40 | NODE_AUTH_TOKEN: ${{secrets.gtoken}} 41 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "skipLibCheck": true, 5 | "target": "es6", 6 | "lib": ["dom","ES6","esnext"], /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ 7 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ 8 | "strict": true, /* Enable all strict type-checking options. */ 9 | "outDir": "./dist", 10 | "rootDir": "./", 11 | "moduleResolution": "node", 12 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 13 | "resolveJsonModule": true, 14 | "declaration": true, 15 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ 16 | }, 17 | } 18 | -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | export { default as Solidfiles } from './src/Solidfiles'; 2 | import { getBlogList, getSourceVideo } from './src/Blog'; 3 | import GP from './src/GP'; 4 | import SB from './src/SB'; 5 | 6 | 7 | /* 8 | Blogger 9 | getBlogList: Promise 10 | getSourceVideo: Promise 11 | 12 | Google Photos 13 | GP: Promise<{ source: string }> 14 | 15 | streamsb.com 16 | SB: Promise<{ resolution: string, source: string }> 17 | */ 18 | 19 | //getBlogList('https://prikate09.blogspot.com/2017/10/all-ani-29-oktober-2017-413.html'); 20 | //getSourceVideo('https://www.blogger.com/video.g?token=AD6v5dw27DkFA4pN3A4ym5njnsCfyh0s8spLVR2z2OfXBPSrTIsYZcHSCrpe6GMfmiO5zVxGf2p4ZBwPX6RlX4_ul7yIdQR4Fv8jXSSoKSeJ-4ZJx3sBW4SwQPIogsCMqB4WNNw_vhw') 21 | //GP('https://photos.google.com/share/AF1QipNccwxrdUIfGMkLpt-yA-QxQY7HGqg7_hqIinlPaYxg3rLhZIufTv0qB_fFs4pKYA/photo/AF1QipNRiHEP9DTCQkhhIC1AMah7eMcnm8UN8KTLLW5j?key=TUFuaUtNXzZzdUtsem1iUDNJcFNwbTFqQ3UzWC13') 22 | //SB('https://sbembed1.com/wl8hcnm2ihlr.html').then(console.log) 23 | 24 | export { 25 | getBlogList, 26 | getSourceVideo, 27 | GP, 28 | SB 29 | } 30 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Khalis Afkari 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "google-photos-etc", 3 | "version": "2.1.2", 4 | "main": "./dist/index.js", 5 | "typings": "./dist/index.d.ts", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/khalisafkari/google-photos-etc.git" 9 | }, 10 | "author": "Khalis Afkari ", 11 | "license": "MIT", 12 | "scripts": { 13 | "tsc": "tsc --init", 14 | "build": "tsc -p .", 15 | "dev": "nodemon example/index.js", 16 | "release": "npm-github-release", 17 | "test": "nodemon index.ts" 18 | }, 19 | "devDependencies": { 20 | "@types/cheerio": "^0.22.29", 21 | "@types/express": "^4.17.12", 22 | "nodemon": "^2.0.7", 23 | "npm-github-release": "^0.12.0", 24 | "ts-node": "^10.0.0", 25 | "typescript": "^4.3.2" 26 | }, 27 | "dependencies": { 28 | "axios": "^0.21.1", 29 | "cheerio": "^1.0.0-rc.9", 30 | "cors": "^2.8.5", 31 | "express": "^4.17.1", 32 | "request": "^2.88.0" 33 | }, 34 | "homepage": "https://github.com/khalisafkari/google-photos-etc", 35 | "description": "[![Build Status](https://travis-ci.org/khalisafkari/google-photos-etc.svg?branch=master)](https://travis-ci.org/khalisafkari/google-photos-etc)", 36 | "bugs": { 37 | "url": "https://github.com/khalisafkari/google-photos-etc/issues" 38 | }, 39 | "keywords": [ 40 | "google", 41 | "google", 42 | "photos", 43 | "google", 44 | "drive", 45 | "blogger" 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /src/Blog.ts: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import cheerio from "cheerio"; 3 | 4 | interface source { 5 | thumbnail: string; 6 | iframe_id: string; 7 | allow_resize: boolean; 8 | streams: Array<{ 9 | play_url: string; 10 | format_id: number; 11 | }> 12 | } 13 | 14 | interface list { 15 | id: string; 16 | source: source; 17 | } 18 | 19 | export const getBlogList = async (url: string): Promise => { 20 | try { 21 | const fetch = await axios.get(url); 22 | const $ = cheerio.load(fetch.data); 23 | const list: any[] = []; 24 | $('iframe').each(async (index, element) => { 25 | const item = $(element).attr('src'); 26 | if (item) { 27 | list.push({ 28 | id: item, 29 | }) 30 | } 31 | }) 32 | 33 | for (let i = 0;i < list.length;i++) { 34 | list[i].source = await getSourceVideo(list[i].id) 35 | } 36 | 37 | return list; 38 | 39 | } catch (e) { 40 | return e; 41 | } 42 | } 43 | 44 | export const getSourceVideo = async (url: string | any): Promise | undefined> => { 45 | try { 46 | const fetch = await axios.get(url); 47 | const $ = cheerio.load(fetch.data); 48 | const data = $('script').html()?.trim(); 49 | return JSON.parse(data?.replace('var VIDEO_CONFIG = ', '')) 50 | } catch (e) { 51 | return e; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/SB.ts: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import cheerio from "cheerio"; 3 | 4 | export default async (url: string) => { 5 | if (!url) { 6 | throw new Error('cannot valid url') 7 | } 8 | try { 9 | const fetch = await axios.get(url) 10 | const $ = cheerio.load(fetch.data); 11 | const list = $('.tbl1 td a').map((index, elemenent) => { 12 | return { 13 | resolution: $(elemenent).text(), 14 | source: $(elemenent).attr('onclick')?.replace('download_video(','').replace(')','').replace(/'/gi,'').split(',') 15 | } 16 | }).get(); 17 | 18 | const listItem = [] 19 | 20 | for(let i = 0;i < list.length;i++) { 21 | listItem.push({ 22 | resolution: list[i].resolution, 23 | source: await getSource({ 24 | id: list[i].source[0], 25 | mode: list[i].source[1], 26 | hash:list[i].source[2] 27 | }) 28 | }) 29 | } 30 | 31 | return listItem; 32 | 33 | } catch (e) { 34 | return e; 35 | } 36 | } 37 | 38 | const getSource = async ({ id, mode, hash }:{ id: string, mode: string, hash: string }) => { 39 | try { 40 | const fetch = await axios.get(`https://sbembed1.com/dl?op=download_orig&id=${id}&mode=${mode}&hash=${hash}`) 41 | const $ = cheerio.load(fetch.data); 42 | return $('span a').attr('href') 43 | } catch(e) { 44 | return e; 45 | } 46 | } -------------------------------------------------------------------------------- /dist/src/Solidfiles.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | var __importDefault = (this && this.__importDefault) || function (mod) { 12 | return (mod && mod.__esModule) ? mod : { "default": mod }; 13 | }; 14 | Object.defineProperty(exports, "__esModule", { value: true }); 15 | const cheerio_1 = __importDefault(require("cheerio")); 16 | const axios_1 = __importDefault(require("axios")); 17 | class Solidfiles { 18 | get(uri) { 19 | return __awaiter(this, void 0, void 0, function* () { 20 | const url = yield axios_1.default.get(uri); 21 | return JSON.parse(this.parse(url.data)); 22 | }); 23 | } 24 | parse($) { 25 | var _a; 26 | const item = (_a = cheerio_1.default.load($)('body > script:nth-child(16)').html()) === null || _a === void 0 ? void 0 : _a.replace("angular.module('sf.viewer').constant('viewerOptions', ", "").replace(");", ''); 27 | return item; 28 | } 29 | } 30 | exports.default = new Solidfiles(); 31 | -------------------------------------------------------------------------------- /dist/src/GP.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | var __importDefault = (this && this.__importDefault) || function (mod) { 12 | return (mod && mod.__esModule) ? mod : { "default": mod }; 13 | }; 14 | Object.defineProperty(exports, "__esModule", { value: true }); 15 | const axios_1 = __importDefault(require("axios")); 16 | const cheerio_1 = __importDefault(require("cheerio")); 17 | exports.default = (url) => __awaiter(void 0, void 0, void 0, function* () { 18 | var _a; 19 | try { 20 | const fetch = yield axios_1.default.get(url); 21 | const $ = cheerio_1.default.load(fetch.data); 22 | const item = (_a = $('body > script').eq(5).html()) === null || _a === void 0 ? void 0 : _a.match(/\bhttps?:\/\/[^,\s()<>]+/gi); 23 | let source = undefined; 24 | for (let i = 0; i < item.length; i++) { 25 | const result = item[i]; 26 | if (result.indexOf('video-downloads') != -1) { 27 | source = result; 28 | } 29 | } 30 | return { 31 | source 32 | }; 33 | } 34 | catch (e) { 35 | return e; 36 | } 37 | }); 38 | -------------------------------------------------------------------------------- /dist/src/Blog.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | var __importDefault = (this && this.__importDefault) || function (mod) { 12 | return (mod && mod.__esModule) ? mod : { "default": mod }; 13 | }; 14 | Object.defineProperty(exports, "__esModule", { value: true }); 15 | exports.getSourceVideo = exports.getBlogList = void 0; 16 | const axios_1 = __importDefault(require("axios")); 17 | const cheerio_1 = __importDefault(require("cheerio")); 18 | const getBlogList = (url) => __awaiter(void 0, void 0, void 0, function* () { 19 | try { 20 | const fetch = yield axios_1.default.get(url); 21 | const $ = cheerio_1.default.load(fetch.data); 22 | const list = []; 23 | $('iframe').each((index, element) => __awaiter(void 0, void 0, void 0, function* () { 24 | const item = $(element).attr('src'); 25 | if (item) { 26 | list.push({ 27 | id: item, 28 | }); 29 | } 30 | })); 31 | for (let i = 0; i < list.length; i++) { 32 | list[i].source = yield exports.getSourceVideo(list[i].id); 33 | } 34 | return list; 35 | } 36 | catch (e) { 37 | return e; 38 | } 39 | }); 40 | exports.getBlogList = getBlogList; 41 | const getSourceVideo = (url) => __awaiter(void 0, void 0, void 0, function* () { 42 | var _a; 43 | try { 44 | const fetch = yield axios_1.default.get(url); 45 | const $ = cheerio_1.default.load(fetch.data); 46 | const data = (_a = $('script').html()) === null || _a === void 0 ? void 0 : _a.trim(); 47 | return JSON.parse(data === null || data === void 0 ? void 0 : data.replace('var VIDEO_CONFIG = ', '')); 48 | } 49 | catch (e) { 50 | return e; 51 | } 52 | }); 53 | exports.getSourceVideo = getSourceVideo; 54 | -------------------------------------------------------------------------------- /dist/src/SB.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | var __importDefault = (this && this.__importDefault) || function (mod) { 12 | return (mod && mod.__esModule) ? mod : { "default": mod }; 13 | }; 14 | Object.defineProperty(exports, "__esModule", { value: true }); 15 | const axios_1 = __importDefault(require("axios")); 16 | const cheerio_1 = __importDefault(require("cheerio")); 17 | exports.default = (url) => __awaiter(void 0, void 0, void 0, function* () { 18 | if (!url) { 19 | throw new Error('cannot valid url'); 20 | } 21 | try { 22 | const fetch = yield axios_1.default.get(url); 23 | const $ = cheerio_1.default.load(fetch.data); 24 | const list = $('.tbl1 td a').map((index, elemenent) => { 25 | var _a; 26 | return { 27 | resolution: $(elemenent).text(), 28 | source: (_a = $(elemenent).attr('onclick')) === null || _a === void 0 ? void 0 : _a.replace('download_video(', '').replace(')', '').replace(/'/gi, '').split(',') 29 | }; 30 | }).get(); 31 | const listItem = []; 32 | for (let i = 0; i < list.length; i++) { 33 | listItem.push({ 34 | resolution: list[i].resolution, 35 | source: yield getSource({ 36 | id: list[i].source[0], 37 | mode: list[i].source[1], 38 | hash: list[i].source[2] 39 | }) 40 | }); 41 | } 42 | return listItem; 43 | } 44 | catch (e) { 45 | return e; 46 | } 47 | }); 48 | const getSource = ({ id, mode, hash }) => __awaiter(void 0, void 0, void 0, function* () { 49 | try { 50 | const fetch = yield axios_1.default.get(`https://sbembed1.com/dl?op=download_orig&id=${id}&mode=${mode}&hash=${hash}`); 51 | const $ = cheerio_1.default.load(fetch.data); 52 | return $('span a').attr('href'); 53 | } 54 | catch (e) { 55 | return e; 56 | } 57 | }); 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #### Multi direct link Streaming & Downloader 2 | 3 | [![Build Status](https://travis-ci.org/khalisafkari/google-photos-etc.svg?branch=master)](https://travis-ci.org/khalisafkari/google-photos-etc) 4 | 5 | > Grab Blogger & Google Photos, mp4upload.com, cloudvideo.tv, etc streaming link 6 | **** 7 | > **Leaguage** : node 8 | 9 | > **react-native** : [react-native-google-photos](https://github.com/khalisafkari/react-native-google-photos) 10 | 11 | ## TOC 12 | * [Install](#installation) 13 | * [Screenshot](#screenshot) 14 | * [Note](#note) 15 | * [Support](#support) 16 | 17 | ## Installation 18 | 19 | 20 | 1. clone repo 21 | 2. install dep with **npm i** 22 | 3. run **npm run dev** 23 | 4. JSON Mode 24 | ```js 25 | // localhost example blogger 26 | `http://localhost:3000/blist?url=https%3A%2F%2Fprikate09.blogspot.com%2F2017%2F10%2Fall-ani-29-oktober-2017-413.html` 27 | 28 | // onlie mode blogger 29 | `https://khalis-khalis411.vercel.app/blist?url=https%3A%2F%2Fprikate09.blogspot.com%2F2017%2F10%2Fall-ani-29-oktober-2017-413.html` 30 | 31 | // blogger WithToken localhost 32 | `http://localhost:3000/bsource?url=https%3A%2F%2Fwww.blogger.com%2Fvideo.g%3Ftoken%3DAD6v5dw27DkFA4pN3A4ym5njnsCfyh0s8spLVR2z2OfXBPSrTIsYZcHSCrpe6GMfmiO5zVxGf2p4ZBwPX6RlX4_ul7yIdQR4Fv8jXSSoKSeJ-4ZJx3sBW4SwQPIogsCMqB4WNNw_vhw` 33 | 34 | // online blogger WithToken 35 | `https://khalis-khalis411.vercel.app/bsource?url=https%3A%2F%2Fwww.blogger.com%2Fvideo.g%3Ftoken%3DAD6v5dw27DkFA4pN3A4ym5njnsCfyh0s8spLVR2z2OfXBPSrTIsYZcHSCrpe6GMfmiO5zVxGf2p4ZBwPX6RlX4_ul7yIdQR4Fv8jXSSoKSeJ-4ZJx3sBW4SwQPIogsCMqB4WNNw_vhw` 36 | 37 | 38 | //localhost example photos.google.com 39 | `http://localhost:3000/gp?url=https://photos.google.com/share/AF1QipNccwxrdUIfGMkLpt-yA-QxQY7HGqg7_hqIinlPaYxg3rLhZIufTv0qB_fFs4pKYA/photo/AF1QipNRiHEP9DTCQkhhIC1AMah7eMcnm8UN8KTLLW5j?key=TUFuaUtNXzZzdUtsem1iUDNJcFNwbTFqQ3UzWC13` 40 | 41 | //now demo mode photos.google.com 42 | `https://khalis-khalis411.vercel.app/gp?url=https://photos.google.com/share/AF1QipNccwxrdUIfGMkLpt-yA-QxQY7HGqg7_hqIinlPaYxg3rLhZIufTv0qB_fFs4pKYA/photo/AF1QipNRiHEP9DTCQkhhIC1AMah7eMcnm8UN8KTLLW5j?key=TUFuaUtNXzZzdUtsem1iUDNJcFNwbTFqQ3UzWC13` 43 | 44 | // now demo Solidfiles 45 | `https://khalis.khalis411.now.sh/Solidfiles` 46 | 47 | // localhost demo Solidfiles 48 | `http://localhost:3000/Solidfiles` 49 | 50 | 51 | to request a demo by yourself please use the url query 52 | 53 | ``` 54 | 55 | ## Screenshot 56 | 57 | > proxy mode 58 | ![](https://i.imgur.com/7TfqEUc.png) 59 | 60 | > json mode 61 | > ![](https://i.imgur.com/xETf6I7.png) 62 | 63 | 64 | ## Note 65 | > json mode no longer uses the www.blogger.com url but the url of your blog 66 | 67 | > if you use react-native follow this repo [react-native-google-photos](https://github.com/khalisafkari/react-native-google-photos) 68 | 69 | ## Available 70 | 71 | * [x] Google Photos 72 | * [x] Blogger.com 73 | * [x] solidFiles 74 | 75 | ## Support 76 |
77 | jetbrains 78 | zeit 79 |
80 | 81 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | // 2 | // const app = require('express')(); 3 | // const cors = require('cors'); 4 | // const { Blogger,Solidfiles,GPhotos } = require('../dist') 5 | // app.use(cors()) 6 | // 7 | // app.get('/',(req,res)=>{ 8 | // res.send('data') 9 | // }) 10 | // 11 | // app.get('/WithBlogger',async(req,res) => { 12 | // try { 13 | // const data = await Blogger.WithBlogger(req.query.url || 'https://prikate09.blogspot.com/2017/10/all-ani-29-oktober-2017-413.html'); 14 | // res.send(data) 15 | // } catch (error) { 16 | // res.send() 17 | // } 18 | // }); 19 | // 20 | // app.get('/WithVideoToken',async(req,res) => { 21 | // try { 22 | // const data = await Blogger.WithVideoToken(req.query.url || 'https://www.blogger.com/video.g?token=AD6v5dyQXUjqRayoSfBIT3qk5lxWIjHZfaVrQbwohxdEXTw2ulOd9Dt7mrxZOyhuVoYBPUATpbeo9uZDqkCmVkzKsS2LYmzHXjsZRKEjDzK7OgNVKJBm59j_LJUE2djMywWz2JDQ-us') 23 | // res.send(data) 24 | // } catch (error) { 25 | // res.send() 26 | // } 27 | // }) 28 | // 29 | // app.get('/Solidfiles',async(req,res) => { 30 | // try { 31 | // const data = await Solidfiles.get(req.query.url || 'http://www.solidfiles.com/v/aZKjvxnDmk3NX' ); 32 | // res.send(data) 33 | // } catch (error) { 34 | // res.send() 35 | // } 36 | // }) 37 | // 38 | // app.get('/GPhotos',async(req,res) => { 39 | // console.log(req.headers) 40 | // try { 41 | // const data = await GPhotos.get(req.query.url || 'https://photos.google.com/share/AF1QipMTEPAiVF8t0YqLukflnOSQjwfd8ARIoT2h37AXvYO1uaWodbeiFoBUDuD_19tEbg/photo/AF1QipPA2Bq0JlAR9LoGD3mogsxSb9OZWEG4XqBDD4Rv?key=cjhUT0xrZjM5NGN2SVRLOVptZU5SMUlKV0lQYWpB') 42 | // // let todos = [] 43 | // // for(let i = 0;i < data.length;i++){ 44 | // // if(data[i]._res === "medium"){ 45 | // // todos.push({ 46 | // // id:data[i]._id, 47 | // // res:data[i]._res 48 | // // }) 49 | // // } 50 | // // } 51 | // res.send(data) 52 | // } catch (error) { 53 | // res.send() 54 | // } 55 | // }) 56 | // 57 | // 58 | // 59 | // app.listen(3000,() => { 60 | // console.log(3000) 61 | // }); 62 | 63 | const express = require('express'); 64 | const cors = require('cors'); 65 | const { GP, getBlogList, getSourceVideo, SB } = require('../dist'); 66 | 67 | const app = express(); 68 | app.use(cors()) 69 | 70 | app.get('/', (req, res) => { 71 | return res.status(200).send({ 72 | google: { 73 | url: '/gp?url=https://photos.google.com/share/AF1QipNccwxrdUIfGMkLpt-yA-QxQY7HGqg7_hqIinlPaYxg3rLhZIufTv0qB_fFs4pKYA/photo/AF1QipNRiHEP9DTCQkhhIC1AMah7eMcnm8UN8KTLLW5j?key=TUFuaUtNXzZzdUtsem1iUDNJcFNwbTFqQ3UzWC13' 74 | }, 75 | blogger:{ 76 | list: '/blist?url=https://prikate09.blogspot.com/2017/10/all-ani-29-oktober-2017-413.html', 77 | source: '/bsource?url=https://www.blogger.com/video.g?token=AD6v5dw27DkFA4pN3A4ym5njnsCfyh0s8spLVR2z2OfXBPSrTIsYZcHSCrpe6GMfmiO5zVxGf2p4ZBwPX6RlX4_ul7yIdQR4Fv8jXSSoKSeJ-4ZJx3sBW4SwQPIogsCMqB4WNNw_vhw' 78 | }, 79 | streamsb:{ 80 | url: '/sb?url=https://sbembed1.com/wl8hcnm2ihlr.html#' 81 | } 82 | }) 83 | }); 84 | 85 | app.get('/gp', async (req, res) => { 86 | const url = req.query.url; 87 | if (!url) { 88 | return res.status(201).send({ 89 | status: 201, 90 | message: 'not valid url' 91 | }) 92 | } 93 | const fetch = await GP(url); 94 | return res.status(200).send(fetch) 95 | }) 96 | 97 | app.get('/blist', async (req,res) => { 98 | const url = req.query.url; 99 | if (!url) { 100 | return res.status(201).send({ 101 | status: 201, 102 | message: 'not valid url' 103 | }) 104 | } 105 | 106 | const fetch = await getBlogList(url); 107 | return res.status(200).send(fetch) 108 | }) 109 | 110 | app.get('/bsource', async (req, res) => { 111 | const url = req.query.url; 112 | if (!url) { 113 | return res.status(201).send({ 114 | status: 201, 115 | message: 'not valid url' 116 | }) 117 | } 118 | 119 | const fetch = await getSourceVideo(url); 120 | return res.status(200).send(fetch); 121 | }) 122 | 123 | app.get('/sb', async (req, res) => { 124 | const url = req.query.url; 125 | if(!url) { 126 | return res.status(201).send({ 127 | status: 201, 128 | message: 'not valid url' 129 | }) 130 | } 131 | const fetch = await SB(url); 132 | return res.status(200).send(fetch) 133 | }) 134 | 135 | app.listen(3000); 136 | -------------------------------------------------------------------------------- /old/index.js: -------------------------------------------------------------------------------- 1 | const cheerio = require('cheerio'); 2 | const axios = require('axios'); 3 | 4 | class Video { 5 | async Blogger({uri}){ 6 | const url = await axios.get(uri); 7 | const $ = cheerio.load(url.data); 8 | const todos = [] 9 | $('iframe').each((index,item)=>{ 10 | const $element = $(item); 11 | if(!$element.attr('src')){}else{todos.push($element.attr('src'))}; 12 | }) 13 | for(let i = 0;i < todos.length;i++){todos[i] = await multi(todos[i])} 14 | return todos; 15 | } 16 | 17 | async Blogger_Video({uri,type}){ 18 | if(type == 1){ 19 | const url = await bg_url(uri); 20 | return url; 21 | }else if(type == 2){ 22 | const url = await multi(uri); 23 | return url.url 24 | }else{ 25 | return { 26 | code:1, 27 | message:'params not found' 28 | } 29 | } 30 | 31 | } 32 | 33 | async CloudVideo({uri}){ 34 | const its = uri.replace('https://cloudvideo.tv/','') 35 | const url = await axios.get(uri); 36 | const $ = cheerio.load(url.data); 37 | const todos = { 38 | video_hls_only:cheerio.load(url.data)('video > source').attr('src'), 39 | data:[] 40 | } 41 | $('#download > a').each(async(i,item)=>{ 42 | const $element = $(item); 43 | const m = $element.attr('onclick').replace('download_video(','').replace(')','').replace(`'${its}'`,''); 44 | if(m.indexOf(`'n'`) !== -1){ 45 | todos.data.push({ 46 | title:$element.text(), 47 | url:`https://cloudvideo.tv/dl?op=download_orig&id=${its}&mode=n&hash=${m.replace(`,'n','`,'').replace(`'`,'')}` 48 | }) 49 | }else if(m.indexOf(`'h'`) !== -1){ 50 | todos.data.push({ 51 | title:$element.text(), 52 | url:`https://cloudvideo.tv/dl?op=download_orig&id=${its}&mode=n&hash=${m.replace(`,'h','`,'').replace(`'`,'')}` 53 | }) 54 | }else if(m.indexOf(`'l'`) !== -1){ 55 | todos.data.push({ 56 | title:$element.text(), 57 | url:`https://cloudvideo.tv/dl?op=download_orig&id=${its}&mode=n&hash=${m.replace(`,'l','`,'').replace(`'`,'')}` 58 | }) 59 | } 60 | }) 61 | for(let i = 0;i < todos.data.length;i++){ 62 | const data = await cloud(todos.data[i].url); 63 | todos.data[i].url = data; 64 | } 65 | return todos; 66 | } 67 | 68 | async Photos(i){ 69 | const url = await axios.get(i); 70 | const $ = cheerio.load(url.data)('body').html() 71 | const item = `${$}` 72 | const $data = item.split('003d'); 73 | const todos = {} 74 | for(let i = 0;i < $data.length;i++){ 75 | if($data[i].indexOf('hd1080') != -1){ 76 | todos['hd1080'] = `${decodeURIComponent($data[1].split('%3Dm')[0])}=m37` 77 | }else if($data[i].indexOf('hd720') != -1){ 78 | todos['hd720'] = `${decodeURIComponent($data[1].split('%3Dm')[0])}=m22` 79 | }else{ 80 | todos['hd480'] = `${decodeURIComponent($data[1].split('%3Dm')[0])}=m18` 81 | } 82 | } 83 | return todos; 84 | } 85 | 86 | async Mp4Upload(i){ 87 | const url = await axios.get(i); 88 | const $ = cheerio.load(url.data)('body > script:nth-child(9)').html(); 89 | const items = $.substring(926,$.length); 90 | const tt = `${items.slice(0,-15)}`; 91 | const m = explodeMp4Upload(tt) 92 | return m; 93 | } 94 | 95 | async RapidVideo(i){ 96 | const url = await axios.get(i); 97 | return cheerio.load(url.data)('source').attr('src') 98 | } 99 | } 100 | 101 | const explodeMp4Upload = async(i) => { 102 | const t = i.split('video|')[1]; 103 | const m = t.split('|282') 104 | if(i.indexOf('|www2|') !== -1){ 105 | // console.log('yes |www2|') 106 | return `https://www2.mp4upload.com:282/d/${m[0]}/video.mp4` 107 | }else if(i.indexOf('|s3|') !== -1){ 108 | // console.log('yes |s3|') 109 | return `https://s3.mp4upload.com:282/d/${m[0]}/video.mp4` 110 | } 111 | } 112 | 113 | const cloud =async(i) =>{ 114 | const url = await axios.get(i); 115 | return cheerio.load(url.data)('a[class="btn btn-primary btn-block btn-signin"]').attr('href') 116 | } 117 | 118 | const multi = async(i) => { 119 | const url = await axios.get(i); 120 | const $ = cheerio.load(url.data); 121 | const data = $('script')[0].children[0] 122 | const rp = JSON.parse( data.data.replace('var VIDEO_CONFIG =','')) 123 | return{ 124 | poster:rp.thumbnail, 125 | url:rp.streams[0].play_url 126 | } 127 | } 128 | 129 | const bg_url = async(s) => { 130 | const i = await axios.get(s); 131 | const url = await axios.get(cheerio.load(i.data)('iframe').attr('src')); 132 | const $ = cheerio.load(url.data)('script')[0].children[0]; 133 | const rp = JSON.parse($.data.replace('var VIDEO_CONFIG =','')); 134 | return rp.streams[0].play_url; 135 | } 136 | 137 | // const blogger = async(url) => { 138 | // let uri = await axios.get(url); 139 | // const $ = cheerio.load(uri.data); 140 | // const data = $('script')[0].children[0] 141 | // const rp = JSON.parse( data.data.replace('var VIDEO_CONFIG =','')) 142 | // return rp.streams[0]; 143 | // } 144 | 145 | module.exports = new Video() -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 16 | 17 | 19 | 20 | 24 | 25 | 26 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |