立即注册 登录
彼岸网 返回首页

天香公主的个人空间 http://www.bian-wang.com/discuz/?10005 [收藏] [复制] [分享] [RSS] https://github.com/txgz999/discuz/wiki

日志

Discuz功能改进:一键贴

热度 7已有 4710 次阅读2015-10-3 07:05 PM |个人分类:Discuz

Discuz提供的微博功能相对简陋,在微博上除了能写文字外,也就是能用bb代码来加超链接了,连图片也没法贴。我以前讨论过如何扩展微博功能来让用户使用bb代码在上面贴图(链接)。这是个很自然的想法,因为一是超链接在微博里就是用bb代码加的,二是日志后的评论里可以用bb代码来贴图。所以这样的做法是对Discuz内置功能的一个自然延伸。在储存格式上有两种可能,一是储存用户填写的bb代码,然后在显示前转换为html代码。二是在储存前将bb代码转换成html代码,在数据库里存html代码,这样就能直接显示了。两种方法都是可行的而且各有利弊。存bb代码便于用户编辑修改(不过现在微博还没有修改功能),而且bb代码相当简约。上面提到的两个内置的贴超链接和贴图功能存的都是html代码,但内置的日志里贴的视频的功能则采取了存bb代码的做法,也许是因为把它转换成html里的object代码会在储存时多占很大空间。


近来我看到汉山网让用户直接贴图片的地址,然后系统将它转换成图片显示,称之为一键完成又称一键通和一键贴(链接)。我觉得那样的做法比用bb代码好。一是对用户更方便,不需要记bb代码了。二是储存内容干净,没有bb代码。三是用户修改起来也方便,因为按原样储存没对用户输入做任何转换。当然这种做法也有一定缺陷:
1)它对图片的识别是依据地址结尾处图片文件名的后缀(如.png),所以它没法识别用短地址代表的图片,比如它可以识别 https://www.google.com/images/srpr/logo11w.png 但却没法识别与此等价的短地址 http://tinyurl.com/lubjeod
而用bb代码就没有这局限。
2) 它没法让用户选择图片显示尺寸,而bb代码则不难扩充来支持这个自由度。
3) 用户没有只贴图片地址不要贴图的自由。
但感觉这些都不是大问题。关于1)短地址用的人不多,而且能在浏览器里轻易就能转换成普通地址。关于2),因为各人的微博都显示在一起,所以以网站统一显示尺寸为好。关于3),可以去掉地址最前端的protocol来避免转换。

1。一键贴图

下面我们来考虑下如何实现对这种贴图办法的支持。

新的代码加在了 /source/include/space/space_doing.php 里,在从数据库里取出了微博内容后将图片地址转换成了html里的图片元素,举例而言,将图片地址
https://www.google.com/images/srpr/logo11w.png 转换成了类似于下面的html图片元素 <img src="https://www.google.com/images/srpr/logo11w.png" /> 下面两段代码里的最后两句是新加的。第一段是处理微博主贴的内容,第二段是处理微博回复的内容: $query = C::t('home_doing')->fetch_all_search($start, $perpage, 1, $uids, '', $searchkey, '', '' ,'', 1, $doid, $f_index); foreach($query as $value) { if($value['status'] == 0 || $value['uid'] == $_G['uid'] || $_G['adminid'] == 1) { require_once libfile('function/url2html'); $value['message'] =url2html($value['message']); foreach(C::t('home_docomment')->fetch_all_by_doid($doids) as $value) { require_once libfile('function/url2html'); $value['message'] = url2html($value['message']); 具体的转换代码定义在一个新加的文件 /source/function/function_url2html.php 里: function url2html ($message) { $message = preg_replace("/(https?:\/\/\S+?.(?:jpe?g|png|gif))/ie", "url2html_img('\\1')", $message); return $message; } function url2html_img($url) { return "<a href='$url' target='_blank' style='vertical-align: top;'> <img src='$url' style='max-height: 150px;'/></a>"; } 上面修改的文件 /source/include/space/space_doing.php 是在显示整个微博页时用的,还有一个文件/source/include/spacecp/spacecp_doing.php 则处理了加了一个回复后对新回复所属的微博主贴包括其下所有回复的显示更新的情形,因此也需要做类似修改: foreach(C::t('home_docomment')->fetch_all_by_doid($doid) as $value) { require_once libfile('function/url2html'); $value['message'] = url2html($value['message']);

