1. 下載 libmms
直接從官方網頁 http://sourceforge.net/projects/libmms/ 下載程式碼進行編譯,會無法正常編譯為 iOS 對應的 library。
編譯的命令如下:
./build.sh
make
其中 build.sh 的內容如下:
export CC=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc
export CFLAGS="-arch i386"
export LD=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk
export AS=/usr/local/bin/gas-preprocessor.pl
export LDFLAGS="-L/Users/albert/Work/pkg-config-0.28/glib":$LDFLAGS
./configure \
--prefix=/Users/albert/Work/libmms-0.6.2/compiled/i386
錯誤訊息如下:
localhost:libmms-0.6.2 albert$ make
make all-recursive
Making all in src
make all-am
/bin/sh ../libtool --tag=CC --mode=link /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc -arch i386 -version-info 0:2:0 -no-undefined -export-dynamic -L/Users/albert/Work/pkg-config-0.28/glib: -o libmms.la -rpath /Users/albert/Work/libmms-0.6.2/compiled/i386/lib mms.lo mmsh.lo mmsx.lo uri.lo -L/opt/local/lib -lglib-2.0 -lintl
libtool: link: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc -dynamiclib -o .libs/libmms.0.dylib .libs/mms.o .libs/mmsh.o .libs/mmsx.o .libs/uri.o -L/Users/albert/Work/pkg-config-0.28/glib: -L/opt/local/lib /opt/local/lib/libglib-2.0.dylib -lresolv /opt/local/lib/libintl.dylib /opt/local/lib/libiconv.dylib -lc -arch i386 -install_name /Users/albert/Work/libmms-0.6.2/compiled/i386/lib/libmms.0.dylib -compatibility_version 1 -current_version 1.2
ld: warning: directory not found for option '-L/Users/albert/Work/pkg-config-0.28/glib:'
ld: warning: ignoring file /opt/local/lib/libglib-2.0.dylib, file was built for unsupported file format ( 0xcf 0xfa 0xed 0xfe 0x 7 0x 0 0x 0 0x 1 0x 3 0x 0 0x 0 0x 0 0x 6 0x 0 0x 0 0x 0 ) which is not the architecture being linked (i386): /opt/local/lib/libglib-2.0.dylib
ld: warning: ignoring file /opt/local/lib/libintl.dylib, file was built for unsupported file format ( 0xcf 0xfa 0xed 0xfe 0x 7 0x 0 0x 0 0x 1 0x 3 0x 0 0x 0 0x 0 0x 6 0x 0 0x 0 0x 0 ) which is not the architecture being linked (i386): /opt/local/lib/libintl.dylib
ld: warning: ignoring file /opt/local/lib/libiconv.dylib, file was built for unsupported file format ( 0xcf 0xfa 0xed 0xfe 0x 7 0x 0 0x 0 0x 1 0x 3 0x 0 0x 0 0x 0 0x 6 0x 0 0x 0 0x 0 ) which is not the architecture being linked (i386): /opt/local/lib/libiconv.dylib
Undefined symbols for architecture i386:
"_g_free", referenced from:
_split_user_passwd in uri.o
_gnet_uri_new in uri.o
_gnet_uri_delete in uri.o
_field_escape in uri.o
_gnet_uri_set_scheme in uri.o
_gnet_uri_set_userinfo in uri.o
_gnet_uri_set_hostname in uri.o
...
"_g_malloc", referenced from:
_field_escape in uri.o
"_g_malloc0_n", referenced from:
_gnet_uri_new in uri.o
_gnet_uri_new_fields in uri.o
_gnet_uri_new_fields_all in uri.o
_gnet_uri_clone in uri.o
"_g_return_if_fail_warning", referenced from:
_gnet_uri_new in uri.o
_gnet_uri_clone in uri.o
_gnet_uri_equal in uri.o
_gnet_uri_hash in uri.o
_gnet_uri_escape in uri.o
_gnet_uri_unescape in uri.o
_gnet_uri_get_string in uri.o
...
"_g_str_hash", referenced from:
_gnet_uri_hash in uri.o
"_g_strdup", referenced from:
_split_user_passwd in uri.o
_gnet_uri_new in uri.o
_gnet_uri_new_fields in uri.o
_gnet_uri_new_fields_all in uri.o
_gnet_uri_clone in uri.o
_gnet_uri_set_scheme in uri.o
_gnet_uri_set_userinfo in uri.o
...
"_g_string_append", referenced from:
_gnet_uri_get_string in uri.o
"_g_string_append_printf", referenced from:
_gnet_uri_get_string in uri.o
"_g_string_free", referenced from:
_gnet_uri_get_string in uri.o
"_g_string_insert_c", referenced from:
_g_string_append_c_inline in uri.o
"_g_string_sized_new", referenced from:
_gnet_uri_get_string in uri.o
"_g_strndup", referenced from:
_gnet_uri_new in uri.o
"_libiconv", referenced from:
_string_utf16 in mms.o
"_libiconv_close", referenced from:
_mms_connect in mms.o
"_libiconv_open", referenced from:
_mms_connect in mms.o
ld: symbol(s) not found for architecture i386
collect2: ld returned 1 exit status
make[3]: *** [libmms.la] Error 1
make[2]: *** [all] Error 2
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2
2. 編譯成 library
使用更改過後的libmms,直接使用 xCode 打開,則可以正確編譯。
git clone git://github.com/aporat/xcode-libmms.git。
編譯後的library位於
/Users/albert/Library/Developer/Xcode/DerivedData/MMS-afkkckenpbbhexgcbgmgvvysynsy/Build/Products/Release-iphoneos
3. 比較 libmms 與 xcode-libmms 的差異處
主要在於 URI的使用方式。
xcode-libmms 不會 #include uri.h,也不使用 GURI,透過新增四個參數 host, uri, query, pport,利用這些參數取代原本 GURI的功能。
4. 使用 libmms
使用 xCode 開啟 xcode-libmms project。更改iOS Deployment Target,接著便可以編譯成iOS Device使用的library。
新增一個 project for iOS device,命名為 testMMS。 在 project中新增下列指令,編譯後會發現以下錯誤
Undefined symbols for architecture armv7:
"_iconv", referenced from:
_string_utf16 in libMMS.a(mms.o)
"_iconv_open", referenced from:
_mms_connect in libMMS.a(mms.o)
"_iconv_close", referenced from:
_mms_connect in libMMS.a(mms.o)
"_Status_GetNewStatusByKey", referenced from:
_mms_connect in libMMS.a(mms.o)
_mmsh_connect in libMMS.a(mmsh.o)
_mmsh_connect_int in libMMS.a(mmsh.o)
"_Status_SetNewStatusByKey", referenced from:
_mms_connect in libMMS.a(mms.o)
_mmsh_connect in libMMS.a(mmsh.o)
_mmsh_connect_int in libMMS.a(mmsh.o)
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
解決方式:Step1. 在 xcode 專案中選擇要編譯的target,選擇 Build Phases 中的 Link Library With Libraries,新增 libiconv
Step2. _Status_SetNewStatusByKey 與 _Status_GetNewStatusByKey 是不需要的,因此直接在 xcode-libmms 中移除對應的程式,在重新編譯libmms即可。
執行下列程式,應該可以看到已經正確建立連線。
mms_t *vpMMS;
vpMMS=connect(NULL, NULL,"mms://bcr.media.hinet.net/RA000008","bcr.media.hinet.net","RA000008","",1755,64*1024);
註:實驗發現 ffmpeg 可以透過 mmsh 或 mmst 直接連結 mms 對應的音樂串流,因此後續實作網路電台時便沒有再使用 libmms 的函數。
參考資料:
1. http://sourceforge.net/projects/libmms/
2. http://www.wunderradio.com/code.html
3. http://biancheng.dnbcw.info/c/257462.html
4. http://fryfishtw.pixnet.net/blog/post/24293699-台灣網路廣播電台清單
5. http://stackoverflow.com/questions/7464851/libiconv-not-linking-to-ios-project