`

百度UEditor编辑器视频相关bug汇总和稳定解决方案

 
阅读更多

百度UEditor编辑器的视频是个很头疼的问题,从昨晚到今天折腾了一天,也看了不少帖子,很多都是只治标不治本,而且有很多改法也是忽略本质,不过受大神启发,自己还是琢磨出来了。

百度UEditor编辑器的视频主要容易出现几个问题:

1、添加视频之后,点击查看html源码,结果丢失src后面的链接;

2、视屏编辑器预览BUG;

3、添加视屏后百度编辑器预览BUG;

这三个问题,本文将分别讲解:

一、丢失src后面的链接问题


这个问题其实网上有很多大神已经找到关键点了:白名单!没错,就是这个!

这个问题可以参考这个两个帖子:

http://blog.csdn.net/eunyeon/article/details/52964152

https://github.com/fex-team/ueditor/pull/2957/commits/d4b875ce165b3225929496c2d85848afbff0deeb?diff=split

其实就是在ueditor.config.js的白名单whitList:里面加上src字段,这样就不会被过滤了。

 

[html] view plain copy
  1. <span style="font-size:18px;">img:    ['src', 'alt', 'title', 'width', 'height', 'id', '_src', '_url', 'loadingclass', 'class', 'data-latex'], </span>  
[html] view plain copy
  1. <span style="font-size:18px;">//视频部分白名单********  
  2. video:  ['autoplay', 'controls', 'loop', 'preload', 'src', 'height', 'width', 'class', 'style'],    
  3. source: ['src', 'type'],    
  4. embed:  ['type', 'class', 'pluginspage', 'id', 'src', 'width', 'height', 'align', 'bgcolor', 'style', 'wmode', 'play',    
  5.     'loop', 'menu', 'allowscriptaccess', 'allowfullscreen'],  
  6. iframe: ['src', 'class', 'height', 'width', 'max-width', 'max-height', 'align', 'frameborder', 'allowfullscreen']  
  7. //********</span>  

img里面为什么要加上'_src'和'_url',第一篇博客里面说是因为编辑器在切换源码的过程中过滤掉img的_url属性(用来存储视频url)_src/plugins/video.js里处理的是_url,而不是_src。

 

然而,问题来了,居然没有用!!!!骂人

折腾了半天,最后发现只要把 whitList: 改成 whiteList:就好了。源码中少了一个e,一口血吐出来。想问百度UEditor的开发大神么英语六级过了么?


 

二、视屏编辑器预览BUG

关于视频编辑器的问题个人没找到有解释清楚的,折腾了半天还是自己看源码搞明白了,这里让我慢慢说。

视屏编辑器的bug在这里:


然而在确认之后,在UEditor的编译器上,把鼠标放在视频位置,弹出菜单,点击了下方的“修改”按钮


打开之后,奇迹出现了。。


晕死,怎么会这样。我找了半天,终于在视频编译器对应的video.js中找到问题了,就是这个方法:

 

[javascript] view plain copy
  1. /** 
  2.      * 监听url改变事件 
  3.      * @param url 
  4.      * @modify ie9以上使用oninput属性监听,onpropertychange不稳定 
  5.      */  
  6.     function addUrlChangeListener(url){  
  7.         if (browser.ie) {  
  8.             url.onpropertychange = function () {  
  9.                     createPreviewVideo( this.value );  
  10.         } else {  
  11.             url.addEventListener( "input"function () {  
  12.                 createPreviewVideo( this.value );  
  13.             }, false );  
  14.         }  
  15.     }  



 

这个方法中,url变量是视频编译器上输入“视频网址”的html Dom对象,我这里用的IE11测试的,然后onpropertychange这个方法就出现了问题。

 

这个方法的目的是监听这个html Dom对象是否发生了value变化,但是这对于ie11而言第一次打开却不起效果?!就比如说首次加载的时候就不行,首次加载的代码在这里(我只是想向大神证明我没胡说):


由于IE11已经能支持HTML5的规范了,所以可以直接用oninput方法,这里把上述函数改为:

 

[javascript] view plain copy
  1. /** 
  2.      * 监听url改变事件 
  3.      * @param url 
  4.      * @modify ie9以上使用oninput属性监听,onpropertychange不稳定 
  5.      */  
  6.     function addUrlChangeListener(url){  
  7.         if (browser.ie) {  
  8.             if(browser.ie11Compat==true  
  9.                     || browser.ie9Compat == true){  
  10.                 url.oninput = function () {  
  11.                     createPreviewVideo( this.value );  
  12.                 }  
  13.             }else{  
  14.                 //ie9以下  
  15.                 url.onpropertychange = function () {  
  16.                     createPreviewVideo( this.value );  
  17.                 }  
  18.             }  
  19.         } else {  
  20.             url.addEventListener( "input"function () {  
  21.                 createPreviewVideo( this.value );  
  22.             }, false );  
  23.         }  
  24.     }  

这样首次打开就也能播放视频了。


上述browser.ie11Compat==true和browser.ie9Compat == true请参照ueditor.all.js中这部分代码:

 

[javascript] view plain copy
  1. browser.ie11Compat = document.documentMode == 11;  
  2.         /** 
  3.          * @property { boolean } ie9Compat 检测浏览器模式是否为 IE9 兼容模式 
  4.          * @warning 如果浏览器不是IE, 则该值为undefined 
  5.          * @example 
  6.          * ```javascript 
  7.          * if ( UE.browser.ie9Compat ) { 
  8.          *     console.log( '当前浏览器运行在IE9兼容模式下' ); 
  9.          * } 
  10.          * ``` 
  11.          */  
  12.         browser.ie9Compat = document.documentMode == 9;  

 

好,这样解决了一般网络视频的播放问题,但是又有个问题来了,如果连接地址不是flash格式,而是普通的mp4文件地址问么办?

修改上述函数,在flash流路径下加上

 

[javascript] view plain copy
  1. type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"  


这两条属性,就可以兼容路径后缀为.mp4的视频流播放了。效果如下:

 

 

可以看到,这是后缀为.MP4的视屏流,也可以预览播放成功了。
网上有些人直接去掉了这两条属性,我试过这样对于flash流也能播放成功,但是很不稳定,电脑都死机过几回。。腾讯给的分享链接地址里面也是有这两条属性的,所以我建议对于flash流最好还是也带着吧。
三、添加视屏后百度编辑器预览BUG
百度编辑器预览BUG主要是因为在编译器中显示成了一张图片而不是视频。

关于这个我参考了一位作者的做法:

http://blog.csdn.net/belen_xue/article/details/73252802
个人认为其做法有点粗暴,甚至可能导致一部分问题,具体我慢慢细说。
首先,在引入js包的时候,请不要使用ueditor.all.min.js,因为这是压缩过的js,源码为ueditor.all.js,可修改。



那么接下来就要对ueditor.all.js进行操刀了!
先找到这个函数me.commands["insertvideo"] ,作者的做法直接将参数“image”改为了“embed”,认为这是视频就应该这样改:


 

改完之后,确实能确保编译器中能看到视频了,而不是图片了,但是窗口却不能关闭了,然后作者就又把上面那个for循环删了,原因是因为改完后找不到 id 这个属性了;

接下来在creatInsertStr方法中,switch的case 'embed': 分支中,str去掉了这两个属性:

 

[javascript] view plain copy
  1. type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"  


这样确实能保证绝大多数视频都能正常显示了,但是还是同video.js中的问题一样,稳定性不好,另外还有个非常大的问题,如果点击查看源码(那个html按钮),再返回,又会变成图片!
怎么办?

我在creatInsertStr方法下方直接发现了一个方法:

 

发现这个方法其实是在做图片和视频的切换。如果切换到查看html,或者调用获取编译器内容的getContent()方法时,会切回成embed标签,也就是嵌入视频标签,切换回预览页面时,又会切换回图片显示。也就是说,按照那位作者的做法,这个方法内容也必须注释掉,且两个IF都要注释。

 

[javascript] view plain copy
  1. function switchImgAndVideo(root,img2video){  
  2.         utils.each(root.getNodesByTagName(img2video ? 'img' : 'embed video'),function(node){  
  3.             //去掉转换  
  4.             var className = node.getAttr('class');  
  5. //            if(className && className.indexOf('edui-faked-video') != -1){  
  6. //                var html = creatInsertStr( img2video ? node.getAttr('_url') : node.getAttr('src'),node.getAttr('width'),node.getAttr('height'),null,node.getStyle('float') || '',className,img2video ? 'embed':'image');  
  7. //                node.parentNode.replaceChild(UE.uNode.createElement(html),node);  
  8. //            }  
  9. //            if(className && className.indexOf('edui-upload-video') != -1){  
  10. //                var html = creatInsertStr( img2video ? node.getAttr('_url') : node.getAttr('src'),node.getAttr('width'),node.getAttr('height'),null,node.getStyle('float') || '',className,img2video ? 'video':'image');  
  11. //                node.parentNode.replaceChild(UE.uNode.createElement(html),node);  
  12. //            }  
  13.         });  
  14.     }  

 

这样实践后,确实不会再出现切回图片的问题了,但是我在想,为何百度UEditor的开发人员非要把视频转为图片显示呢?

 

看到这个了吗,如果按照作者的做法换成视频的话,这个功能菜单自然就没有了。
另外按照作者的做法,如果这里是视频流的话,在编译器预览页面上删除视频,而视频如果正在播放,有些播放器可能会这样:


 

视频是被删了,可他附在页面上还在播放呢!

接下来我说下个人的做法:
me.commands["insertvideo"]方法,将上传和嵌入分开处理,for循环不需要删除,因为下面有办法解决(不就是少个id吗?我加上不就完了?)。

 

[javascript] view plain copy
  1. me.commands["insertvideo"] = {  
  2.         execCommand: function (cmd, videoObjs, type){  
  3.             videoObjs = utils.isArray(videoObjs)?videoObjs:[videoObjs];  
  4.             var html = [],id = 'tmpVedio', cl;  
  5.             for(var i=0,vi,len = videoObjs.length;i<len;i++){  
  6.                 vi = videoObjs[i];  
  7. //                cl = (type == 'upload' ? 'edui-upload-video video-js vjs-default-skin':'edui-faked-video');  
  8. //                html.push(creatInsertStr( vi.url, vi.width || 420,  vi.height || 280, id + i, null, cl, 'image'));  
  9.                 if(type == 'upload'){  
  10.                     cl = 'edui-upload-video video-js vjs-default-skin';  
  11.                     html.push(creatInsertStr( vi.url, vi.width || 420,  vi.height || 280, id + i, null, cl, 'video'));    
  12.                 }else{  
  13.                     cl = 'edui-faked-video';  
  14.                     html.push(creatInsertStr( vi.url, vi.width || 420,  vi.height || 280, id + i, null, cl, 'embed'));  
  15.                 }  
  16.             }  
  17.             me.execCommand("inserthtml",html.join(""),true);  
  18.             var rng = this.selection.getRange();  
  19.             for(var i= 0,len=videoObjs.length;i<len;i++){  
  20.                 var img = this.document.getElementById('tmpVedio'+i);  
  21.                 domUtils.removeAttributes(img,'id');  
  22.                 rng.selectNode(img).select();  
  23.                 me.execCommand('imagefloat',videoObjs[i].align);  
  24.             }  
  25.         },  

然后在creatInsertStr方法中,修改embed的处理方式:

 

 

[javascript] view plain copy
  1. case 'embed':  
  2.     if(utils.html(url) && utils.html(url).indexOf('.swf') != -1){  
  3.             str = '<embed type="application/x-shockwave-flash" class="' + classname + '" pluginspage="http://www.macromedia.com/go/getflashplayer"' +  
  4.                 (id ? 'id="' + id+'"' : '') +' src="' +  utils.html(url) + '" width="' + width  + '" height="' + height  + '"'  + (align ? ' style="float:' + align + '"''') +  
  5.                 ' wmode="transparent" play="true" loop="false" menu="false" allowscriptaccess="never" allowfullscreen="true" >';  
  6.         }else{  
  7.             //非flash流采用流播放模式,同上传视频一样  
  8.             var ext = url.substr(url.lastIndexOf('.') + 1);  
  9.             if(ext == 'ogv') ext = 'ogg';  
  10.             str = '<video' + (id ? ' id="' + id + '"' : '') + ' class="' + classname + ' video-js" ' + (align ? ' style="float:' + align + '"''') +  
  11.                 ' controls autoplay="autoplay" width="' + width + '" height="' + height + '" src="' + url + '" data-setup="{}">' +  
  12.                 '<source src="' + url + '" type="video/' + ext + '" /></video>';  
  13.         }  
  14.     break;  



 

这里判断一下,如果不是flash流的话就采用上传文件的方式去显示内容,也就是用video标签这种方式,这样就不用会出现删除视频后还附在页面上播放的情况(之前那种是和播放器有关系);

 

另外,如果是flash流的话,也就是embed标签,我这里将id属性添加上了,然后再embed标签的白名单里面配置上id属性就行了这样就不需要删除前面那个函数的for循环了。如果你是按我上面的那个白名单配置的话,就已经配好咯大笑

最后就是注释掉转换函数的内容:

 

[javascript] view plain copy
  1. function switchImgAndVideo(root,img2video){  
  2.         utils.each(root.getNodesByTagName(img2video ? 'img' : 'embed video'),function(node){  
  3.             //去掉转换  
  4.             var className = node.getAttr('class');  
  5. //            if(className && className.indexOf('edui-faked-video') != -1){  
  6. //                var html = creatInsertStr( img2video ? node.getAttr('_url') : node.getAttr('src'),node.getAttr('width'),node.getAttr('height'),null,node.getStyle('float') || '',className,img2video ? 'embed':'image');  
  7. //                node.parentNode.replaceChild(UE.uNode.createElement(html),node);  
  8. //            }  
  9. //            if(className && className.indexOf('edui-upload-video') != -1){  
  10. //                var html = creatInsertStr( img2video ? node.getAttr('_url') : node.getAttr('src'),node.getAttr('width'),node.getAttr('height'),null,node.getStyle('float') || '',className,img2video ? 'video':'image');  
  11. //                node.parentNode.replaceChild(UE.uNode.createElement(html),node);  
  12. //            }  
  13.         });  
  14.     }  

 

这种做法虽然失去了那些小菜单的功能,但是测试之后,整体也是非常稳定的。


这样删除视频后不会出现附在上面继续播放的问题。

 

PS:很多属性,比如:edui-faked-video、edui-upload-video这些,其实都是开发者早就设置好为了实现某些功能的,所以随意的更改他们肯定会意味着不稳定或者功能确实等各式各样的问题。我今天研究了一天,发现其实这两个属性的目的就是为了做图片和视频转换,然后在预览界面,图片的话就可以使用那些菜单功能。所以看,其实这些问题,百度UEditor的开发者们早就想到了,而我们非要画蛇添足的去改,是不是有些“舍本逐末”的味道呢?

以前做项目遇到这种情况往往也总是不择手段,能解决问题就好,可现在却越来越重视程序的鲁棒性。其实很多开源的工具,别人能放出来给大家用,自然是稳定的,若是需求不满足,我们要改也不能改得太暴力,若不符合开发者的初衷,自然改出来的功能也容易出问题。

今天一晚上加班写的文档,可能难免有些写的不正确或者理解不到位的地方,也忘各位大神指正!

 

原文:http://blog.csdn.net/yingjia11/article/details/78472261

分享到:
评论

相关推荐

    百度ueditor编辑器.zip

    百度ueditor编辑器百度ueditor编辑器百度ueditor编辑器百度ueditor编辑器百度ueditor编辑器百度ueditor编辑器百度ueditor编辑器百度ueditor编辑器百度ueditor编辑器百度ueditor编辑器

    百度ueditor编辑器

    UEditor主要面向网站开发者,提供了一个易于集成、功能完备的编辑器解决方案。它的核心优势在于其简洁的API和高效的性能,可以在不增加服务器负担的情况下提供流畅的编辑体验。编辑器支持多种语言环境,包括但不限于...

    百度ueditor编辑器jsp版本

    【百度UEditor编辑器JSP版本详解】 UEditor是由百度公司旗下的Web前端研发部精心打造的一款强大而易用的富文本Web编辑器。其主要目标是提供一个轻量级、高性能且用户友好的编辑工具,使得用户在网页上能够轻松进行...

    百度ueditor编辑器 word导入功能(asp.net版本)

    百度Ueditor的Word导入功能允许用户直接粘贴Word文档内容到编辑器中,这个功能非常实用,因为它可以保留原有的文字格式、段落、图片和表格等,极大地提高了内容编辑的效率。对于ASP.NET开发者来说,集成这个功能意味...

    UEditor编辑器兼容音频上传

    UEditor编辑器是一款由百度开发的开源在线HTML编辑器,其设计目的是为了提供一个轻量级、高效且功能丰富的富文本编辑解决方案。该编辑器在众多网站和应用中被广泛使用,因为它支持多种格式的内容编辑,包括文字、...

    百度编辑器ueditor上传图片视频以及div去掉P标签

    :“百度编辑器ueditor上传图片视频以及div去掉P标签”涉及到的是在使用ueditor编辑器时,如何处理HTML元素与标签的问题,特别是针对`&lt;p&gt;`(段落)标签与`&lt;div&gt;`(分组内容)标签的转换,以及在上传图片和视频时如何...

    百度编辑器ueditor.zip

    《全面解析:百度编辑器ueditor的使用与配置》...无论是简单的文字输入,还是复杂的多媒体内容编辑,ueditor都能提供高效、稳定的解决方案。只需简单几步配置,你就能拥有一个强大的在线编辑环境,提升用户的编辑体验。

    织梦搭配百度ueditor编辑器.rar

    utf-8版本和gbk都在里面,用于织梦后台直接可以粘贴图片发表内容 inc_fun_funAdmin.php可用于替换织梦include\inc\inc_fun_funAdmin.php文件 ueditor是可以直接粘贴图片的百度编辑器,放置在织梦include目录下面

    百度Ueditor在线富文本编辑器

    **百度Ueditor在线富文本编辑器** 百度Ueditor是一款由百度公司开发的开源、免费的在线富文本编辑器,主要用于Web应用中提供便捷的文本编辑功能。它以其强大的功能、良好的用户体验以及易于集成的特点,被广泛应用...

    百度Ueditor编辑器的使用,ASP.NET也可上传图片.zip

    总的来说,百度Ueditor为ASP.NET开发者提供了一个强大且易用的富文本编辑解决方案。虽然集成过程涉及前端和后端的配合,但其丰富的功能和灵活性使得这个过程变得值得。正确配置和使用Ueditor,可以极大地提升用户...

    百度Ueditor编辑器1.4.3.1 for wordpress 插件

    百度Ueditor编辑器1.4.3.1 for wordpress 插件

    百度富文本编辑器UEditor 1.4.3版本

    百度富文本编辑器UEditor是一款由百度公司开发的开源富文本编辑器,它在1.4.3版本中提供了丰富的功能和优秀的用户体验,适用于网页内容编辑、论坛发帖、博客写作等多种场景。UEditor以其易用性、稳定性和可定制性...

    ECshop编辑器更换成百度编辑器UEditor,远程图片可本地化

    UEditor是由百度web前端研发部开发所见即所得文本web编辑器,具有轻量,可定制,注重用户体验等特点。功能全面、专业稳定、用户体验佳。UEditor优点体积小巧,性能优良,使用简单。兼容目前所有主流的浏览器Mozilla,...

    百度文本编辑器实例UEditor实例

    **标题详解:**“百度文本编辑器实例UEditor实例” 百度UEditor是一款强大的富文本编辑器,由百度公司开发,广泛应用于网站内容编辑系统。它提供了丰富的文本格式化选项、图片上传、视频插入、表格编辑等功能,使得...

    百度编辑器ueditor

    **百度编辑器ueditor详解** 百度编辑器ueditor是一款由百度公司开发的开源富文本在线编辑器,它专为Web开发者设计,旨在提供一个简单、高效且功能丰富的文本编辑体验。ueditor支持多种浏览器环境,如Chrome、Fire...

    百度开源在线文本编辑器(ueditor) demo

    百度UEditor是一款功能强大的在线文本编辑器,由百度公司开源并维护。它提供了丰富的编辑功能和良好的用户体验,被广泛应用于博客、论坛、CMS(内容管理系统)等场景。UEditor不仅在基本的文本编辑上表现出色,还...

    百度UEditor 整合135所需要的文件

    整合135编辑器与百度UEditor的目的在于让用户能直接在UEditor中享受135编辑器的样式和模板资源。这个过程通常涉及以下几个步骤: - **导入样式和模板**:从135编辑器导出的文件包含CSS样式和HTML模板,需要将这些...

    【ASP.NET编程知识】ASP.NET百度Ueditor编辑器实现上传图片添加水印效果.docx

    * 百度Ueditor编辑器是一个功能强大且功能丰富的富文本编辑器,它提供了许多实用的功能,如图片上传、视频上传、语音上传等。 * 在ASP.NET中使用Ueditor编辑器可以实现富文本编辑的功能。 知识点二:修改Ueditor...

Global site tag (gtag.js) - Google Analytics