这种做法的特点是在储存微博时不做任何相关处理,而从数据库提取微博后,则用正则表达式来找出该微博里的所有图片,然后将这些图片地址都替换成能直接显示成图片的html图片元素。

2。一键视频

汉山上的一键贴不光支持贴图,还支持贴音频和多个视频网站的视频。接下来我们讨论一下如何支持贴YouTube视频。常见的YouTube视频地址有多种形式,举例而言:
https://www.youtube.com/embed/MD5bFCDfySc (视频地址)
https://www.youtube.com/v/MD5bFCDfySc (视频地址)
https://www.youtube.com/watch?v=MD5bFCDfySc (视频网页地址)
https://m.youtube.com/watch?v=MD5bFCDfySc (视频网页地址)
https://youtu.be/MD5bFCDfySc (视频网页地址)
有些对应于视频本身,还有些则对应于视频所在的网页。 我们要支持所有这些形式的地址。将前面介绍过的函数 url2html 增补如下: function url2html ($message) { $message = preg_replace("/(https?:\/\/\S+?.(?:jpe?g|png|gif))/ie", "url2html_img('\\1')", $message); $message = preg_replace("/https?:\/\/(?:www.)?youtube.com\/embed\/([a-zA-Z0-9\_\-]+)/ie", "url2html_youtube('\\1')", $message); $message = preg_replace("/https?:\/\/(?:www.)?youtube.com\/v\/([a-zA-Z0-9\_\-]+)/ie", "url2html_youtube('\\1')", $message); $message = preg_replace("/https?:\/\/(?:[a-zA-Z0-9\-]+\.)?youtube.com\/watch\?v=([a-zA-Z0-9\_\-]+)/ie", "url2html_youtube('\\1')", $message); $message = preg_replace("/https?:\/\/youtu.be\/([a-zA-Z0-9\_\-]+)/ie", "url2html_youtube('\\1')", $message); return $message; } function url2html_youtube($vid) { return "<iframe src='https://www.youtube.com/embed/$vid?rel=0' frameborder='0' allowfullscreen style='width: 400px; height: 300px; vertical-align: top;'></iframe>"; }


这种做法将每个微博里的Youtube地址都显示成了一个iframe,网民可以点击后在那里观看。缺点一是如果将视频按Youtube推荐的尺寸560*315来显示的话,它在微博里占地过大,影响阅读其它内容。而如果缩小过多的话,看起来不方便,会不得不再点击全屏播放。 二是这样做微博页上网页越多,网页的负担越大,显示和反应的速度越慢。 每个iframe里的内容都要向YouTube网站发数个请求来获取,即使是不看视频的网友也会受其影响。

3。按需嵌入

Amit Agarwal (链接)介绍了 Google+ 网站 (链接)是如何来避免网页速度变慢的。它们在网页上显示视频的并不是iframe,而只是视频的一张缩影图片。只当用户点击图片后,那张图片才被一个当时生成的iframe所取代。

他还介绍了具体的实现方法。下面的处理借鉴了他的方法。我们将上面提到的 url2html_youtube 函数修改如下:
function url2html_youtube($vid) { return '<div class="youtube-player"> <div style="display: inline; position: relative; cursor: pointer;" onclick="loadYouTubeVideo(this, \''.$vid.'\');"> <img class="youtube-thumb" src="//i.ytimg.com/vi/'.$vid.'/0.jpg" /> <div class="play-button"></div></div></div>'; } 在用户点击了显示的YouTube视频图片后,loadYouTubeVideo函数将它用一个 iframe 来替换,它定义在 /template/default/common/footer.htm 里: function loadYouTubeVideo(pd, vid) { var iframe = document.createElement("iframe"); iframe.setAttribute("src", "//www.youtube.com/embed/" + vid + "?autoplay=1&border=0&wmode=opaque&enablejsapi=1&controls=1&showinfo=1"); iframe.setAttribute("frameborder", "0"); iframe.setAttribute("id", "youtube-iframe"); pd.parentNode.replaceChild(iframe, pd); } 相关风格的定义如下: div.youtube-player { display: inline-block; width: 400px; height: 300px; position: relative; vertical-align: top; background-color: Black; margin-bottom: 20px; } img.youtube-thumb { width: 400px; height: 300px; position: absolute; } div.play-button { height: 128px; width: 128px; position:absolute; margin-left: 136px; margin-top: 86px; background: url({IMGDIR}/player_play.png) no-repeat; } #youtube-iframe { width: 100%; height: 100%; position: absolute; }


