js / 学习 · 2021年8月25日

node+electron,下载

初始化项目;

npm init -y

安装备种包;

npm install electron –save-dev

npm install electron-builder –save-dev 。用来打包

npm install fs -save 。流文件操作

npm install request -save 。请求

新建 index.js index.html文件

index.js

const { app, BrowserWindow,Menu } = require('electron')



function createWindow() {
    Menu.setApplicationMenu(null)
    const win = new BrowserWindow({
        width: 900,
        height: 600,
        webPreferences: {
            nodeIntegration: true,//
            contextIsolation: false,//渲染进程用node模块
            enableRemoteModule: true//渲染进程用electron的remote
        }
    })

    win.loadFile('index.html')
}

app.whenReady().then(() => {
    createWindow()

    app.on('activate', () => {
        if (BrowserWindow.getAllWindows().length === 0) {
            createWindow()
        }
    })
})

app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        app.quit()
    }
})

index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>视频处理</title>
</head>
<style>
    * {
        margin: 0;
        padding: 0;
        list-style: none;
    }

    .m {
        margin: 20px;
        width: 800px;
        height: auto;
    }

    .nav {
        height: 40px;
    }

    .nav ul li {
        float: left;
        width: 80px;
        height: 40px;
        margin: 0 2px;
        border-radius: 6px;
        line-height: 40px;
        text-align: center;
        background: rgb(143, 168, 206);
        color: #fff;
        cursor: pointer;
        font-weight: 600;
    }

    .nav ul li:hover {
        background: rgb(16, 160, 124);
    }

    .container {
        width: 800px;
        height: auto;
    }



    .con {
        position: absolute;
        width: 800px;
        height: 500px;
        margin: 6px 2px;
        padding: 2px;
        /* border: 1px solid #000; */
    }

    .con input[type="text"] {
        margin: 4px 0;
        width: 400px;
        height: 24px;
    }

    .con input[type="button"] {
        width: 80px;
        height: 28px;
        background: rgb(170, 195, 231);
        cursor: pointer;
        color: rgb(255, 255, 255);
        font-weight: 600;
        border-radius: 4px;
    }

    .con input[type="button"]:hover {
        background: rgb(16, 160, 124);
    }


    .r1 {
        display: flex;
        flex-direction: row;
    }

    .r2 {
        display: flex;
        flex-direction: column;
    }

    .selecta {
        border-bottom: 2px solid rgb(199, 88, 184);
        box-shadow: 1px 1px 2px 1px bisque;
    }

    .btn10 {
        margin: 0 4px;
        margin-top: 4px;
    }

    .btn11 {
        margin: 4px 4px;
    }

    .loading {
        width: 80px;
        height: 24px;
    }

    .loading span {
        display: inline-block;
        width: 4px;
        height: 24px;
        border-radius: 2px;
        background: rgb(144, 238, 214);
        animation: load 1s ease infinite;
    }

    @keyframes load {

        0%,
        100% {
            height: 24px;
            background: rgb(144, 238, 233);
        }

        50% {
            height: 24px;
            margin: -12px 0;
            background: lightblue;
        }
    }

    .loading span:nth-child(2) {
        animation-delay: 0.2s;
    }

    .loading span:nth-child(3) {
        animation-delay: 0.4s;
    }

    .loading span:nth-child(4) {
        animation-delay: 0.6s;
    }

    .loading span:nth-child(5) {
        animation-delay: 0.8s;
    }

    .con input[type="time"] {
        margin: 2px 2px;
        width: 90px;
        height: 22px;
    }

    .tss {
        font-size: 14px;
    }
</style>

<body>
    <div class="m">
        <div class="nav" id="tab">
            <ul>
                <li class="selecta" onclick="swtabs(0)">下载</li>
  </ul>
        </div>
</div>
    <script>
const fs = require('fs')
const path = require('path')
const request = require('request')

const { dialog } = require("electron").remote
//选择
$('btn10').addEventListener('click', function (e) {
            dialog.showSaveDialog(null, {
                defaultPath: "download.mp4",
                properties: ["openFile"],
            }).then(res => {
                console.log(res.filePath)
                $('txt10').value = res.filePath
            }).catch(err => {
                console.log(err)
                dialog.showMessageBox(null,
                    {
                        message: err,
                        type: "info"
                    })
            })
        })
        // 下载
        $('btn11').addEventListener('click', function (e) {
            let url = $('urltxt10').value
            let p = $('txt10').value
            if (url.trim().length != 0 && p.trim().length != 0) {//不为空
                $('btn11').disabled = true
                $('loading1').className = "loading"//显示加载效果

                //请求参数
                opt2 = {
                    uri: url,
                    headers: {
                       
                        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
                    }
                }

                let fname = new Date().valueOf() //Array对象的原始值

                let stream = fs.createWriteStream(p)//写入流文件

                let reqs = request(opt2).on('error', errs => {//请求下载错误
                    // console.log(errs)
                    $('txt12').value = errs
                    $('btn11').disabled = false
                    $('loading1').className = ""
                }).on('response', (response) => {//请求返回

                    let totlev = response.headers['content-length']
                    let rangdata = 0
                    response.on('data', (data) => {//返回数据

                        rangdata += Buffer.byteLength(data)//下载数据长度
                        $('txt12').value = "进度:" + (rangdata / totlev * 100).toFixed() + "%"

                    })

                }).pipe(stream)//管道写入
                    .on('close', function (err) {
                        console.log(err)
                        console.log('done')
                        // console.log("已下载")
                        $('btn11').disabled = false
                        $('loading1').className = ""
                        if (err) {
                            dialog.showMessageBox(null,
                                {
                                    message: err,
                                    type: "info"
                                })
                        } else {
                            dialog.showMessageBox(null,
                                {
                                    message: "已下载",
                                    type: "info"
                                })
                        }
                    })
            } else {
                dialog.showMessageBox(null,
                    {
                        message: "内容不能为空",
                        type: "info"
                    })
            }
        })
   </script>
</body>

</html>

package.json配置文件。下面分别是配置运行和打包。

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "electron .",
    "dist": "electron-builder --win --ia32"
  },

运行如图

预览