├── package.json ├── LICENSE ├── README.md └── index.js /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hexo-tag-dplayer", 3 | "version": "0.3.3", 4 | "description": "Embed dplayer in Hexo posts/pages", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "video", 11 | "danmaku", 12 | "hexo", 13 | "tag", 14 | "player", 15 | "dplayer" 16 | ], 17 | "author": "dixyes", 18 | "license": "MIT", 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/MoePlayer/hexo-tag-dplayer.git" 22 | }, 23 | "bugs": { 24 | "url": "https://github.com/MoePlayer/hexo-tag-dplayer/issues" 25 | }, 26 | "homepage": "https://github.com/MoePlayer/hexo-tag-dplayer#readme", 27 | "dependencies": { 28 | "dplayer": "^1.6.0", 29 | "hexo-log": "^0.2.0", 30 | "hexo-fs": "^0.2.2", 31 | "hexo-util": "^0.6.2" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2017 Yun Dou (dixyes) 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # hexo-tag-dplayer 2 | 本项目是将diygod的dplayer运行在hexo的插件 3 | 4 | 感谢关注这个插件的人们,感谢aplayer的hexo插件作者@grzhan,感谢A or D播放器作者@Diygod 5 | 6 | 感谢插件豆子@dixyes的移植 7 | 8 | 借鉴项目:https://github.com/grzhan/hexo-tag-aplayer 9 | 10 | 这个项目的两个维护者一个只会卖萌,一个又沉迷屁股(这是豆子) 11 | 12 | 所以有什么bug很长时间没解决的,请谅解 13 | 14 | 如果您能修复的话,也希望请您修复一下提交个pr什么的,祝君安康 15 | 16 | 17 | --------------------------------------------- 18 | 19 | 20 | 21 | Embed DPlayer([https://github.com/DIYgod/DPlayer](https://github.com/DIYgod/DPlayer)) in Hexo posts/pages. 22 | 23 | [Hexo Demo](https://morz.org/archives/2016-09-09/%E8%A7%86%E9%A2%91%E5%88%86%E4%BA%AB-%E3%80%90%E6%9D%B1%E6%96%B9Vocal%E3%80%91%E8%8A%B1%E6%98%A0%E3%80%8C%E3%82%BF%E3%83%9E%E3%82%B7%E3%82%A4%E3%83%8E%E3%83%8F%E3%83%8A%E3%80%8D-%E5%87%8B%E5%8F%B6%E6%A3%95-%E3%80%8CSubbed%E3%80%8D.html) 24 | 25 | ![plugin screenshot](https://video-cache.morz.org/data/img/dplayer-1.jpg) 26 | 27 | 28 | 29 | ## npm install 30 | 31 | npm install hexo-tag-dplayer --save 32 | 33 | ## Usage 34 | 35 | {% dplayer key=value ... %} 36 | 37 | key can be 38 | 39 | dplayer options: 40 | 'autoplay', 'loop', 'screenshot', 'hotkey', 'mutex', 'dmunlimited' : bool options, use "yes" "y" "true" "1" "on" or just without value to enable 41 | 'preload', 'theme', 'lang', 'logo', 'url', 'pic', 'thumbnails', 'vidtype', 'suburl', 'subtype', 'subbottom', 'subcolor', 'subcolor', 'id', 'api', 'token', 'addition', 'dmuser' : string arguments 42 | 'volume', 'maximum' : number arguments 43 | container options: 44 | 'width', 'height' : string, used in container element style 45 | other: 46 | 'code' : value of this key will be append to script tag 47 | 48 | arguments to DPlayer options mapping: 49 | 50 | { 51 | container: "you needn't set this", 52 | autoplay: 'autoplay', 53 | theme: 'theme', 54 | loop: 'loop', 55 | lang: 'lang', 56 | screenshot: 'screenshot', 57 | hotkey: 'hotkey', 58 | preload: 'preload', 59 | logo: 'logo', 60 | volume: 'volume', 61 | mutex: 'mutex', 62 | video: { 63 | url: 'url', 64 | pic: 'pic', 65 | thumbnails: 'thumbnails', 66 | type: 'vidtype', 67 | }, 68 | subtitle: { 69 | url: 'suburl', 70 | type: 'subtype', 71 | fontSize: 'subsize', 72 | bottom: 'subbottom', 73 | color: 'subcolor', 74 | }, 75 | danmaku: { 76 | id: 'id', 77 | api: 'api', 78 | token: 'token', 79 | maximum: 'maximum', 80 | addition: ['addition'], 81 | user: 'dmuser', 82 | unlimited: 'dmunlimited', 83 | }, 84 | icons: 'icons', 85 | contextmenu: 'menu', 86 | } 87 | 88 | see dplayer documents for more infomation. 89 | 90 | for example: 91 | 92 | {% dplayer "url=https://moeplayer.b0.upaiyun.com/dplayer/hikarunara.mp4" "addition=https://dplayer.daoapp.io/bilibili?aid=4157142" "api=https://api.prprpr.me/dplayer/" "pic=https://moeplayer.b0.upaiyun.com/dplayer/hikarunara.jpg" "id=9E2E3368B56CDBB4" "loop=yes" "theme=#FADFA3" "autoplay=false" "token=tokendemo" %} 93 | {% dplayer 'url=some.mp4' "id=someid" "api=https://api.prprpr.me/dplayer/" "addition=/some.json" 'code=player.on("loadstart",function(){console.log("loadstart")})' "autoplay" %} 94 | 95 | 96 | ## PJAX compatible 97 | 98 | ```js 99 | $(document).on('pjax:start', function () { 100 | if (window.dplayers) { 101 | for (let i = 0; i < window.dplayers.length; i++) { 102 | window.dplayers[i].destroy(); 103 | } 104 | window.dplayers = []; 105 | } 106 | }); 107 | ``` 108 | 109 | ## Customization 110 | 111 | You can modify variables `scriptDir`(default: "/assets/js/" ) and `styleDir`(default: "/assets/css/") in `index.js` according to your blog's directory structure. 112 | 113 | or just use _config.yml configuration: 114 | 115 | # on _config.yml of hexo-site 116 | hexo-tag-dplayer: 117 | js_path: /path/to/your/default/path 118 | css_path: /sth 119 | default: #default tag argument 120 | id: somedefid # equals to setting id=somedefid in all {%dplayer%} tags 121 | api: https://api.prprpr.me/dplayer/ 122 | #and other options... 123 | 124 | ## Issue 125 | 126 | If any issue occurs, tell me via issue, use a hexo raw tag like below to use dplayer: 127 | 128 | {% raw %} 129 |
130 | 131 | 174 | {% endraw %} 175 | 176 | see [DPlayer](https://github.com/DIYgod/DPlayer) for usage detail 177 | 178 | ## Todo 179 | 180 | - [x] Publish it to the [hexo plugin list](https://hexo.io/plugins) and npm 181 | 182 | ## LICENSE 183 | 184 | MIT 185 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * hexo-tag-dplayer 3 | * Embed DPlayer(https://github.com/DIYgod/DPlayer) in Hexo posts/pages. 4 | * Syntax: 5 | * {% dplayer key=value ... %} 6 | */ 7 | 'use strict'; 8 | 9 | const fs = require('hexo-fs'), 10 | util = require('hexo-util'), 11 | log = require('hexo-log')({name:"hexo-tag-dplayer",debug:false}), // logger 12 | urlFn = require('url'), 13 | path = require('path'), 14 | srcDir = path.dirname(require.resolve('dplayer')), 15 | scriptDir = '/assets/js/', // default script directories 16 | styleDir = '/assets/css/', 17 | files = [ 18 | ['DPlayer.min.css', styleDir], 19 | ['DPlayer.min.js', scriptDir], 20 | // some map for debug use 21 | //['DPlayer.min.css.map', styleDir], 22 | //['DPlayer.min.js.map', scriptDir], 23 | // if there be any other dplayer file 24 | //['someDplayerFile.xxx', targetDir], 25 | ]; 26 | 27 | String.prototype.replaceAll = function(search, replacement) { 28 | var target = this; 29 | //log.debug(target.split(search)) 30 | return target.split(search).join(replacement); 31 | }; 32 | 33 | var counter = 0, 34 | conf = hexo.config['hexo-tag-dplayer'] || {}, 35 | tbIns=[]; 36 | 37 | 38 | if (!conf.cdn){ 39 | files.forEach(item => { 40 | var destPath = item[1], filePath = path.join(srcDir, item[0]); 41 | if (item[1] === scriptDir){ 42 | destPath = conf.js_path || item[1]; 43 | } else if (item[1] === styleDir){ 44 | destPath = conf.css_path || item[1]; 45 | } 46 | fs.access(filePath, (fs.constants || fs).R_OK , (err) => { 47 | if(err){ 48 | log.info(item[0]+' is not found in this version of dplayer, skip it.'); 49 | } else { 50 | hexo.extend.generator.register(path.posix.join(destPath, item[0]), (_) => { 51 | return { 52 | path: path.relative(hexo.config.root, path.posix.join(destPath, item[0])), 53 | data: function() { 54 | return fs.createReadStream(filePath); 55 | } 56 | } 57 | }); 58 | tbIns.push(path.posix.join(destPath, item[0])); 59 | } 60 | }) 61 | }) 62 | } 63 | 64 | hexo.extend.filter.register('after_render:html', (str, data) => { 65 | if(str.includes('') && str.includes('class="dplayer hexo-tag-dplayer-mark"')){ //make sure dplayer used in final html 66 | log.debug("got page that dplayer used"); 67 | var target = conf.cdn || tbIns, 68 | s = str; 69 | target.forEach(item => { 70 | //console.log(item); 71 | if (item.endsWith('.css')) { 72 | var tag = util.htmlTag('link', {rel: 'stylesheet', type: 'text/css', href: item }); 73 | s = s.replace(/<\/head>/, tag + ''); 74 | }else if (item.endsWith('.js')) { 75 | var tag = util.htmlTag('script', {src: item}, ''); 76 | s = s.replace(/<\/head>/, tag + ''); 77 | }else if (item.endsWith('.map')) { 78 | //do nothing when sorce map used 79 | }else{ 80 | log.info('unknown file type of dplayer file:'+item); 81 | } 82 | }) 83 | //log.debug('postfilter: '+s); 84 | return s; 85 | } 86 | return str; 87 | }) 88 | 89 | 90 | 91 | // {% dplayer key=value ... %} 92 | hexo.extend.tag.register('dplayer', function (args) { 93 | 94 | //hexo.locals.get('posts').forEach(console.log) 95 | 96 | const def = conf['default'] || {}; 97 | //log.debug("default setting:"+def) 98 | 99 | var id = 'dplayer' + (counter++), opt = {}; 100 | 101 | for (var i in args) { 102 | var k = args[i].split('=')[0], 103 | v = args[i].split("=").length < 2 ? "true" : args[i].slice(args[i].indexOf('=')+1); 104 | if (['autoplay', 'loop', 'screenshot', 'hotkey', 'mutex', 'dmunlimited'].indexOf(k) >= 0){ 105 | // bool 106 | v = v.toLowerCase(); 107 | opt[k] = ['true', 'yes', '1', 'y', 'on', ''].indexOf(v) >= 0; 108 | } else if (['preload', 'theme', 'lang', 'logo', 'url', 'pic', 'thumbnails', 'vidtype', 'suburl', 'subtype', 'subbottom', 'subcolor', 'subcolor', 'id', 'api', 'token', 'addition', 'dmuser', 'width', 'height', 'code'].indexOf(k) >= 0){ 109 | // string 110 | opt[k] = v.toString(); 111 | } else if (['volume', 'maximum'].indexOf(k) >= 0){ 112 | // number 113 | opt[k] = Number(v) || undefined; 114 | } else if (['yet not implemented'].indexOf(k) >= 0){ 115 | // native 116 | continue; 117 | } 118 | } 119 | 120 | const width = opt.width || def.width, 121 | height = opt.height || def.height; 122 | var url = opt.url || def.url; 123 | var raw = '
'; 124 | if(url != undefined){ 125 | if (hexo.config['post_asset_folder'] == true ){ 126 | //for #10, if post_asset_folder is enable, regard url as relative url 127 | if (! (url.startsWith('https://') || url.startsWith('http://') || url.startsWith('/'))){ 128 | var PostAsset = hexo.model('PostAsset'); 129 | var asset = PostAsset.findOne({post: this._id, slug: url}); 130 | if (!asset) return 'bad asset path...'; 131 | opt.url = urlFn.resolve(hexo.config.root, asset.path); 132 | } 133 | } 134 | raw += ''; 191 | //console.log(opt.code,def.code,(opt.code || def.code || '')); 192 | } 193 | else{ 194 | raw += '

no url specified, no dplayer _(:3」∠)_

'; 195 | } 196 | return raw; 197 | }); 198 | --------------------------------------------------------------------------------