这种办法对网页的速度会有改善,但还是没解决视频占地和周边微博内容尺寸不匹配的问题。

4。弹窗播放

现在我们来介绍第三种办法。保留第二种办法里显示视频图片的优点,但将它缩小到能和微博里其它内容高度匹配,当用户点击它时将视频在一个新窗口里按YouTube推荐的560*315的尺寸播放。这个窗口可以用我们前文介绍过的Discuz软件提供的弹窗功能(链接)来实现。
我们先要对前面提到过的函数 url2html_youtube 做个小的改动: function url2html_youtube($vid) { return '<div class="youtube-player"> <div style="display: inline; position: relative; cursor: pointer;" onclick="loadYouTubeVideo(\''.$vid.'\');"> <img class="youtube-thumb" src="//i.ytimg.com/vi/'.$vid.'/0.jpg" /> <div class="play-button"></div></div></div>'; } 重点要改的是函数 loadYouTubeVideo 里的内容: function loadYouTubeVideo(vid) { var html = "<div class='f_c' style='width: 400px; height: 320px;'>"; html += "<h3 class='flb' style='background-color: #a4cf50; padding: 0px 8px 0px;'><span><a href='javascript:;' class='flbc' onclick='hideWindow(\"youtube\");'></a></span></h3>"; html += "<iframe src='//www.youtube.com/embed/"+vid+"?autoplay=1&border=0&wmode=opaque&enablejsapi=1&controls=1&showinfo=1' frameborder=0 allowfullscreen allowtransparency width=400 height=300></iframe></div>"; showWindow('youtube', html, 'html', 0); } 再要修改下前面提到过的有关风格(还缩小一个图): div.youtube-player { display: inline-block; width: 200px; height: 150px; position: relative; vertical-align: top;margin-bottom: 20px; } img.youtube-thumb { width: 200px; height: 150px; position: absolute; } div.play-button { position:absolute; width: 48px; height: 48px; margin-left: 152px; margin-top: 103px; background: url({IMGDIR}/player_play.png) no-repeat; }



本文主要讨论了如何在微博里添加对图片和油管视频的一键贴的支持。这样的做法不难类似的推广到其它形式的视频音频和其它格式的文件如PDF,以及论坛博文文章及其评论里。

发表评论 评论 (49 个评论)

回复 天香公主 2016-5-10 08:16 AM
sesemule: 懂了⊙▽⊙
我又想了想这问题,虽然要通过解析爱奇艺的视频网页地址来得到视频地址几近不可能,但应该可以允许用户直接贴视频地址(用户得先在视频网页上找到视频地址),等我周末更新和测试后再告诉你
回复 天香公主 2016-5-10 06:34 AM
sesemule: 测试MP3的时候遇到一个问题:控制音乐播放器长度高度的不应该是这段代码吗<embed width=&quot;180&quot; height=&quot;60&quot; autostart=&quot;false&quot; lo ...
把这之前的那句
<audio controls>
改成类似下面的
<audio controls style="width: 150px;">
回复 天香公主 2016-5-10 06:09 AM
sesemule: 成功了。
   我原来以为动态只用了记录内容的开始多少个字,所以担心会有地址被截断的情况出现。后来看了Discuz代码发现动态是全文拷贝了记录内容,那就没这问题了。
