Simple Video Downloader 3.0.4 - Webpack, ES6, Unit Tests and more!

in #utopian-io6 years ago (edited)

Introducing to Simple Video Downloader

The Video Downloader is a Chrome Extension that helps you save your favorite videos. It can be installed via Chrome Webstore:
https://chrome.google.com/webstore/detail/ilcdiicigjaccgipndigcenjieedjohj/

Total Number of Current Users

image.png

Install on Firefox or other browsers?

It should work, but not fully tested on Firefox via Chrome Extension Foxified

Changes v3.0.4

Pull Requests Merged: https://github.com/DoctorLai/VideoDownloadHelper/pull/4

  1. using ES6 and webpack - npm run build
    image.png
  2. unit tests via mocha and chai - npm run test
    image.png
  3. adding ParseVideo class that analyses HTML
  4. handles pearvideo.com
  5. handles miaopai.com

Class of ParseVideo

/* jshint -W097 */
/* jshint -W117 */
"use strict";

const { ValidURL, extractDomain, FixURL } = require( '../js/functions' )  ;

class ParseVideo {
    constructor(url, html = "") {
        // e.g. https://www.dailymotion.com/video/x2bu0q2
        this.url = url;
        // e.g. <html>....</html>
        this.html = html;
    }

    // entry of video parser
    Parse() {
        let domain = extractDomain(this.url);
        let video_url = "";
        if (domain.includes("miaopai.com")) {
            video_url = ParseVideo.parse_miaopai_com(this.url, this.html);
            if (ValidURL(video_url)) {
                return video_url;
            }
        }        
        if (domain.includes("pearvideo.com")) {
            video_url = ParseVideo.parse_pearvideo_com(this.url, this.html);
            if (ValidURL(video_url)) {
                return video_url;
            }            
        }
        video_url = ParseVideo.extract_all_video_urls(this.url, this.html);
        if (video_url !== null) {
            return video_url;
        }
        video_url = ParseVideo.extract_all_mp4_urls(this.url, this.html);
        if (video_url !== null) {
            return video_url;
        }
        return null;
    }

    // parse miaopai.com video e.g. https://miaopai.com/show/abcde.html
    // this is one of the simplest form and we can get it from URL
    static parse_miaopai_com(url, html) {
        let re = /.*miaopai\.com\/show\/(.*)\.html?$/i;
        let found = re.exec(url);
        if (found !== null) {
            return "http://gslb.miaopai.com/stream/" + found[1] + ".mp4";
        } 
        return null;
    }

    // extract all video_url in html e.g. "video_url": "https://aaaabbb.com/"
    static extract_all_video_urls(url, html) {
        let re = /['"]?video_url['"]?:\s*(['"])(https?:[^\s'",]+)\1/ig;
        let found = re.exec(html);
        let video_url = [];
        while (found !== null) {  
            let url = FixURL(found[2]);
            if (ValidURL(url)) {
                video_url.push(url);
            }
            found = re.exec(html);
        }
        return (video_url.length === 0) ? null :
               ( (video_url.length === 1) ? video_url[0] : video_url);
    }

    // parse pearvideo.com e.g. http://www.pearvideo.com/video_1050733
    static parse_pearvideo_com(url, html) {
        let video_url = [];
        let re = /([hsl]d|src)Url\s*=\s*[\"\']([^\"\']+)[\'\"]/ig;
        let found = re.exec(html);
        while (found !== null) {
            let tmp_url = FixURL(found[2]); 
            if (ValidURL(tmp_url)) {
                video_url.push(tmp_url);
            }
            found = re.exec(html);
        }        
        return (video_url.length === 0) ? null :
               ( (video_url.length === 1) ? video_url[0] : video_url);        
    }

    // extract all MP4 in html e.g. "mp4","url":"https://aabb.com"
    static extract_all_mp4_urls(url, html) {
        let re = /mp4[\'\"]\s*,\s*[\'\"]url[\'\"]\s*:\s*[\'\"]([^\"\']+)[\'\"]/ig;
        let found = re.exec(html);
        let video_url = [];
        while (found !== null) {  
            let url = FixURL(found[1]);
            if (ValidURL(url)) {
                video_url.push(url);
            }
            found = re.exec(html);
        }
        return (video_url.length === 0) ? null :
               ( (video_url.length === 1) ? video_url[0] : video_url);
    }
}

if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
    module.exports = {
        ParseVideo
    };
}

Screenshot

image.png

Roadmap

  1. Use async/await to replace Promise/Then
  2. Fix broken video parser due to video site changes e.g. ted.com
  3. Add more unit tests (increase code coverage)
  4. Support vimeo and other video sites
  5. Merge video segments (ts)

VIP Key Exclusive to Utopian

Please note, you can enter the VIP Key which allows you to call the server API in case the client video parser fails locally - this greatly unlocks video parser to many many other video sites.

image.png

The KEY is iamutopian


Enjoy and Steem On!

Vote for me or Set me as a witness Proxy - Every vote counts! - Thank you!

Your Vote is much appreciated, and every vote counts.

Check out My Witness Page

Support me and my work as a witness - witness thread by

  1. voting me here, or
  2. voting me as a witness proxy - let @justyy represent you.

Thank you! Some of My Contributions: SteemYY.com - SteemIt Tutorials, Robots, Tools and APIs and VPS Search Tool

Relevant Video Download Posts

Sort:  

Great plugin.

I was using something similar years ago on Firefox. It's always good to see unit tests, hope the project can maintain a good code coverage.

I see you have different parser logic on different domains.

It might be hard to maintain at some point if you want to add more parsers like this. Maybe modularize it will help. :)


Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]

Thank you for your review, @emrebeyler! Keep up the good work!

Hello! Your post has been resteemed and upvoted by @ilovecoding because we love coding! Keep up good work! Consider upvoting this comment to support the @ilovecoding and increase your future rewards! ^_^ Steem On!

Reply !stop to disable the comment. Thanks!

Hi @justyy!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server

Hey, @justyy!

Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!

Congratulations! This post has been upvoted from the communal account, @minnowsupport, by justyy - SteemYY.com from the Minnow Support Project. It's a witness project run by aggroed, ausbitbank, teamsteem, someguy123, neoxian, followbtcnews, and netuoso. The goal is to help Steemit grow by supporting Minnows. Please find us at the Peace, Abundance, and Liberty Network (PALnet) Discord Channel. It's a completely public and open space to all members of the Steemit community who voluntarily choose to be there.

If you would like to delegate to the Minnow Support Project you can do so by clicking on the following links: 50SP, 100SP, 250SP, 500SP, 1000SP, 5000SP.
Be sure to leave at least 50SP undelegated on your account.