'#FFFFFF', 'controlbar.icons'=>'rgba(255,255,255,0.8)', 'controlbar.iconsActive'=>'#FFFFFF', 'controlbar.background'=>'rgba(0,0,0,0)', 'timeslider.progress'=>'#F2F2F2', 'timeslider.rail'=>'rgba(255,255,255,0.3)', 'menus.text'=>'rgba(255,255,255,0.8)', 'menus.textActive'=>'#FFFFFF', 'menus.background'=>'#333333', 'tooltips.text'=>'#000000', 'tooltips.background'=>'#FFFFFF' ); /** * 激活插件方法,如果激活失败,直接抛出异常 * * @access public * @return void * @throws Typecho_Plugin_Exception */ public static function activate() { Typecho_Plugin::factory('Widget_Abstract_Contents')->contentEx = array('JWPlayer_Plugin','jwparse'); Typecho_Plugin::factory('Widget_Abstract_Contents')->excerpt = array('JWPlayer_Plugin','txtparse'); Typecho_Plugin::factory('admin/write-post.php')->bottom = array('JWPlayer_Plugin','jwbutton'); Typecho_Plugin::factory('admin/write-page.php')->bottom = array('JWPlayer_Plugin','jwbutton'); /* 模版调用钩子 例: jwplayer(array('file'=>'http://test.mp4')); ?> 参数为键值对 */ Typecho_Plugin::factory('Widget_Archive')->callJwplayer = array('JWPlayer_Plugin', 'output'); } /** * 禁用插件方法,如果禁用失败,直接抛出异常 * * @static * @access public * @return void * @throws Typecho_Plugin_Exception */ public static function deactivate(){} /** * 获取插件配置面板 * * @access public * @param Typecho_Widget_Helper_Form $form 配置面板 * @return void */ public static function config(Typecho_Widget_Helper_Form $form) { $options = Helper::options(); $security = Helper::security(); $plugurl = $options->pluginUrl; //格式化默认配色 $cset = array(); $cs = Json::encode(self::$skincs); if (isset($options->plugins['activated']['JWPlayer'])) { $settings = $options->plugin('JWPlayer'); $cset = Json::decode($settings->jwcolors,true); } //输出面板效果 echo '
'._t('编辑文章或页面写入%s文件地址%s即可显示影音播放器, ','<jw>','</jw>').' '._t('多个文件连播可用%s号隔开,',',').'
'._t('参数间用%s号隔开, 支持%s等[参数列表]. 示例','|','width(宽度)height(高度)image(封面)title(标题)').'
<jw>http://a.mp4,http://b.flv|
image=http://aa.jpg,http://bb.png|
title=aaa,bbb|
autostart=false|
repeat=true</jw>
'._t('参数').' '._t('默认').' '._t('说明').'
image - '._t('封面图片url,播放音频时全程显示。').'
title - '._t('标题文字,封面窗口和列表项显示。').'
description - '._t('描述文字,封面窗口显示。').'
tracks - '._t('字幕文件url,支持WebVTT/SRT/DFXP格式。').'
width 640 '._t('宽度像素值(整数)或百分数。').'
height 360 '._t('高度像素值(整数),40为音频模式高度。').'
aspectratio - '._t('宽高比如%s,与百分数width锁定画面比例。','16:9').'
autostart false '._t('自动播放,为%s时开启。','true').'
repeat false '._t('循环播放,为%s时开启。','true').'
mute false '._t('静音,为%s时开启。','true').'
preload metadata '._t('预加载,%s最少/%s禁用/%s自动。','metadata','none','auto').'
abouttext - '._t('右击菜单文字,可覆盖插件提示原文链接设置。').'
aboutlink - '._t('右击菜单链接,同上。').'
stretching uniform '._t('画面适应方法,可覆盖插件统一设置,对应值%s固定/%s缩放/%s裁切/%s拉伸。','none','uniform','fill','exactfit').'
minDvrWindow 120 '._t('(直播流)回放模式判定,默认检测到120个缓存单元开启,设置为0可强制显示录像控制按钮。','monoscopic',',').'
stereomode - '._t('VR全景模式解析,使用值%s即为360度自由旋转,多个视频可重复该值用%s号分隔。','monoscopic',',').'
cast - '._t('投屏模式,没有值,留空即可自动检测%s或%s设备请求并显示相关按钮。','Google Cast','Apple Airplay').'
'; $skin = new Typecho_Widget_Helper_Form_Element_Select('skin', array( 'controlbar.text'=>_t('控制栏文本'), 'controlbar.icons'=>_t('图标'), 'controlbar.iconsActive'=>_t('图标(悬停)'), 'controlbar.background'=>_t('控制栏背景'), 'timeslider.progress'=>_t('进度条'), 'timeslider.rail'=>_t('进度条(剩余)'), 'menus.text'=>_t('菜单文本'), 'menus.textActive'=>_t('菜单文本(悬停)'), 'menus.background'=>_t('菜单背景'), 'tooltips.text'=>_t('提示文字'), 'tooltips.background'=>_t('提示文字背景') ), 'controlbar.text','
'._t('视频标题文本(控制栏)').'
'._t('视频描述文本(控制栏)').'
 
下一个
'._t('视频标题文本(菜单)').'
00:25
下一个: Cycle Tour: Tuscany to Umbria
00:15
00:09
00:50
选项
全屏
'._t('定制配色预览').' ⇡
',_t('RGBA末位小数0-1代表透明度可手动修改')); $skin->input->setAttribute('id','selector'); $form->addInput($skin); if (Typecho_Request::getInstance()->is('action=resetskin') && isset($options->plugins['activated']['JWPlayer'])) { $security->protect(); Helper::configPlugin('JWPlayer',array('jwcolors'=>$cs)); Typecho_Response::getInstance()->goBack(); } //重置动作按钮 $resetskin = new Typecho_Widget_Helper_Form_Element_Submit(); $resetskin->value(_t('重置')); $resetskin->input->setAttribute('class','btn btn-xs'); $resetskin->input->setAttribute('formaction',$security->getAdminUrl('options-plugin.php?config=JWPlayer&action=resetskin')); $form->addItem($resetskin); $stretch = new Typecho_Widget_Helper_Form_Element_Select('stretch', array('none'=>_t('固定'),''=>_t('缩放'),'fill'=>_t('裁切'),'exactfit'=>_t('拉伸')),'',_t('画面适应方法'),_t('视频尺寸与播放器尺寸不同时的修正方式')); $form->addInput($stretch); $encode = new Typecho_Widget_Helper_Form_Element_Radio('encode', array(1=>_t('是'),0=>_t('否')),0,_t('加密视频地址'),_t('是否隐藏文件url使其在源码中显示为乱码')); $form->addInput($encode); $info = new Typecho_Widget_Helper_Form_Element_Radio('info', array(1=>_t('是'),0=>_t('否')),0,_t('隐藏标题描述'),_t('是否在窗口显示title与description参数信息')); $form->addInput($info); $about = new Typecho_Widget_Helper_Form_Element_Radio('about', array(1=>_t('是'),0=>_t('否')),0,_t('提示原文链接'),_t('右击窗口时是否显示原文链接, 参数可覆盖')); $form->addInput($about); $tedge = new Typecho_Widget_Helper_Form_Element_Select('tedge', array(''=>_t('默认'),'dropshadow'=>_t('下阴影'),'depressed'=>_t('上阴影'),'uniform'=>_t('深描边'),'raised'=>_t('浅描边')),'',_t('外挂字幕效果')); $form->addInput($tedge); $tsize = new Typecho_Widget_Helper_Form_Element_Text('tsize',NULL,'15',_t('字体大小(单位px, 不用填写): ')); $tsize->input->setAttribute('class','text-s'); $tsize->label->setAttribute('style','position:absolute;color:#999;font-weight:normal;bottom:10px;left:82px;'); $tsize->input->setAttribute('style','position:absolute;width:38px;bottom:13px;left:258px;'); $tsize->setAttribute('style','position:relative'); $form->addInput($tsize->addRule('isFloat')); $logo = new Typecho_Widget_Helper_Form_Element_Text('logo', NULL,'',_t('logo水印图片'),_t('填写完整的图片url, 24位透明png效果最佳')); $logo->input->setAttribute('class','w-60'); $form->addInput($logo->addRule('url',_t('请输入合法的图片地址'))); $llink = new Typecho_Widget_Helper_Form_Element_Text('llink', NULL,'',_t('logo链接地址'),_t('填写点击水印图片将跳转到的目标链接url')); $llink->input->setAttribute('class','w-60'); $form->addInput($llink->addRule('url',_t('请输入合法的链接地址'))); $lpos = new Typecho_Widget_Helper_Form_Element_Select('lpos', array(''=>_t('右上角'),'top-left'=>_t('左上角'),'bottom-right'=>_t('右下角'),'bottom-left'=>_t('左下角'),'control-bar'=>_t('控制条')),'',_t('logo显示位置')); $form->addInput($lpos); $margin = new Typecho_Widget_Helper_Form_Element_Text('margin',NULL,'8',_t('边距(单位px, 不用填写): ')); $margin->input->setAttribute('class','text-s'); $margin->label->setAttribute('style','position:absolute;color:#999;font-weight:normal;bottom:10px;left:82px;'); $margin->input->setAttribute('style','position:absolute;width:38px;bottom:13px;left:230px;'); $margin->setAttribute('style','position:relative'); $form->addInput($margin->addRule('isFloat')); $hide = new Typecho_Widget_Helper_Form_Element_Checkbox('hide', array(1=>_t('自动隐藏')),NULL,''); $hide->label->setAttribute('style','position:absolute;color:#999;font-weight:normal;bottom:10px;left:279px;'); $hide->input->setAttribute('style','position:absolute;bottom:4px;left:60px;'); $hide->setAttribute('style','position:relative'); $form->addInput($hide); $share = new Typecho_Widget_Helper_Form_Element_Checkbox('share', array('weibo'=>_t('新浪微博'),'qzone'=>_t('QQ空间'),'tieba'=>_t('百度贴吧'),'douban'=>_t('豆瓣网'),'renren'=>_t('人人网'),'facebook'=>_t('Facebook'),'twitter'=>_t('Twitter')),NULL,_t('分享功能按钮')); $form->addInput($share); //配色保存隐藏域 $jwcolors = new Typecho_Widget_Helper_Form_Element_Hidden('jwcolors',NULL,$cs,NULL); $jwcolors->input->setAttribute('id','jwcolors'); $form->addInput($jwcolors); } /** * 个人用户的配置面板 * * @access public * @param Typecho_Widget_Helper_Form $form * @return void */ public static function personalConfig(Typecho_Widget_Helper_Form $form){} /** * 内容标签替换 * * @param string $content * @return string */ public static function jwparse($content,$widget,$lastResult) { $content = empty($lastResult) ? $content : $lastResult; $version = explode('/',Helper::options()->version); $sign = ''; $pattern = '/<(jw)>(.*?)<\/\\1>/si'; //markdown fix if ($version['1']=='17.10.30' && $widget->isMarkdown && !stripos($content,'')) { $sign = '</jw>'; $pattern = '/<(jw)>(.*?)<\/\\1>/si'; $content = str_replace(';/jw>',$sign,$content); } if ($widget instanceof Widget_Archive && !$widget->request->feed && false!==stripos($content,$sign)) { $content = preg_replace_callback($pattern,array('JWPlayer_Plugin','callback'),$content); } return $content; } /** * 摘要文本替换 * * @param string $text * @return string */ public static function txtparse($text,$widget,$lastResult) { $text = empty($lastResult) ? $text : $lastResult; if ($widget instanceof Widget_Archive && false!==stripos($text,'')) { $text = preg_replace('/<(jw)>(.*?)<\/\\1>/si',_t(' [影音片段: 请查看原文播放] '),$text); } return $text; } /** * 参数回调解析 * * @param array $match * @return string */ public static function callback($match) { $settings = Helper::options()->plugin('JWPlayer'); $data = array(); $lists = array(); //过滤html标签 $codes = trim(Typecho_Common::stripTags($match['2'])); if (strpos($codes,'<')) $codes = substr($codes,0,-3); //markdown fix $atts = strpos($codes,'|') ? explode('|',$codes) : array($codes); $file = trim(array_shift($atts)); $files = explode(',',$file); $fnum = count($files); $qfiles = array(); $qnum = ''; $source = ''; $quality = array(); $vr = strpos($codes,'stereomode'); $dvr = strpos($codes,'minDvrWindow'); //处理视频参数 for ($i=0;$i<$fnum;++$i) { //处理画质参数 if ($files[$i]) { $qfiles = explode(';',$files[$i]); $qnum = count($qfiles); //准备画质数组 for ($j=0;$j<$qnum;++$j) { $source = trim($qfiles[$j]); if (false!==strpos($source,'^')) { $metas = explode('^',$source); $quality[$j]['label'] = $metas['0']; $quality[$j]['file'] = self::encode($metas['1']); if (isset($metas['2'])) { $quality[$j]['type'] = $metas['2']; } } else { $quality[$j]['file'] = self::encode($source); //预设3种清晰度 $quality['0']['label'] = _t('标清'); if (isset($quality['1'])) { $quality['1']['label'] = _t('高清'); } if (isset($quality['2'])) { $quality['2']['label'] = _t('超清'); } } } } //多文件画质参数 if ($fnum>1 || $vr || $dvr) { if ($qnum>1) { $lists[$i]['sources'] = $quality; } else { $lists[$i]['file'] = self::encode(trim($files[$i])); } } } //单文件画质参数 if ($fnum<=1) { if ($qnum>1) { $data['sources'] = $quality; } else { $data['file'] = self::encode($file); } } $pair = array(); $key = ''; $val = ''; $listkey = false; $vals = array(); $keyvals = ''; $tfiles = array(); $tnum = ''; $track = ''; $subs = array(); //处理其他参数 foreach ($atts as $att) { $pair = explode('=',$att); $key = trim($pair['0']); $val = isset($pair['1']) ? trim($pair['1']) : ''; $data[$key] = $val; $listkey = in_array($key,array('image','title','description','tracks','stereomode','minDvrWindow')); if ($listkey) { $vals[$key] = explode(',',$data[$key]); } //处理列表参数 for ($i=0;$i<$fnum;++$i) { if (isset($vals[$key][$i])) { $keyvals = trim($vals[$key][$i]); //处理字幕参数 if ($key=='tracks' && $keyvals) { $tfiles = explode(';',$keyvals); $tnum = count($tfiles); //准备语种数组 for ($j=0;$j<$tnum;++$j) { $track = trim($tfiles[$j]); if (false!==strpos($track,'^')) { $infos = explode('^',$track); $subs[$j]['label'] = $infos['0']; $subs[$j]['file'] = $infos['1']; if (isset($infos['2'])) { $subs[$j]['kind'] = $infos['2']; } } else { $subs[$j]['file'] = $track; //预设中英字幕 $subs['0']['label'] = _t('中文'); if (isset($subs['1'])) { $subs['1']['label'] = _t('英文'); } } } if ($tnum<=1) { array_splice($subs,1); } //多文件字幕参数 if ($fnum>1) { unset($data['tracks']); $lists[$i]['tracks'] = $subs; } //多文件其他参数 } elseif ($fnum>1 || $vr || $dvr) { unset($data[$key]); $lists[$i][$key] = $keyvals; } //对应自动置空 } elseif ($listkey) { $lists[$i][$key] = ''; } } //单文件字幕参数 if ($key=='tracks') { if ($fnum<=1) { $data['tracks'] = $subs; } //字幕效果选项 $tsize = $settings->tsize; if ($tsize && $tsize!=='15') { $data['captions']['fontSize'] = $tsize; } if ($settings->tedge) { $data['captions']['backgroundOpacity'] = '0'; $data['captions']['edgeStyle'] = $settings->tedge; } } } if (preg_match("/(\.rss|\.json)/i",$file)) { unset($data['file']); $data['playlist'] = self::encode($file); } elseif ($lists) { $data['playlist'] = $lists; } return self::output('',array($data,true)); } /** * 输出播放器实例 * * @access public * @param array $params 实例参数 * @return string */ public static function output($widget,array $params) { $options = Helper::options(); $url = $options->pluginUrl.'/JWPlayer/player/'; $ids = "jwplayer_".++self::$id; //处理实例参数 $jwsets = array(); $jwsets = isset($params['0']) && is_array($params['0']) ? $params['0'] : $jwsets; $iscall = false; $iscall = !empty($params['1']) && is_bool($params['1']) ? $params['1'] : $iscall; $jwsets = Json::encode($jwsets+self::getsets()); //播放器实例代码 $output = ''; //不重复加载 $output .= '
'._t('播放器载入中...').'
'; $output .= ''; //模版输出判断 if ($iscall) { return $output; } else { echo $output; } } /** * 输出插件设置 * * @return array */ public static function getsets() { $options = Helper::options(); $skincs = self::$skincs; $sets =array(); if (isset($options->plugins['activated']['JWPlayer'])) { $settings = $options->plugin('JWPlayer'); $share = $settings->share; $stretch = $settings->stretch; $csets = Json::decode($settings->jwcolors,true); $archive = Typecho_Widget::widget('Widget_Archive'); $url = $archive->permalink; $key = array(); //输出配色参数 foreach ($csets as $keys=>$cs) { if ($skincs[''.$keys.'']!==$cs) { $key = explode('.',$keys); $sets['skin'][''.$key['0'].''][''.$key['1'].''] = $cs; } } if ($stretch) { $sets['stretching'] = $stretch; } if ($settings->info) { $sets['displaytitle'] = 'false'; $sets['displaydescription'] = 'false'; } if ($settings->about) { $sets['abouttext'] = _t('原文链接: ').$archive->title; $sets['aboutlink'] = $url; } if ($share) { $sets['sharing']['heading'] = _t('分享'); $sets['sharing']['link'] = $url; array_push($share,'email'); $sets['sharing']['sites'] = $share; } //输出logo参数 $logo = $settings->logo; $llink = $settings->llink; $lops = $settings->lpos; $margin = $settings->margin; if ($logo) { $sets['logo']['file'] = $logo; if ($llink) { $sets['logo']['link'] = $llink; } if ($lops) { $sets['logo']['position'] = $lops; } if (false!==$margin && $margin!=='8') { $sets['logo']['margin'] = $margin; } if ($settings->hide) { $sets['logo']['hide'] = true; } } } return $sets+self::locals(); } /** * 加密视频地址 * * @param string $string * @return string */ private static function encode($string) { if (Helper::options()->plugin('JWPlayer')->encode) { $string = rawurlencode($string); $ntexto = ''; $codekey = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-'; for ($i=0;$iarray( 'rewind'=>_t('后退10秒'), 'settings'=>_t('选项'), 'cc'=>_t('字幕'), 'hd'=>_t('画质'), 'fullscreen'=>_t('全屏'), 'videoInfo'=>_t('查看媒体信息'), 'copied'=>_t('复制成功'), 'playlist'=>_t('列表'), 'nextUp'=>_t('下一个'), 'liveBroadcast'=>_t('在线直播') )); } /** * 输出编辑器按钮 * * @access public * @return void */ public static function jwbutton() { ?>