回复 sesemule 2016-5-10 06:08 AM
测试MP3的时候遇到一个问题:控制音乐播放器长度高度的不应该是这段代码吗<embed width="180" height="60" autostart="false" loop="false" src="'.$url.'">,为什么修改width、height无效?(因为在手机上显示的时候,音乐播放器过长,撑破了页面,我想把它改短一点)
回复 sesemule 2016-5-10 01:11 AM
天香公主: 我看了看代码,可以改在文件source/function/function_feed.php里的函数mkfeed里:在开头几句
function mkfeed($feed, $actors=array()) {
        global $_G;
        $feed[ ...
成功了。
回复 天香公主 2016-5-9 09:25 PM
sesemule: 我希望可以在动态列表里显示和记录列表里一样的效果,既然记录是修改source/include/space/space_doing.php和/source/include/spacecp/spacecp_doing.php,那么 ...
我看了看代码,可以改在文件source/function/function_feed.php里的函数mkfeed里:在开头几句
function mkfeed($feed, $actors=array()) {
        global $_G;
        $feed['title_data'] = empty($feed['title_data'])?array():(is_array($feed['title_data'])?$feed['title_data']:@dunserialize($feed['title_data']));
        if(!is_array($feed['title_data'])) $feed['title_data'] = array();
后加上
    if ($feed['idtype']=='doid') {
        if (!empty($feed['title_data'] ['message'])) {
            require_once libfile('function/url2html');
            $feed['title_data']['message'] = url2html($feed['title_data']['message']);
        }
    }

你试试吧
回复 sesemule 2016-5-9 10:59 AM
我希望可以在动态列表里显示和记录列表里一样的效果,既然记录是修改source/include/space/space_doing.php和/source/include/spacecp/spacecp_doing.php,那么动态是不是应该修改/source/include/space/space_home.php和/source/include/spacecp/spacecp_feed.php?我看不懂代码,所以也不知道应该添加在什么位置。请天香公主指教
回复 sesemule 2016-5-9 01:03 AM
天香公主: 之所以不支持爱奇艺是有原因的,从它的视频网页地址看不出嵌入视频地址的规律。以你给的视频网页地址为例,对应的嵌入视频地址是
http://open.iqiyi.com/ ...
懂了⊙▽⊙
回复 天香公主 2016-5-9 12:52 AM
sesemule: 还想麻烦下,代码中并没有爱奇艺,我站有个女生在爱奇艺追剧,还买了会员……请问如何添加爱奇艺的地址?视频形式如下:
http://www.iqiyi.com/v_19rrlw026s.htm ...
之所以不支持爱奇艺是有原因的,从它的视频网页地址看不出嵌入视频地址的规律。以你给的视频网页地址为例,对应的嵌入视频地址是
http://open.iqiyi.com/developer/player_js/coopPlayerIndex.html?vid=7ad8336bea5345d6c095ccbb6dcd8fe0&tvId=479815800&accessToken=2.f22860a2479ad60d8da7697274de9346&appKey=3955c3425820435e86d0f4cdfe56f5e7&appId=1368
回复 sesemule 2016-5-8 07:25 AM
天香公主: 嗯,我没看到过这种式样,有趣的是从我电脑上进这个地址就自动进入了http://v.qq.com/page/z/v/3/z0197m8xrv3.html,这才是我处理了的地址

要想处理你这地址的 ...
还想麻烦下,代码中并没有爱奇艺,我站有个女生在爱奇艺追剧,还买了会员……请问如何添加爱奇艺的地址?视频形式如下:
http://www.iqiyi.com/v_19rrlw026s.html
回复 天香公主 2016-5-8 12:50 AM
sesemule: http://m.v.qq.com/play/play.html?coverid=&vid=z0197m8xrv3

你试试这个,腾讯视频的手机版。
嗯,我没看到过这种式样,有趣的是从我电脑上进这个地址就自动进入了http://v.qq.com/page/z/v/3/z0197m8xrv3.html,这才是我处理了的地址

要想处理你这地址的话,把我给你的代码中的下面这句
// http://v.qq.com/iframe/player.html?vid=q0149bzkuv6
elseif ($url_section["path"]=='/iframe/player.html')
改成
// http://v.qq.com/iframe/player.html?vid=q0149bzkuv6
// http://m.v.qq.com/play/play.html?coverid=&vid=z0197m8xrv3
else
就行了
回复 sesemule 2016-5-8 12:17 AM
天香公主: 腾讯视频我印象中是比较友善的,你给我个你手机上拷贝来的网址,让我看看吧

对,能自动变成超链接也满方便的

抱歉,我对此无能为力,不用智能手机   ...
http://m.v.qq.com/play/play.html?coverid=&vid=z0197m8xrv3

你试试这个,腾讯视频的手机版。
回复 天香公主 2016-5-8 12:00 AM
sesemule: 我已经注意到了,腾讯视频本来是可用的,但我在手机版的腾讯视频拷贝来的网址,就不会自动解析。不过确实无所谓,只要能解析链接,跳转到视频网站查看也可以接受 ...
腾讯视频我印象中是比较友善的,你给我个你手机上拷贝来的网址,让我看看吧

对,能自动变成超链接也满方便的

抱歉,我对此无能为力,不用智能手机
回复 天香公主 2016-5-7 11:55 PM
东风: 我们有你太幸福有了, 这样的一键功能除了在微博里,能加入到博客里吧?那样就太方便了。我有个本地运行的镜像站点,做了测试的。 ...
   好,等我找出来在日志,文章和贴子里的接口代码,明后天试下再给你
回复 sesemule 2016-5-7 11:44 PM
天香公主:    很难做得完善。国内的视频网站不时兼并,所以用pattern来猜测视频地址不很可靠,更好的办法是用它们提供的API,但这就需要修改数据库来储存结果,有点小 ...
我已经注意到了,腾讯视频本来是可用的,但我在手机版的腾讯视频拷贝来的网址,就不会自动解析。不过确实无所谓,只要能解析链接,跳转到视频网站查看也可以接受。

话说你不准备给彼岸写个手机版的模板吗?手机上浏览彼岸真是痛苦啊。
回复 东风 2016-5-7 09:13 PM
天香公主:    真要用的话最好在测试站上测试一下,看看有没有bug,以及和网站上的其它修改或插件是否有冲突。主函数有个参数minorArea,用它来达到不同区域里的不同效 ...
我们有你太幸福有了, 这样的一键功能除了在微博里,能加入到博客里吧?那样就太方便了。我有个本地运行的镜像站点,做了测试的。
回复 天香公主 2016-5-7 08:13 PM
sesemule: 哇,还支持优酷腾讯bilibili……真棒!
   很难做得完善。国内的视频网站不时兼并,所以用pattern来猜测视频地址不很可靠,更好的办法是用它们提供的API,但这就需要修改数据库来储存结果,有点小题大作的感觉。国内的视频很多都不对境外开放,所以感觉在国外网站加不加对国内视频的支持区别不大。
回复 天香公主 2016-5-7 08:06 PM
东风: 太伟大了~~让北美有种不劳而获的赶脚哎~~太幸福了~~
   真要用的话最好在测试站上测试一下,看看有没有bug,以及和网站上的其它修改或插件是否有冲突。主函数有个参数minorArea,用它来达到不同区域里的不同效果,比如在日志里pdf地址要变成嵌入的PDF显示,而在记录里则只要变成一个超链接。文中有在记录里引用这个函数的代码,如果你要在其它地方用它,我可以找找看接口的代码,不过好久没用记不清了,不自己先测试下不敢给你
回复 东风 2016-5-7 07:32 PM
太伟大了~~让北美有种不劳而获的赶脚哎~~太幸福了~~
回复 sesemule 2016-5-7 12:05 AM
天香公主: 给你我现在的function_url2html.php文件,它包含了文中的1)和2),也支持你要的超链接,还支持其它一些多媒体资源 http://www.bian-wang.com/upload/txgz_fun ...
哇,还支持优酷腾讯bilibili……真棒!

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 立即注册

小黑屋|Archiver|彼岸网  

Powered by Discuz! X3.1 © 2001-2014 Comsenz Inc.
GMT-4, 2024-3-29 08:50 AM , Processed in 0.048320 second(s), 8 queries. ,ApcOn

返回顶部