本来一件很简单的需求,慢慢的变成了一场灾难。
早前一直在电脑上看视频,家里的56吋的三星3D电视就在那里落灰了。
突然想到树莓pi上的硬盘里面有很多视频文件和照片,就想整理下,在电
视上放,当然,还有一个想法就是看播放3D是什么效果,我还没用过它看
3D电影呢。
于是,很简单的需求,架个minidlna服务器,so easy,然后,啊哦,
rmvb不支持,看下说明书,明明支持的啊,mkv不支持超过x264 level 4.1,我
下载的片子竟然是5.0的,当然,刚开始一直不知道,就折腾啊折腾,才找
到这个原因,使用ffmpeg也折腾好久才弄明白怎么转换是正确的,顺便一
提:
ffmpeg -i aa.mkv -c:v libx264 -preset fast -c:a copy -scodec
copy out.mkv
-scodec这个参数可能有些问题,没有的话他会按照默认的字幕和配音
弄,弄的话可能有问题,这个参数没有验证过
好不容易弄好之后,一播放,太卡,这个好办多了,换成有线,一切妥
妥的。
但minidlna不支持rmvb,这个比较蛋疼了。除了rmvb,我里面剩下的视
频文件就不多了,也好像不支持mpg,啊哦,又一个问题,想了想,换一个
吧,好在linux下相类似的软件多,于是,换上了mediatomb
苦难从此开始。
按照默认的下载安装,三星的电视竟然连接不上,什么状况啊,按照网
上找到的关于三星的配置(后续会提),也还连不上,这个人品也太差了吧。
详细找了找,发现2012年之后的需要重新编译一下,里面的路径解析这块
有问题,找到最新的代码,编译,发现mp4v2版本不对,修改完,编译,发
现另外的一个某某库也有问题,有无搞错啊,到网上看下代码,最后一个
发布版本竟然是在两三年前的,干脆从git库直接拖吧。于是:
git clone git://mediatomb.git.sourceforge.net/gitroot/mediatomb/mediatomb
autorecof -i
./configure --prefix=/usr --enable-iconv-lib --enable-mysql
--enable-libjs --enable-libmagic --enable-taglib
--enable-libexif --enable-youtube --enable-external-transcoding
--enable-sqlite-backup-defaults --enable-curl --disable-ffmpeg
--disable-ffmpegthumbnailer
make
sudo make install
最后的–disable-ffmpeg和–disable-ffmpegthumbnailer,看需求了,
我记得,ffmpegthumbnailer在弄rmvb的时候,会直接引起崩溃,这个也只
是记忆。这些个参数弄的我心碎啊,尤其是ffmpeg,raspberry pi里面默
认的libavformat库的版本是53的,最新的mediatomb要求是至少54的,弄
的我没办法,只好编译ffmpeg,要知道,编译一遍需要大约n多个小时,反
正昨天晚上我吃饭的时候编译开始,睡到早上5点多的时候发现编译完了。
但最后配合mediatomb的时候,发现一扫rmvb就自动退出了,没办法,干脆
禁用了。
上面明确表示ffmpeg关闭,但至于是不是真的用到,我也没有确认过,
反正ffmpeg我编译完了,就安装了下,到mediatomb编译完了的时候,又是
N久时间,结果,编译完却发现mp4一扫描就退出,找一找,发现mp4v2的库
压根就没用,检测了半天最后来个不兼容,然后,发现autorecof生成的
configure里面检测mp4v2的代码也不是很正确,里面检查的api是过期的
api,最后懒的弄,直接修改configure,结果生成的autoconfig.h中的
mp4v2还是关闭的,手动修改这个文件,所有的mp4v2的定义全部打开,终
于,N久之后,编译通过了。然后安装完,最好使用apt-get先安装,然后
编译,覆盖掉apt-get安装的,这样就不用自己弄那个服务配置了。
上面的花费了我N久的时间,尝试了N多次才找到每个问题点,不说了,
说了都是泪,接下来是配置篇.
/etc/mediatomb/config.xml的配置:
samsung.com
......
......
......
mediatomb最强大的就是转码功能,不过,这个对于raspberry pi么,
还是不用的好,所以其他的我就没有改动,也就是转码功能是关闭的。
基本上,主要的内容就上面那些,如果你按照上面的做的话,多半在编
译的时候会卡住,这里介绍几个补丁:
对于2012年之后生成的三星智能电视的补丁,如果你不确定的话,可是
先不打这个,如果你按照上面的配置,而电视仍然无法连接的话,多半需
要打这个补丁(from http://sourceforge.net/p/mediatomb/patches/_discuss/thread/57c47fb9/8ad8/attachment/mediatomb-urifix.patch)了:
diff -ruN mediatomb.orig/tombupnp/upnp/src/genlib/net/uri/uri.c mediatomb/tombupnp/upnp/src/genlib/net/uri/uri.c
--- mediatomb.orig/tombupnp/upnp/src/genlib/net/uri/uri.c 2012-06-06 23:01:22.000000000 +0200
+++ mediatomb/tombupnp/upnp/src/genlib/net/uri/uri.c 2012-06-07 08:22:01.000000000 +0200
@@ -1042,7 +1042,8 @@
out->path_type = REL_PATH;
}
- if( ( ( begin_hostport + 1 ) < max ) && ( in[begin_hostport] == '/' )
+ //parse hostport only if scheme was found
+ if( ( begin_hostport > 0 ) && ( ( begin_hostport + 1 ) < max ) && ( in[begin_hostport] == '/' )
&& ( in[begin_hostport + 1] == '/' ) ) {
begin_hostport += 2;
@@ -1059,6 +1060,12 @@
out->hostport.text.size = 0;
out->hostport.text.buff = 0;
begin_path = begin_hostport;
+
+ //remove excessive leading slashes (fix for Samsung Smart TV 2012)
+ while( ( ( begin_path + 1 ) < max ) && ( in[begin_path] == '/' ) && ( in[begin_path + 1] == '/') ) {
+ begin_path++;
+ }
+
}
begin_fragment =
另外的一个补丁,据说是解决一个-115的错误的,(from:
http://sourceforge.net/p/mediatomb/bugs/108/) 说不定也可以做相同的解决,但我没有测试
这里顺便一提:
-- mediatomb-0.12.1.orig/tombupnp/upnp/src/genlib/net/uri/uri.c
+++ mediatomb-0.12.1/tombupnp/upnp/src/genlib/net/uri/uri.c
@@ -1042,7 +1042,7 @@ parse_uri( const char *in,
out->path_type = REL_PATH;
}
- if( ( ( begin_hostport + 1 ) < max ) && ( in[begin_hostport] == '/' )
+ if( ( out->type == ABSOLUTE ) && ( ( begin_hostport + 1 ) < max ) && ( in[begin_hostport] == '/' )
&& ( in[begin_hostport + 1] == '/' ) ) {
begin_hostport += 2;
@@ -1054,11 +1054,18 @@ parse_uri( const char *in,
return begin_path;
} else {
+ if ( ( begin_hostport == 0 ) && ( ( begin_hostport + 1 ) < max ) && ( in[begin_hostport] == '/' )
+ && ( in[begin_hostport + 1] == '/' )) {
+ // The path starts with '//' - Samsung 8 series TVs do this... Skip the first character
+ begin_path = 1;
+ begin_fragment = 1;
+ } else {
+ begin_path = begin_hostport;
+ }
out->hostport.IPv4address.sin_port = 0;
out->hostport.IPv4address.sin_addr.s_addr = 0;
out->hostport.text.size = 0;
out->hostport.text.buff = 0;
- begin_path = begin_hostport;
}
begin_fragment =
第二个补丁,关于MP4v2-dev的,只有打了这个补丁,扫描mp4的时候才
不会退出,其实关键是mediatomb的git仓库中的代码使用的mp4v2版本太老
了。这个补丁是从https://trac.macports.org/attachment/ticket/36282/mediatomb-0.12.1-libmp4v2_191_p479.patch
找到的
--- old/src/metadata/libmp4v2_handler.cc 2012-04-05 01:46:26.000000000 +0200
+++ new/src/metadata/libmp4v2_handler.cc 2012-04-05 02:01:24.000000000 +0200
@@ -65,29 +65,28 @@
static void addMetaField(metadata_fields_t field, MP4FileHandle mp4, Ref item)
{
String value;
- char* mp4_retval = NULL;
- u_int16_t track;
- u_int16_t total_tracks;
-
Ref sc = StringConverter::i2i();
+ const MP4Tags* new_tags = MP4TagsAlloc();
+
+ if (!MP4TagsFetch(new_tags, mp4))
+ return;
+
switch (field)
{
case M_TITLE:
- MP4GetMetadataName(mp4, &mp4_retval);
+ value = new_tags->name;
break;
case M_ARTIST:
- MP4GetMetadataArtist(mp4, &mp4_retval);
+ value = new_tags->artist;
break;
case M_ALBUM:
- MP4GetMetadataAlbum(mp4, &mp4_retval);
+ value = new_tags->album;
break;
case M_DATE:
- MP4GetMetadataYear(mp4, &mp4_retval);
- if (mp4_retval)
+ value = new_tags->releaseDate;
+ if (value.length() > 0)
{
- value = mp4_retval;
- free(mp4_retval);
if (string_ok(value))
value = value + "-01-01";
else
@@ -95,34 +94,31 @@
}
break;
case M_GENRE:
- MP4GetMetadataGenre(mp4, &mp4_retval);
+ value = new_tags->genre;
break;
case M_DESCRIPTION:
- MP4GetMetadataComment(mp4, &mp4_retval);
+ value = new_tags->comments;
break;
case M_TRACKNUMBER:
- MP4GetMetadataTrack(mp4, &track, &total_tracks);
- if (track > 0)
+ if (new_tags->track)
{
- value = String::from(track);
- item->setTrackNumber((int)track);
+ value = String::from(new_tags->track->index);
+ item->setTrackNumber((int)new_tags->track->index);
}
else
+ {
+ MP4TagsFree( new_tags );
return;
+ }
break;
default:
+ MP4TagsFree( new_tags );
return;
}
- if ((field != M_DATE) && (field != M_TRACKNUMBER) &&
- (mp4_retval))
- {
- value = mp4_retval;
- free(mp4_retval);
- }
-
+ MP4TagsFree( new_tags );
value = trim_string(value);
-
+
if (string_ok(value))
{
item->setMetadata(MT_KEYS[field].upnp, sc->convert(value));
@@ -190,14 +186,19 @@
}
#if defined(HAVE_MAGIC)
- u_int8_t *art_data;
- u_int32_t art_data_len;
+ void *art_data = 0;
+ u_int32_t art_data_len = 0;
String art_mimetype;
+
+ const MP4Tags* new_tags = MP4TagsAlloc();
+ MP4TagsFetch(new_tags, mp4);
+ if (new_tags->artworkCount)
+ {
+ art_data = new_tags->artwork->data;
+ art_data_len = new_tags->artwork->size;
+ }
#ifdef HAVE_MP4_GET_METADATA_COVER_ART_COUNT
- if (MP4GetMetadataCoverArtCount(mp4) &&
- MP4GetMetadataCoverArt(mp4, &art_data, &art_data_len))
-#else
- MP4GetMetadataCoverArt(mp4, &art_data, &art_data_len);
+ if (new_tags->artworkCount && art_data_len > 0)
#endif
{
if (art_data)
@@ -211,11 +212,10 @@
}
catch (Exception ex)
{
- free(art_data);
+ MP4TagsFree(new_tags);
throw ex;
}
- free(art_data);
if (art_mimetype != _(MIMETYPE_DEFAULT))
{
Ref resource(new CdsResource(CH_MP4));
@@ -225,6 +225,7 @@
}
}
}
+ MP4TagsFree(new_tags);
#endif
MP4Close(mp4);
}
@@ -249,26 +250,35 @@
if (ctype != ID3_ALBUM_ART)
throw _Exception(_("LibMP4V2Handler: got unknown content type: ") + ctype);
+
+ const MP4Tags* new_tags = MP4TagsAlloc();
+ if (MP4TagsFetch(new_tags, mp4))
+ {
#ifdef HAVE_MP4_GET_METADATA_COVER_ART_COUNT
- if (!MP4GetMetadataCoverArtCount(mp4))
- throw _Exception(_("LibMP4V2Handler: resource has no album art information"));
+ if (!new_tags->artworkCount)
+ throw _Exception(_("LibMP4V2Handler: resource has no album art information"));
#endif
- u_int8_t *art_data;
- u_int32_t art_data_len;
- if (MP4GetMetadataCoverArt(mp4, &art_data, &art_data_len))
- {
- if (art_data)
+ void *art_data = 0;
+ u_int32_t art_data_len;
+
+ const MP4TagArtwork* art = new_tags->artwork;
+ art_data = art->data;
+ art_data_len = art->size;
+ if (art)
{
- *data_size = (off_t)art_data_len;
- Ref h(new MemIOHandler((void *)art_data, art_data_len));
- free(art_data);
- return h;
+ if (art_data)
+ {
+ *data_size = (off_t)art_data_len;
+ Ref h(new MemIOHandler(art_data, art_data_len));
+ MP4TagsFree(new_tags);
+ return h;
+ }
}
+ MP4TagsFree(new_tags);
}
-
throw _Exception(_("LibMP4V2Handler: could not serve album art "
- "for file") + item->getLocation() +
- " - embedded image not found");
+ "for file") + item->getLocation() +
+ " - embedded image not found");
}
#endif // HAVE_LIBMP4V2
其他需要做的内容就没有了,然后就可以再电视上好好看大片了,包括
rmvb等。
问题1:
默认支持mpg格式的,从u盘播放页没有问题,但从meidatomb则无法播
放,提示格式不支持,我试了好几种mimetype,都不可以,不知道具体问
题在哪儿,这里一则内容仅供参考,不一定正确:http://forums.cnet.com/7723-13973_102-532671/samsung-d-series-products-dlna-regression/