[
  {
    "path": ".classpath",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<classpath>\n\t<classpathentry kind=\"src\" path=\"src\"/>\n\t<classpathentry kind=\"src\" path=\"gen\"/>\n\t<classpathentry kind=\"con\" path=\"com.android.ide.eclipse.adt.ANDROID_FRAMEWORK\"/>\n\t<classpathentry exported=\"true\" kind=\"con\" path=\"com.android.ide.eclipse.adt.LIBRARIES\"/>\n\t<classpathentry exported=\"true\" kind=\"con\" path=\"com.android.ide.eclipse.adt.DEPENDENCIES\"/>\n\t<classpathentry kind=\"output\" path=\"bin/classes\"/>\n</classpath>\n"
  },
  {
    "path": ".gitignore",
    "content": "# built application files\n*.apk\n*.ap_\n\n# files for the dex VM\n*.dex\n\n# Java class files\n*.class\n\n# generated files\nbin/\ngen/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n"
  },
  {
    "path": ".project",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>OPlayer</name>\n\t<comment></comment>\n\t<projects>\n\t</projects>\n\t<buildSpec>\n\t\t<buildCommand>\n\t\t\t<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t\t<buildCommand>\n\t\t\t<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t\t<buildCommand>\n\t\t\t<name>org.eclipse.jdt.core.javabuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t\t<buildCommand>\n\t\t\t<name>com.android.ide.eclipse.adt.ApkBuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t</buildSpec>\n\t<natures>\n\t\t<nature>com.android.ide.eclipse.adt.AndroidNature</nature>\n\t\t<nature>org.eclipse.jdt.core.javanature</nature>\n\t</natures>\n</projectDescription>\n"
  },
  {
    "path": "AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.nmbb.oplayer\"\n    android:versionCode=\"1\"\n    android:versionName=\"1.0\" >\n\n    <uses-sdk\n        android:minSdkVersion=\"7\"\n        android:targetSdkVersion=\"15\" />\n\n    <uses-permission android:name=\"android.permission.WRITE_SETTINGS\" />\n    <uses-permission android:name=\"android.permission.WAKE_LOCK\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.READ_PHONE_STATE\" />\n    <uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\" />\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.BROADCAST_STICKY\" />\n    <uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\" />\n    <uses-permission android:name=\"android.permission.CHANGE_WIFI_MULTICAST_STATE\" />\n    <uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />\n    <uses-permission android:name=\"android.permission.GET_TASKS\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n\n    <application\n        android:name=\".OPlayerApplication\"\n        android:icon=\"@drawable/icon\"\n        android:label=\"@string/app_name\"\n        android:theme=\"@style/AppTheme\" >\n        <activity\n            android:name=\".ui.MainActivity\"\n            android:configChanges=\"orientation|keyboard|keyboardHidden|navigation\"\n            android:label=\"@string/app_name\"\n            android:screenOrientation=\"portrait\"\n            android:theme=\"@android:style/Theme.NoTitleBar\" >\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".ui.player.VideoActivity\"\n            android:configChanges=\"orientation|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation\"\n            android:label=\"@string/app_name\"\n            android:launchMode=\"singleTop\"\n            android:process=\":vitamio\"\n            android:screenOrientation=\"landscape\"\n            android:theme=\"@android:style/Theme.NoTitleBar\"\n            android:windowSoftInputMode=\"stateAlwaysHidden\" >\n            <intent-filter>\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n\n                <data\n                    android:mimeType=\"audio/*\"\n                    android:scheme=\"http\" />\n                <data\n                    android:mimeType=\"audio/*\"\n                    android:scheme=\"rtsp\" />\n                <data\n                    android:mimeType=\"audio/*\"\n                    android:scheme=\"rtmp\" />\n                <data\n                    android:mimeType=\"audio/*\"\n                    android:scheme=\"udp\" />\n                <data\n                    android:mimeType=\"audio/*\"\n                    android:scheme=\"tcp\" />\n                <data\n                    android:mimeType=\"audio/*\"\n                    android:scheme=\"file\" />\n                <data\n                    android:mimeType=\"audio/*\"\n                    android:scheme=\"content\" />\n                <data\n                    android:mimeType=\"audio/*\"\n                    android:scheme=\"mms\" />\n                <data\n                    android:mimeType=\"video/*\"\n                    android:scheme=\"http\" />\n                <data\n                    android:mimeType=\"video/*\"\n                    android:scheme=\"rtsp\" />\n                <data\n                    android:mimeType=\"video/*\"\n                    android:scheme=\"rtmp\" />\n                <data\n                    android:mimeType=\"video/*\"\n                    android:scheme=\"udp\" />\n                <data\n                    android:mimeType=\"video/*\"\n                    android:scheme=\"tcp\" />\n                <data\n                    android:mimeType=\"video/*\"\n                    android:scheme=\"file\" />\n                <data\n                    android:mimeType=\"video/*\"\n                    android:scheme=\"content\" />\n                <data\n                    android:mimeType=\"video/*\"\n                    android:scheme=\"mms\" />\n                <data android:mimeType=\"application/octet-stream\" />\n                <data android:mimeType=\"application/x-mpegurl\" />\n                <data android:mimeType=\"application/vnd.apple.mpegurl\" />\n            </intent-filter>\n            <intent-filter>\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data android:scheme=\"content\" />\n            </intent-filter>\n            <intent-filter>\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n\n                <data\n                    android:mimeType=\"application/x-mpegurl\"\n                    android:scheme=\"http\" />\n            </intent-filter>\n            <intent-filter>\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n\n                <data android:scheme=\"rtsp\" />\n                <data android:scheme=\"rtmp\" />\n                <data android:scheme=\"mms\" />\n                <data android:scheme=\"tcp\" />\n                <data android:scheme=\"udp\" />\n            </intent-filter>\n            <intent-filter>\n                <action android:name=\"android.intent.action.VIEW\" />\n                <action android:name=\"android.intent.action.SEND\" />\n                <action android:name=\"android.intent.action.SENDTO\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data android:mimeType=\"video/*\" />\n                <data android:mimeType=\"application/sdp\" />\n                <data android:mimeType=\"application/octet-stream\" />\n            </intent-filter>\n            <intent-filter>\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n\n                <data android:scheme=\"http\" />\n                <data android:mimeType=\"video/*\" />\n            </intent-filter>\n            <intent-filter>\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n\n                <data android:scheme=\"file\" />\n                <data android:scheme=\"content\" />\n                <data android:scheme=\"http\" />\n                <data android:scheme=\"https\" />\n                <data android:scheme=\"ftp\" />\n                <data android:scheme=\"rtsp\" />\n                <data android:scheme=\"rtmp\" />\n                <data android:scheme=\"mms\" />\n                <data android:scheme=\"tcp\" />\n                <data android:scheme=\"udp\" />\n                <data android:scheme=\"gopher\" />\n                <data android:mimeType=\"video/*\" />\n                <data android:mimeType=\"audio/*\" />\n            </intent-filter>\n            <intent-filter>\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n\n                <data android:scheme=\"file\" />\n                <data android:scheme=\"content\" />\n                <data android:scheme=\"http\" />\n                <data android:scheme=\"https\" />\n                <data android:scheme=\"ftp\" />\n                <data android:scheme=\"rtsp\" />\n                <data android:scheme=\"rtmp\" />\n                <data android:scheme=\"mms\" />\n                <data android:scheme=\"tcp\" />\n                <data android:scheme=\"udp\" />\n                <data android:scheme=\"gopher\" />\n                <data android:host=\"*\" />\n                <data android:pathPattern=\".*\\\\.avi\" />\n                <data android:pathPattern=\".*\\\\.asf\" />\n                <data android:pathPattern=\".*\\\\.f4v\" />\n                <data android:pathPattern=\".*\\\\.flv\" />\n                <data android:pathPattern=\".*\\\\.mkv\" />\n                <data android:pathPattern=\".*\\\\.mpeg\" />\n                <data android:pathPattern=\".*\\\\.mpg\" />\n                <data android:pathPattern=\".*\\\\.mov\" />\n                <data android:pathPattern=\".*\\\\.rm\" />\n                <data android:pathPattern=\".*\\\\.vob\" />\n                <data android:pathPattern=\".*\\\\.wmv\" />\n                <data android:pathPattern=\".*\\\\.ts\" />\n                <data android:pathPattern=\".*\\\\.tp\" />\n                <data android:pathPattern=\".*\\\\.m3u\" />\n                <data android:pathPattern=\".*\\\\.m3u8\" />\n                <data android:pathPattern=\".*\\\\.m4v\" />\n                <data android:pathPattern=\".*\\\\.mp4\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".PlayerActivity\"\n            android:configChanges=\"orientation|keyboard|keyboardHidden|navigation\"\n            android:label=\"@string/app_name\"\n            android:theme=\"@android:style/Theme.NoTitleBar.Fullscreen\" >\n        </activity>\n        <activity\n            android:name=\"com.nmbb.oplayer.ui.vitamio.InitActivity\"\n            android:configChanges=\"orientation|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation\"\n            android:launchMode=\"singleTop\"\n            android:theme=\"@android:style/Theme.NoTitleBar\"\n            android:windowSoftInputMode=\"stateAlwaysHidden\" />\n\n        <receiver android:name=\".receiver.MediaScannerReceiver\" >\n\n            <!-- 重启 -->\n            <intent-filter>\n                <action android:name=\"android.intent.action.BOOT_COMPLETED\" />\n            </intent-filter>\n            <intent-filter>\n                <action android:name=\"android.intent.action.MEDIA_MOUNTED\" />\n\n                <data android:scheme=\"file\" />\n            </intent-filter>\n            <!-- 文件更改 -->\n            <intent-filter>\n                <action android:name=\"com.nmbb.oplayer.action.MEDIA_SCANNER_SCAN_FILE\" />\n                <action android:name=\"com.nmbb.oplayer.action.MEDIA_SCANNER_SCAN_DIRECTORY\" />\n\n                <data android:scheme=\"file\" />\n            </intent-filter>\n        </receiver>\n\n        <service\n            android:name=\".ui.player.PlayerService\"\n            android:process=\":vitamio\" />\n        <service\n            android:name=\"io.vov.vitamio.VitamioService\"\n            android:exported=\"false\" >\n            <intent-filter>\n                <action android:name=\"io.vov.vitamio.IVitamioService\" />\n            </intent-filter>\n        </service>\n        <service android:name=\".service.MediaScannerService\" />\n    </application>\n\n</manifest>"
  },
  {
    "path": "LICENSE",
    "content": ""
  },
  {
    "path": "README.md",
    "content": "OPlayer\n=======\n\nAndroid平台基于Vitamio的开源播放器\n\n支持以下协议的音频和视频播放：\n* MMS\n* RTSP (RTP, SDP)\n* HTTP流式传输(progressive streaming)\n* HTTP Live Streaming (M3U8), Android 2.1+\nVitamio集成了许多音频和视频的解码包，相比Android内置默认的媒体格式，这里列出其中的一些：\n* divx/xvid\n* wmv\n* flv\n* ts\n* rmvb\n* mkv\n* mov\n* m4v\n* avi\n* mp4\n* 3gp\n\n==\nVitamio官网：\nhttp://vitamio.org\n\n==\n我的博客：\nhttp://www.cnblogs.com/over140/\n\n==\nVitamio系列文章：\nhttp://www.cnblogs.com/over140/category/409230.html\n\n==\n依赖Vitamio，下载最新的Vitamio：\nhttps://github.com/yixia/VitamioBundle"
  },
  {
    "path": "assets/online.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<list>\n  <head>\n    <version>1.1.0</version>\n    <title>default stream</title>\n  </head>\n  <body>\n    <media id=\"001\" version=\"21\" title=\"CCTV-1 综合\" image=\"http://cn.daroonsoft.com/images/cctv_1.png\" guide=\"cctv1\">\n        <ref href=\"mms://www.xjklmy.com/tv-6\" width=\"384\" height=\"288\" bitrate=\"755\" />\n                <ref href=\"rtsp://114.255.201.246/cctv1_256_h264.sdp\" width=\"320\" height=\"240\" bitrate=\"264\" />\n                <ref href=\"rtsp://116.199.127.68/cctv1_HD\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n                <ref href=\"rtmp://live.cditv.cn/test/CCTV1\" width=\"320\" height=\"240\" bitrate=\"548\" />\n                <ref href=\"rtsp://bupt01.video.edu.cn/CCTV-1\" width=\"640\" height=\"480\" bitrate=\"412\" />\n                <ref href=\"rtsp://116.199.127.68/cctv1_HD\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n                <ref href=\"rtsp://211.138.120.114/cctv1\" width=\"512\" height=\"384\" bitrate=\"544\" />\n                <ref href=\"http://cntv.itv.doplive.com.cn/live591/index_128k.m3u8\" width=\"320\" height=\"240\" bitrate=\"256\" />\n    </media>\n    <media id=\"002\" version=\"18\" title=\"CCTV-2 财经\" image=\"http://cn.daroonsoft.com/images/cctv_2.png\"  guide=\"cctv2\">\n        <ref href=\"mms://bupt02.video.edu.cn/CCTV-2\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"rtsp://114.255.201.246/cctv2_256_h264.sdp\" width=\"320\" height=\"240\" bitrate=\"548\" />\n                <ref href=\"mms://211.138.120.114/cctv2\" width=\"512\" height=\"384\" bitrate=\"544\" />\n                <ref href=\"http://cntv.itv.doplive.com.cn/live592/index_128k.m3u8\" width=\"320\" height=\"240\" bitrate=\"256\" />\n    </media>\n    <media id=\"003\" version=\"15\" title=\"CCTV-3 综艺\" image=\"http://cn.daroonsoft.com/images/cctv_3.png\"  guide=\"cctv3\"\n        desc=\"中央电视台综艺频道是以播出音乐及歌舞节目为主的专业频道，于1995年11月30日正式播出，通过亚太1A卫星覆盖全国，每天播出19小时左右。\" >\n                <ref href=\"rtsp://114.255.201.246/cctv3_256_h264.sdp\" width=\"320\" height=\"240\" bitrate=\"264\" />\n                <ref href=\"mms://211.138.120.114/cctv3\" width=\"512\" height=\"384\" bitrate=\"544\" />\n                <ref href=\"rtsp://116.199.127.68/cctv3\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n                <ref href=\"http://cntv.itv.doplive.com.cn/live593/index_128k.m3u8\" width=\"320\" height=\"240\" bitrate=\"256\" />\n    </media>\n    <media id=\"004\" version=\"19\" title=\"CCTV-4 中文国际（亚）\" image=\"http://cn.daroonsoft.com/images/cctv_4.png\"  guide=\"cctv4\" \n        desc=\"中央电视台国际频道是以海外华人、华侨和港、澳、台为主要服务对象的专业频道，于1992年10月1日开播。国际频道的播出信号采用数字压缩技术，通过多颗国际卫星传输，基本实现了卫星传输信号的全球覆盖和卫星直播信号的重点地区覆盖。\">\n        <ref href=\"mms://bupt02.video.edu.cn/CCTV-4\" width=\"640\" height=\"480\" bitrate=\"632\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=11\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"mms://211.138.120.114/cctv4\" width=\"512\" height=\"384\" bitrate=\"544\" />\n                <ref href=\"http://cntv.itv.doplive.com.cn/live594/index_128k.m3u8\" width=\"320\" height=\"240\" bitrate=\"256\" />\n    </media>\n    <media id=\"005\" version=\"24\" title=\"CCTV-5 体育\" image=\"http://cn.daroonsoft.com/images/cctv_5.png\"  guide=\"cctv5\" \n        desc=\"中央电视台体育频道是国内创办最早、规模最大、拥有世界众多顶级赛事国内独家报道权的专业体育频道，于1995年1月1日正式开播，通过亚太1A卫星覆盖全国，每天平均播出16小时以上。\" >\n                <ref href=\"http://112.231.23.20:554/rtplive/tv18/playlist.m3u8\" width=\"320\" height=\"240\" bitrate=\"548\" />\n                <ref href=\"rtmp://live.cditv.cn/test/CCTV5\" width=\"320\" height=\"240\" bitrate=\"548\" />\n                <ref href=\"rtsp://114.255.201.246/cctv5_256_h264.sdp\" width=\"320\" height=\"240\" bitrate=\"548\" />\n                <ref href=\"rtsp://116.199.127.68/cctv5\" width=\"720\" height=\"576\" bitrate=\"800\" />\n                <ref href=\"rtmp://202.108.17.140/multicast/livestream\" width=\"480\" height=\"320\" bitrate=\"600\" />\n                <ref href=\"rtsp://bupt01.video.edu.cn/CCTV-5\" width=\"640\" height=\"480\" bitrate=\"632\" />\n                <ref href=\"rtsp://211.138.120.114/cctv5\" width=\"512\" height=\"384\" bitrate=\"544\" />\n                <ref href=\"rtsp://media.zzti.edu.cn/cctv5\" width=\"320\" height=\"240\" bitrate=\"548\" />\n                <ref href=\"http://cntv.itv.doplive.com.cn/live595/index_128k.m3u8\" width=\"320\" height=\"240\" bitrate=\"256\" />\n    </media>\n    <media id=\"006\" version=\"17\" title=\"CCTV-6 电影\" image=\"http://cn.daroonsoft.com/images/cctv_6.png\"  guide=\"cctv6\"\n        desc=\"中央电视台电影频道是以宣传电影、培养电影观众、传播影视文化为宗旨的专业频道，于1996年1月1日正式开播，通过亚太1A卫星覆盖全国，每天平均播出近17小时。\" >\n        <ref href=\"mms://bupt02.video.edu.cn/CCTV-6\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"rtsp://114.255.201.246/cctv6_256_h264.sdp\" width=\"320\" height=\"240\" bitrate=\"548\" />\n                <ref href=\"mms://211.138.120.114/cctv6\" width=\"512\" height=\"384\" bitrate=\"544\" />\n                <ref href=\"rtsp://116.199.127.68/cctv6\" width=\"720\" height=\"576\" bitrate=\"800\" />\n                <ref href=\"http://live512.itv.doplive.com.cn/live512/index_128k.m3u8\" width=\"320\" height=\"240\" bitrate=\"256\" />\n    </media>\n    <media id=\"007\" version=\"11\" title=\"CCTV-7 军事 农业\" image=\"http://cn.daroonsoft.com/images/cctv_7.png\"  guide=\"cctv7\"\n        desc=\"中央电视台少儿·军事·农业频道是以播出少儿、军事、农业节目为主的专业频道，于1995年11月30日开播，通过亚太1A卫星覆盖全国。平均每日播出近17个小时。\" >\n        <ref href=\"mms://bupt02.video.edu.cn/CCTV-7\" width=\"640\" height=\"480\" bitrate=\"632\" />\n                <ref href=\"http://cntv.itv.doplive.com.cn/live597/index_900k.m3u8\" width=\"320\" height=\"240\" bitrate=\"256\" />\n    </media>\n    <media id=\"008\" version=\"12\" title=\"CCTV-8 电视剧\" image=\"http://cn.daroonsoft.com/images/cctv_8.png\"  guide=\"cctv8\"\n        desc=\"中央电视台电视剧频道是以优秀电视剧为主要播出内容的专业频道，于1999年5月3日开播，通过亚太1A卫星覆盖全国，平均每天播出17小时。\" >\n        <ref href=\"mms://bupt02.video.edu.cn/CCTV-8\" width=\"640\" height=\"480\" bitrate=\"632\" />\n                <ref href=\"rtsp://114.255.201.246/cctv8_256_h264.sdp\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"mms://211.138.120.114/cctv8\" width=\"512\" height=\"384\" bitrate=\"544\" />\n                <ref href=\"rtsp://116.199.127.68/cctv8\" width=\"720\" height=\"576\" bitrate=\"800\" />\n    </media>\n    <media id=\"009\" version=\"17\" title=\"CCTV-News\" image=\"http://cn.daroonsoft.com/images/cctv_news.png\"  guide=\"\">\n        <ref href=\"http://cntv.itv.doplive.com.cn/live599/index_128k.m3u8\" width=\"320\" height=\"240\" bitrate=\"256\" />\n        <ref href=\"mms://bupt02.video.edu.cn/CCTV-9\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"mms://222.47.26.81/litv11\" width=\"320\" height=\"240\" bitrate=\"256\" />\n                <ref href=\"mms://4.71.37.8/cctv9-200\" width=\"320\" height=\"240\" bitrate=\"256\" />\n                <ref href=\"mms://211.138.120.114/cctv9\" width=\"512\" height=\"384\" bitrate=\"544\" />\n    </media>\n    <media id=\"010\" version=\"12\" title=\"CCTV-9 纪录\" image=\"http://cn.daroonsoft.com/images/cctv_9.png\"  guide=\"cctv9\">\n        <ref href=\"mms://media.zzti.edu.cn/cctvnews/\" width=\"320\" height=\"240\" bitrate=\"256\" />\n        <ref href=\"http://t.live.cntv.cn/m3u8/cctv9-jilu.m3u8\" width=\"720\" height=\"576\" bitrate=\"800\" />\n                <ref href=\"rtmp://live.cditv.cn/test/CCTV9\" width=\"320\" height=\"240\" bitrate=\"548\" />\n    </media>\n    <media id=\"011\" version=\"10\" title=\"CCTV-10 科教\" image=\"http://cn.daroonsoft.com/images/cctv_10.png\"  guide=\"cctv10\"\n        desc=\"中央电视台科学·教育频道(CCTV-10)，是因应国家“科教兴国”方略，以提高国民素质为宗旨，以教科文题材为内容的专业电视频道。\" >\n        <ref href=\"mms://bupt02.video.edu.cn/CCTV-10\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"mms://211.138.120.114/cctv10\" width=\"512\" height=\"384\" bitrate=\"544\" />\n    </media>\n    <media id=\"012\" version=\"6\" title=\"CCTV-11 戏曲\" image=\"http://cn.daroonsoft.com/images/cctv_11.png\"  guide=\"cctv11\"\n        desc=\"中央电视台戏曲频道以弘扬和发展我国优秀戏曲艺术，满足戏迷审美要求为宗旨的专业频道，于2001年7月9日开播。\" >\n        <ref href=\"mms://bupt02.video.edu.cn/CCTV-11\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n        <ref href=\"http://t.live.cntv.cn/m3u8/cctv-xiqu.m3u8\" width=\"720\" height=\"576\" bitrate=\"800\" />\n    </media>\n    <media id=\"013\" version=\"9\" title=\"CCTV-12 社会与法\" image=\"http://cn.daroonsoft.com/images/cctv_12.png\" guide=\"cctv12\">\n        <ref href=\"mms://bupt02.video.edu.cn/CCTV-12\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n        <ref href=\"http://t.live.cntv.cn/m3u8/cctv12.m3u8\" width=\"720\" height=\"576\" bitrate=\"800\" />\n                <ref href=\"rtsp://114.255.201.246/cctv12_256_h264.sdp\" width=\"720\" height=\"576\" bitrate=\"800\" />\n                <ref href=\"http://202.108.39.103:554/57?.flv\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"mms://211.138.120.114/cctv12\" width=\"512\" height=\"384\" bitrate=\"544\" />\n    </media>\n    <media id=\"014\" version=\"23\" title=\"CCTV-13 新闻\" image=\"http://cn.daroonsoft.com/images/cctv_13.png\" guide=\"cctvxwpd\" \n        desc=\"新闻频道全天24小时播出，全天24档整点新闻。整点新闻将以最快的速度向观众提供第一手的国内国际新闻资讯，突出时效性和信息量，实现滚动、递进、更新式报道。整点新闻后，分别安排了各分类新闻，主要有财经、体育、文化、国际四大类。\" >\n        <ref href=\"http://cntv.itv.doplive.com.cn/live603/index_900k.m3u8\" width=\"648\" height=\"480\" bitrate=\"900\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=1\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"http://ora.t.live.cntv.cn/live/test?fmt=x264_0K_flv\" width=\"720\" height=\"576\" bitrate=\"800\" />\n                <ref href=\"mms://211.138.120.114/cctvxw\" width=\"512\" height=\"384\" bitrate=\"544\" />\n    </media>\n        <media id=\"216\" version=\"5\" title=\"CCTV-14 少儿\" image=\"http://cn.daroonsoft.com/images/cctv_shaoer.png\" guide=\"cctvsepd\">\n                <ref href=\"rtsp://211.68.71.252/CCTV-kid\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"rtsp://bupt01.video.edu.cn/CCTV-kid\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n        <media id=\"370\" version=\"1\" title=\"CCTV-15 音乐\" image=\"http://cn.daroonsoft.com/images/cctv_music.png\" guide=\"cctvylpd\">\n                <ref href=\"rtsp://bupt01.video.edu.cn/CCTV-music\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n        <media id=\"366\" version=\"2\" title=\"CCTV-风云足球\" image=\"http://cn.daroonsoft.com/images/ffzq.png\"  guide=\"fyzq\">\n                <ref href=\"rtmp://livertmp.wasu.cn/live4/fyzq\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n        <media id=\"214\" version=\"1\" title=\"CCTV高清\" image=\"http://cn.daroonsoft.com/images/cctv_gaoqing.png\" guide=\"cctv-gq\"  >\n                <ref href=\"rtmp://202.108.17.104/live/test02\" width=\"720\" height=\"480\" bitrate=\"1044\" />\n        </media>\n    <media id=\"072\" version=\"10\" title=\"中国教育—1\" image=\"http://cn.daroonsoft.com/images/cetv.png\" guide=\"jyyt\"  >\n        <ref href=\"mms://bupt02.video.edu.cn/CETV-1\" width=\"640\" height=\"480\" bitrate=\"1044\" />         \n                <ref href=\"http://gslb.tv.sohu.com/live?cid=30\" width=\"640\" height=\"480\" bitrate=\"1044\" />   \n    </media>\n    <media id=\"073\" version=\"6\" title=\"中国教育—3\" image=\"http://cn.daroonsoft.com/images/cetv.png\" guide=\"jyst\"  >\n        <ref href=\"mms://bupt02.video.edu.cn/CETV-3\" width=\"640\" height=\"480\" bitrate=\"1440\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=29\" width=\"640\" height=\"480\" bitrate=\"1440\" />\n    </media>\n        <media id=\"367\" version=\"1\" title=\"欧洲足球\" image=\"http://cn.daroonsoft.com/images/oozq.png\"  guide=\"\">\n                <ref href=\"rtmp://livertmp.wasu.cn/live/ozzq\" width=\"320\" height=\"240\" bitrate=\"128\" />\n    </media>\n    <media id=\"018\" version=\"28\" title=\"湖南卫视\" image=\"http://cn.daroonsoft.com/images/hunantv.png\" guide=\"hunanws\">\n        <ref href=\"mms://222.47.26.81/litv09\" width=\"320\" height=\"240\" bitrate=\"548\" />\n        <ref href=\"http://gslb.tv.sohu.com/live?cid=44\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=9\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"rtsp://121.14.129.221/broadcast/pushfeeder/rtpencoder/hnws-s.sdp\" width=\"176\" height=\"144\" bitrate=\"156\" />\n                <ref href=\"http://180.153.212.207:1863/18091377.flv\" width=\"720\" height=\"402\" bitrate=\"1044\" />\n    </media>\n        <media id=\"022\" version=\"4\" title=\"金鹰卡通\" image=\"http://cn.daroonsoft.com/images/hunantv.png\" guide=\"hnjykt\">\n        <ref href=\"rtmp://livertmp.wasu.cn/live7/jykt\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n    <media id=\"112\" version=\"6\" title=\"长沙新闻\" image=\"http://cn.daroonsoft.com/images/changshatv.png\" guide=\"csxwpd\">\n        <ref href=\"mms://222.240.196.154/xinwenlive\" width=\"320\" height=\"240\" bitrate=\"421\" />\n    </media>\n    <media id=\"113\" version=\"5\" title=\"长沙政法\" image=\"http://cn.daroonsoft.com/images/changshatv.png\" guide=\"cszfpd\">\n        <ref href=\"mms://222.240.196.154/live\" width=\"320\" height=\"240\" bitrate=\"421\" />\n    </media>\n    <media id=\"114\" version=\"4\" title=\"长沙女性\" image=\"http://cn.daroonsoft.com/images/changshatv.png\" guide=\"csnxpd\">\n        <ref href=\"mms://222.240.196.154/wmlive\" width=\"320\" height=\"240\" bitrate=\"421\" />\n    </media>\n    <media id=\"027\" version=\"20\" title=\"上海东方卫视\" image=\"http://cn.daroonsoft.com/images/dongfangtv.png\" guide=\"dfaws\">\n        <ref href=\"mms://bupt02.video.edu.cn/SHWS\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=3\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"http://112.90.11.88:1863/3900155972.flv\" width=\"720\" height=\"402\" bitrate=\"1044\" />\n                <ref href=\"rtsp://116.199.127.68/dongfang\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n        <media id=\"372\" version=\"6\" title=\"东方财经\" image=\"http://cn.daroonsoft.com/images/dongfangtv.png\" guide=\"\"  >\n                <ref href=\"http://edgews.yicai.com/channels/602/400.flv/live\" width=\"640\" height=\"480\" bitrate=\"900\" />\n    </media>\n    <media id=\"126\" version=\"7\" title=\"五星体育\" image=\"http://cn.daroonsoft.com/images/shanghaitv.png\" guide=\"sitvwxty\">\n        <ref href=\"http://live-cdn.smgbb.tv/channels/214/400.flv/live\" width=\"480\" height=\"348\" bitrate=\"600\" />\n    </media>\n    <media id=\"111\" version=\"6\" title=\"第一财经\" image=\"http://cn.daroonsoft.com/images/cbnlogo.png\" guide=\"ssdycjpd\">\n        <ref href=\"mms://clientcbn.bbtv.cn/clientcbn\" width=\"320\" height=\"240\" bitrate=\"548\" />\n        <ref href=\"http://live-cdn.smgbb.tv/channels/212/400.flv/live\" width=\"480\" height=\"348\" bitrate=\"600\" />\n    </media>\n    <media id=\"127\" version=\"4\" title=\"上海新闻综合\" image=\"http://cn.daroonsoft.com/images/shanghaitv.png\" guide=\"ssxwzhpd\">\n        <ref href=\"http://live-cdn.smgbb.tv/channels/210/400.flv/live\" width=\"480\" height=\"348\" bitrate=\"600\" />\n    </media>\n    <media id=\"128\" version=\"4\" title=\"上海星尚\" image=\"http://cn.daroonsoft.com/images/shanghaitv.png\" guide=\"\">\n        <ref href=\"http://live-cdn.smgbb.tv/channels/211/400.flv/live\" width=\"480\" height=\"348\" bitrate=\"600\" />\n    </media>\n    <media id=\"130\" version=\"4\" title=\"上海纪实\" image=\"http://cn.daroonsoft.com/images/shanghaitv.png\" guide=\"ssjspd\">\n        <ref href=\"http://live-cdn.smgbb.tv/channels/215/400.flv/live\" width=\"480\" height=\"348\" bitrate=\"600\" />\n    </media>\n    <media id=\"131\" version=\"4\" title=\"上海娱乐\" image=\"http://cn.daroonsoft.com/images/shanghaitv.png\" guide=\"ssxwylpd\">\n        <ref href=\"http://live-cdn.smgbb.tv/channels/217/400.flv/live\" width=\"480\" height=\"348\" bitrate=\"600\" />\n    </media>\n    <media id=\"132\" version=\"4\" title=\"上海艺术人文\" image=\"http://cn.daroonsoft.com/images/shanghaitv.png\" guide=\"\">\n        <ref href=\"http://live-cdn.smgbb.tv/channels/218/400.flv/live\" width=\"480\" height=\"348\" bitrate=\"600\" />\n    </media>\n    <media id=\"133\" version=\"4\" title=\"上海ICS外语频道\" image=\"http://cn.daroonsoft.com/images/shanghaitv.png\" guide=\"\">\n        <ref href=\"http://live-cdn.smgbb.tv/channels/220/400.flv/live\" width=\"480\" height=\"348\" bitrate=\"600\" />\n    </media>\n        <media id=\"240\" version=\"1\" title=\"东方购物\" image=\"http://cn.daroonsoft.com/images/shanghaitv.png\" guide=\"\">\n        <ref href=\"http://live-cdn.smgbb.tv/channels/219/400.flv/live\" width=\"480\" height=\"348\" bitrate=\"600\" />\n    </media>\n        <media id=\"320\" version=\"1\" title=\"游戏风云\" image=\"http://cn.daroonsoft.com/images/shanghaitv.png\" guide=\"sitvyxfy\">\n        <ref href=\"http://live-cdn.smgbb.tv/channels/293/400.flv/live\" width=\"480\" height=\"348\" bitrate=\"409\" />\n    </media>\n    <media id=\"373\" version=\"6\" title=\"生活时尚\" image=\"http://cn.daroonsoft.com/images/eastmovie.png\" guide=\"\"  >\n        <ref href=\"http://live-cdn.smgbb.tv/channels/222/400.flv/live\" width=\"320\" height=\"240\" bitrate=\"256\" />\n    </media>\n        <media id=\"108\" version=\"9\" title=\"炫动卡通\" image=\"http://cn.daroonsoft.com/images/xuandongkatongtv.png\" guide=\"\">\n                <ref href=\"http://live-cdn.smgbb.tv/channels/224/400.flv/live\" width=\"480\" height=\"348\" bitrate=\"600\" />\n    </media>\n        <media id=\"368\" version=\"1\" title=\"劲爆体育\" image=\"http://cn.daroonsoft.com/images/jbty.png\"  guide=\"sitvjbty\" >\n                <ref href=\"rtmp://livertmp.wasu.cn/live5/jbty\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n    <media id=\"036\" version=\"16\" title=\"北京卫视\" image=\"http://cn.daroonsoft.com/images/btv.png\" guide=\"btv1\">\n        <ref href=\"mms://bupt02.video.edu.cn/BTV-1\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"http://biz.vsdn.tv380.com/playlive.php?5B63686E5D445830303030303035307C313430367C317C323030307C474754567C687474705B2F63686E5D5B74735D307C687474705B2F74735DVSDNSOOONERCOM00\" width=\"768\" height=\"576\" bitrate=\"1044\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=36\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"rtsp://116.199.127.68/beijing\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n    <media id=\"085\" version=\"4\" title=\"北京影视\" image=\"http://cn.daroonsoft.com/images/btv.png\" guide=\"btv4\">\n        <ref href=\"mms://bupt02.video.edu.cn/BTV-5\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n    <media id=\"086\" version=\"5\" title=\"北京文艺\" image=\"http://cn.daroonsoft.com/images/btv.png\" guide=\"btv2\">\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=37\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n    <media id=\"087\" version=\"5\" title=\"北京生活\" image=\"http://cn.daroonsoft.com/images/btv.png\" guide=\"btv7\">\n        <ref href=\"mms://bupt02.video.edu.cn/BTV-7\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n    <media id=\"088\" version=\"5\" title=\"北京科教\" image=\"http://cn.daroonsoft.com/images/btv.png\" guide=\"btv3\"  >\n        <ref href=\"mms://bupt02.video.edu.cn/BTV-3\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=38\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n    <media id=\"089\" version=\"5\" title=\"北京财经\" image=\"http://cn.daroonsoft.com/images/btv.png\" guide=\"btv5\"  >\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=40\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n    <media id=\"090\" version=\"5\" title=\"北京青年\" image=\"http://cn.daroonsoft.com/images/btv.png\" guide=\"btv8\"  >\n        <ref href=\"mms://bupt02.video.edu.cn/BTV-8\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n    <media id=\"094\" version=\"6\" title=\"北京体育\" image=\"http://cn.daroonsoft.com/images/btv.png\" guide=\"btv6\"  >\n        <ref href=\"mms://bupt02.video.edu.cn/BTV-6\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n        <media id=\"115\" version=\"1\" title=\"杭州综合频道\" image=\"http://cn.daroonsoft.com/images/hangzhoutv.png\" guide=\"hzzhpd\"  >\n        <ref href=\"http://live.hcrt.cn/channels/100/400.flv/live\" width=\"480\" height=\"360\" bitrate=\"450\" />\n    </media>\n        <media id=\"116\" version=\"1\" title=\"杭州西湖明珠频道\" image=\"http://cn.daroonsoft.com/images/hangzhoutv.png\" guide=\"hzxhmzpd\"  >\n        <ref href=\"http://live.hcrt.cn/channels/101/400.flv/live\" width=\"480\" height=\"360\" bitrate=\"450\" />\n    </media>\n        <media id=\"117\" version=\"2\" title=\"杭州生活频道\" image=\"http://cn.daroonsoft.com/images/hangzhoutv.png\" guide=\"hzshpd\"  >\n        <ref href=\"http://live.hcrt.cn/channels/102/400.flv/live\" width=\"480\" height=\"360\" bitrate=\"450\" />\n    </media>\n    <media id=\"118\" version=\"5\" title=\"杭州影视频道\" image=\"http://cn.daroonsoft.com/images/hangzhoutv.png\" guide=\"hzyspd\"  >\n                <ref href=\"http://live.hcrt.cn/channels/39/400.flv/live\" width=\"384\" height=\"288\" bitrate=\"450\" />\n                <ref href=\"rtsp://211.138.120.114/ztv5\" width=\"512\" height=\"384\" bitrate=\"544\" />\n    </media>\n        <media id=\"119\" version=\"2\" title=\"杭州少儿频道\" image=\"http://cn.daroonsoft.com/images/hangzhoutv.png\" guide=\"hzsepd\"  >\n        <ref href=\"http://live.hcrt.cn/channels/40/400.flv/live\" width=\"480\" height=\"384\" bitrate=\"450\" />\n    </media>\n        <media id=\"202\" version=\"2\" title=\"房产频道\" image=\"http://cn.daroonsoft.com/images/hangzhoutv.png\" guide=\"\"  >\n                <ref href=\"http://58.248.254.7:1935/live/ifcpd.sdp/playlist.m3u8\" width=\"320\" height=\"240\" bitrate=\"128\" />\n        </media>\n    <media id=\"037\" version=\"14\" title=\"江西卫视\" image=\"http://cn.daroonsoft.com/images/jiangxitv.png\" guide=\"jxws\"  >\n        <ref href=\"http://biz.vsdn.tv380.com/playlive.php?5B63686E5D445830303030303035307C313531347C317C323030307CE74754567C687474705B2F63686E5D5B74735D307C687474705B2F74735DVSDNSOOONERCOM00\" width=\"768\" height=\"576\" bitrate=\"1044\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=18\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"rtmp://live.cjxtv.com:1935/live2/livestream\" width=\"320\" height=\"240\" bitrate=\"128\" />\n    </media>\n    <media id=\"038\" version=\"10\" title=\"广西卫视\" image=\"http://cn.daroonsoft.com/images/guangxi.png\" guide=\"gxws\"  >\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=23\" width=\"640\" height=\"480\" bitrate=\"1240\" />\n                <ref href=\"http://222.216.111.88:5000/nn_live.flv?id=1004\" width=\"640\" height=\"480\" bitrate=\"1240\" />\n    </media>\n    <media id=\"039\" version=\"14\" title=\"河南卫视\" image=\"http://cn.daroonsoft.com/images/henantv.png\" guide=\"henanws\"  >\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=19\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n    <media id=\"040\" version=\"13\" title=\"湖北卫视\" image=\"http://cn.daroonsoft.com/images/hubeitv.png\" guide=\"hubeiws\"  >\n        <ref href=\"rtsp://bupt01.video.edu.cn/HBWS\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"http://live9.hbtv.com.cn/channels/zbk/hbws/flv:sd/live\" width=\"768\" height=\"576\" bitrate=\"1240\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=22\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n        <media id=\"134\" version=\"1\" title=\"湖北经视\" image=\"http://cn.daroonsoft.com/images/hubeitv.png\" guide=\"\"  >\n        <ref href=\"http://live9.hbtv.com.cn/channels/zbk/jingshi2/flv:sd/live\" width=\"720\" height=\"576\" bitrate=\"900\" />\n    </media>\n        <media id=\"140\" version=\"1\" title=\"湖北体育\" image=\"http://cn.daroonsoft.com/images/hubeitv.png\" guide=\"hbtypd\"  >\n        <ref href=\"http://live9.hbtv.com.cn/channels/zbk/hbty/flv:sd/live\" width=\"720\" height=\"576\" bitrate=\"900\" />\n    </media>\n        <media id=\"141\" version=\"1\" title=\"湖北影视\" image=\"http://cn.daroonsoft.com/images/hubeitv.png\" guide=\"hubyspd\"  >\n        <ref href=\"http://live9.hbtv.com.cn/channels/zbk/hbys/flv:sd/live\" width=\"720\" height=\"576\" bitrate=\"900\" />\n    </media>\n        <media id=\"225\" version=\"1\" title=\"湖北电视台\" image=\"http://cn.daroonsoft.com/images/hubeitv.png\" guide=\"\"  >\n        <ref href=\"http://live9.hbtv.com.cn/channels/zbk/hbtv/flv:sd/live\" width=\"720\" height=\"576\" bitrate=\"900\" />\n    </media>\n    <media id=\"042\" version=\"16\" title=\"黑龙江电视台\" image=\"http://cn.daroonsoft.com/images/heilongjiangtv.png\" guide=\"hljws\"  >\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=59\" width=\"800\" height=\"448\" bitrate=\"1044\" />\n    </media>\n    <media id=\"043\" version=\"8\" title=\"辽宁卫视\" image=\"http://cn.daroonsoft.com/images/niaolingtv.png\" guide=\"lnws\"  >\n        <ref href=\"mms://bupt02.video.edu.cn/LNWS\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=10\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n    <media id=\"044\" version=\"8\" title=\"山西卫视\" image=\"http://cn.daroonsoft.com/images/shanxitv.png\" guide=\"sx1ws\"  >\n        <ref href=\"http://gslb.tv.sohu.com/live?cid=50\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n    <media id=\"045\" version=\"12\" title=\"陕西卫视\" image=\"http://cn.daroonsoft.com/images/shaxiatv.png\" guide=\"sx3ws\"  >\n                <ref href=\"http://biz.vsdn.tv380.com/playlive.php?5B63686E5D445830303030303035307C313531337C317C323030307CE74754567C687474705B2F63686E5D5B74735D307C687474705B2F74735DVSDNSOOONERCOM00\" width=\"768\" height=\"576\" bitrate=\"1240\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=20\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n    <media id=\"046\" version=\"9\" title=\"天津卫视\" image=\"http://cn.daroonsoft.com/images/tianjingtv.png\" guide=\"tjws\"  >\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=15\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n    <media id=\"047\" version=\"6\" title=\"云南卫视\" image=\"http://cn.daroonsoft.com/images/yunnantv.png\" guide=\"ynws\"  >\n        <ref href=\"mms://bupt02.video.edu.cn/YNWS\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"http://biz.vsdn.tv380.com/playlive.php?5B63686E5D445830303030303035307C313533317C317C323030307CE74754567C687474705B2F63686E5D5B74735D307C687474705B2F74735DVSDNSOOONERCOM00\" width=\"768\" height=\"576\" bitrate=\"1240\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=17\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n        <media id=\"310\" version=\"7\" title=\"云南都市\" image=\"http://cn.daroonsoft.com/images/yunnantv.png\" guide=\"\"  >\n        <ref href=\"http://116.55.228.241/channels/622/400.flv/live\" width=\"480\" height=\"384\" bitrate=\"521\" />\n    </media>\n        <media id=\"311\" version=\"7\" title=\"云南娱乐\" image=\"http://cn.daroonsoft.com/images/yunnantv.png\" guide=\"yntyylpd\"  >\n        <ref href=\"http://116.55.228.243/channels/623/400.flv/live\" width=\"480\" height=\"384\" bitrate=\"521\" />\n    </media>\n        <media id=\"312\" version=\"7\" title=\"云南公共\" image=\"http://cn.daroonsoft.com/images/yunnantv.png\" guide=\"ynggpd\"  >\n        <ref href=\"http://116.55.228.241/channels/626/400.flv/live\" width=\"480\" height=\"384\" bitrate=\"521\" />\n    </media>\n    <media id=\"048\" version=\"12\" title=\"重庆卫视\" image=\"http://cn.daroonsoft.com/images/chongqingtv.png\" guide=\"zqws\"  >\n        <ref href=\"mms://bupt02.video.edu.cn/CQWS\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"rtsp://123.147.160.18/cqtv.sdp\" width=\"768\" height=\"576\" bitrate=\"1240\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=35\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n        <media id=\"322\" version=\"1\" title=\"武汉体育\" image=\"http://cn.daroonsoft.com/images/wuhantv.png\" guide=\"whtypd\"  >\n                <ref href=\"rtmp://multimedia.whbc.com.cn:1935/live/whtv5gd\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n        <media id=\"332\" version=\"1\" title=\"武汉科教生活\" image=\"http://cn.daroonsoft.com/images/wuhantv.png\" guide=\"whkjshpd\"  >\n                <ref href=\"rtmp://multimedia.whbc.com.cn:1935/live/whtv3gd\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n    <media id=\"049\" version=\"11\" title=\"宁夏卫视\" image=\"http://cn.daroonsoft.com/images/ningxiatv.png\" guide=\"nxws\"  >\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=33\" width=\"320\" height=\"640\" bitrate=\"480\" />\n    </media>\n    <media id=\"050\" version=\"18\" title=\"江苏卫视\" image=\"http://cn.daroonsoft.com/images/jiangsutv.png\" guide=\"jsws\"  >\n        <ref href=\"mms://bupt02.video.edu.cn/JSWS\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=8\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"http://182.131.19.166:1863/1258215255.flv\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"rtsp://116.199.127.68/jiangsu\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n    <media id=\"051\" version=\"10\" title=\"贵州卫视\" image=\"http://cn.daroonsoft.com/images/guizhoutv.png\" guide=\"gzws\"  >\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=32\" width=\"640\" height=\"480\" bitrate=\"1240\" />\n    </media>\n        <media id=\"052\" version=\"8\" title=\"内蒙古卫视\" image=\"http://cn.daroonsoft.com/images/neimenggutv.png\" guide=\"nmgws\"  >\n        <ref href=\"http://gslb.tv.sohu.com/live?cid=26\" width=\"320\" height=\"240\" bitrate=\"128\" />\n    </media>\n        <media id=\"053\" version=\"8\" title=\"西藏卫视\" image=\"http://cn.daroonsoft.com/images/xizhangtv.png\" guide=\"xzhyws\"  >\n        <ref href=\"http://gslb.tv.sohu.com/live?cid=25\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n    <media id=\"054\" version=\"6\" title=\"新疆卫视\" image=\"http://cn.daroonsoft.com/images/xinjiangtv.png\" guide=\"xjws\"  >\n        <ref href=\"http://gslb.tv.sohu.com/live?cid=5\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"mms://www.xjklmy.com/tv-1\" width=\"384\" height=\"288\" bitrate=\"256\" />\n    </media>\n    <media id=\"055\" version=\"12\" title=\"四川卫视\" image=\"http://cn.daroonsoft.com/images/sichuantv.png\" guide=\"scws\"  >\n                <ref href=\"http://biz.vsdn.tv380.com/playlive.php?5B63686E5D445830303030303035307C313439397C317C323030307CE74754567C687474705B2F63686E5D5B74735D307C687474705B2F74735DVSDNSOOONERCOM00\" width=\"768\" height=\"576\" bitrate=\"1240\" />\n        <ref href=\"http://gslb.tv.sohu.com/live?cid=27\" width=\"320\" height=\"240\" bitrate=\"128\" />\n                <ref href=\"rtmp://rtmp.sctv.com/SRT_Live/SCTV1_800\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n        <media id=\"295\" version=\"1\" title=\"四川文化旅游\" image=\"http://cn.daroonsoft.com/images/sichuantv.png\" guide=\"scwhlypd\"  >\n                <ref href=\"rtmp://rtmp.sctv.com/SRT_Live/SCTV2_800\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n        <media id=\"296\" version=\"1\" title=\"四川经视频道\" image=\"http://cn.daroonsoft.com/images/sichuantv.png\" guide=\"scjjpd\"  >\n                <ref href=\"rtmp://rtmp.sctv.com/SRT_Live/SCTV3_800\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n        <media id=\"297\" version=\"1\" title=\"四川新闻资讯\" image=\"http://cn.daroonsoft.com/images/sichuantv.png\" guide=\"scxwzxpd\"  >\n                <ref href=\"rtmp://rtmp.sctv.com/SRT_Live/SCTV4_800\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n        <media id=\"298\" version=\"1\" title=\"四川影视文艺\" image=\"http://cn.daroonsoft.com/images/sichuantv.png\" guide=\"scyswypd\"  >\n                <ref href=\"rtmp://rtmp.sctv.com/SRT_Live/SCTV5_800\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n        <media id=\"299\" version=\"1\" title=\"四川星空购物\" image=\"http://cn.daroonsoft.com/images/sichuantv.png\" guide=\"\"  >\n                <ref href=\"rtmp://rtmp.sctv.com/SRT_Live/SCTV6_800\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n        <media id=\"300\" version=\"1\" title=\"四川妇女儿童\" image=\"http://cn.daroonsoft.com/images/sichuantv.png\" guide=\"scfnetpd\"  >\n                <ref href=\"rtmp://rtmp.sctv.com/SRT_Live/SCTV7_800\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n        <media id=\"301\" version=\"1\" title=\"四川公共频道\" image=\"http://cn.daroonsoft.com/images/sichuantv.png\" guide=\"scggpd\"  >\n                <ref href=\"rtmp://rtmp.sctv.com/SRT_Live/SCTV9_800\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n    <media id=\"056\" version=\"17\" title=\"浙江卫视\" image=\"http://cn.daroonsoft.com/images/zhejiangtv.png\" guide=\"zjws\"  >\n        <ref href=\"mms://bupt02.video.edu.cn/ZJWS\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"http://biz.vsdn.tv380.com/playlive.php?5B63686E5D445830303030303035307C313438337C317C323030307CE74754567C687474705B2F63686E5D5B74735D307C687474705B2F74735DVSDNSOOONERCOM00\" width=\"768\" height=\"576\" bitrate=\"1240\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=31\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"http://119.147.126.78:1863/1975434150.flv\" width=\"720\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"rtsp://116.199.127.68/zhejiang\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n        <media id=\"337\" version=\"1\" title=\"浙江钱江\" image=\"http://cn.daroonsoft.com/images/zhejiangtv.png\" guide=\"zjqjdspd\"  >\n                <ref href=\"rtsp://211.138.120.114/ztv2\" width=\"512\" height=\"384\" bitrate=\"228\" />\n    </media>\n        <media id=\"338\" version=\"1\" title=\"浙江经视\" image=\"http://cn.daroonsoft.com/images/zhejiangtv.png\" guide=\"zjjjpd\"  >\n                <ref href=\"rtsp://211.138.120.114/ztv3\" width=\"426\" height=\"320\" bitrate=\"228\" />\n    </media>\n        <media id=\"339\" version=\"1\" title=\"浙江科教\" image=\"http://cn.daroonsoft.com/images/zhejiangtv.png\" guide=\"zjjykjpd\"  >\n                <ref href=\"rtsp://211.138.120.114/ztv4\" width=\"426\" height=\"320\" bitrate=\"228\" />\n    </media>\n        <media id=\"340\" version=\"1\" title=\"浙江影视\" image=\"http://cn.daroonsoft.com/images/zhejiangtv.png\" guide=\"zjysylpd\"  >\n                <ref href=\"rtsp://211.138.120.114/ztv5\" width=\"426\" height=\"320\" bitrate=\"228\" />\n    </media>\n        <media id=\"341\" version=\"1\" title=\"浙江民生\" image=\"http://cn.daroonsoft.com/images/zhejiangtv.png\" guide=\"zjmsxxpd\"  >\n                <ref href=\"rtsp://211.138.120.114/ztv6\" width=\"426\" height=\"320\" bitrate=\"228\" />\n    </media>\n        <media id=\"342\" version=\"1\" title=\"浙江少儿\" image=\"http://cn.daroonsoft.com/images/zhejiangtv.png\" guide=\"zjsepd\"  >\n                <ref href=\"rtsp://211.138.120.114/ztv8\" width=\"426\" height=\"320\" bitrate=\"228\" />\n    </media>\n    <media id=\"057\" version=\"17\" title=\"安徽卫视\" image=\"http://cn.daroonsoft.com/images/anhuitv.png\" guide=\"ahws\"  >\n        <ref href=\"mms://bupt02.video.edu.cn/AHWS\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=13\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n        <media id=\"323\" version=\"1\" title=\"安徽影视\" image=\"http://cn.daroonsoft.com/images/anhuitv.png\" guide=\"ahyspd\"  >\n        <ref href=\"http://livecdn.ahtv.cn/channels/1502/500.flv/live\" width=\"480\" height=\"384\" bitrate=\"512\" />\n    </media>\n        <media id=\"324\" version=\"1\" title=\"安徽经济生活\" image=\"http://cn.daroonsoft.com/images/anhuitv.png\" guide=\"ahjjshpd\"  >\n        <ref href=\"http://livecdn.ahtv.cn/channels/1503/500.flv/live\" width=\"480\" height=\"384\" bitrate=\"512\" />\n    </media>\n        <media id=\"325\" version=\"1\" title=\"安徽综艺\" image=\"http://cn.daroonsoft.com/images/anhuitv.png\" guide=\"\"  >\n        <ref href=\"http://livecdn.ahtv.cn/channels/1504/500.flv/live\" width=\"480\" height=\"384\" bitrate=\"512\" />\n    </media>\n        <media id=\"326\" version=\"1\" title=\"安徽科教\" image=\"http://cn.daroonsoft.com/images/anhuitv.png\" guide=\"ahkjpd\"  >\n        <ref href=\"http://livecdn.ahtv.cn/channels/1505/500.flv/live\" width=\"480\" height=\"384\" bitrate=\"512\" />\n    </media>\n        <media id=\"327\" version=\"1\" title=\"安徽公共\" image=\"http://cn.daroonsoft.com/images/anhuitv.png\" guide=\"ahggpd\"  >\n        <ref href=\"http://livecdn.ahtv.cn/channels/1506/500.flv/live\" width=\"480\" height=\"384\" bitrate=\"512\" />\n    </media>\n        <media id=\"328\" version=\"1\" title=\"安徽人物\" image=\"http://cn.daroonsoft.com/images/anhuitv.png\" guide=\"\"  >\n        <ref href=\"http://livecdn.ahtv.cn/channels/1507/500.flv/live\" width=\"480\" height=\"384\" bitrate=\"512\" />\n    </media>\n        <media id=\"329\" version=\"1\" title=\"安徽国际\" image=\"http://cn.daroonsoft.com/images/anhuitv.png\" guide=\"\"  >\n        <ref href=\"http://livecdn.ahtv.cn/channels/1508/500.flv/live\" width=\"480\" height=\"384\" bitrate=\"512\" />\n    </media>\n    <media id=\"058\" version=\"12\" title=\"山东卫视\" image=\"http://cn.daroonsoft.com/images/shandongtv.png\" guide=\"sdws\"  >\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=14\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n    <media id=\"059\" version=\"14\" title=\"吉林卫视\" image=\"http://cn.daroonsoft.com/images/jilintv.png\" guide=\"jlws\"  >\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=21\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n        <media id=\"302\" version=\"1\" title=\"吉林都市\" image=\"http://cn.daroonsoft.com/images/jilintv.png\" guide=\"jldspd\"  >\n                <ref href=\"rtsp://222.168.5.236/jlds/\" width=\"320\" height=\"240\" bitrate=\"548\" />\n    </media>\n        <media id=\"303\" version=\"1\" title=\"吉林生活\" image=\"http://cn.daroonsoft.com/images/jilintv.png\" guide=\"jlssh\"  >\n                <ref href=\"rtsp://222.168.5.236/jlsh\" width=\"320\" height=\"240\" bitrate=\"548\" />\n    </media>\n        <media id=\"304\" version=\"1\" title=\"吉林影视\" image=\"http://cn.daroonsoft.com/images/jilintv.png\" guide=\"jlyspd\"  >\n                <ref href=\"rtsp://222.168.5.236/jlys\" width=\"320\" height=\"240\" bitrate=\"548\" />\n    </media>\n        <media id=\"305\" version=\"1\" title=\"吉林乡村\" image=\"http://cn.daroonsoft.com/images/jilintv.png\" guide=\"jlxcpd\"  >\n                <ref href=\"rtsp://222.168.5.236/jlxc/\" width=\"320\" height=\"240\" bitrate=\"548\" />\n    </media>\n        <media id=\"306\" version=\"1\" title=\"吉林法制\" image=\"http://cn.daroonsoft.com/images/jilintv.png\" guide=\"jlfz\"  >\n                <ref href=\"rtsp://222.168.5.236/jlfz\" width=\"320\" height=\"240\" bitrate=\"548\" />\n    </media>\n        <media id=\"307\" version=\"1\" title=\"吉林公共\" image=\"http://cn.daroonsoft.com/images/jilintv.png\" guide=\"jlggpd\"  >\n                <ref href=\"rtsp://222.168.5.236/jlgg\" width=\"320\" height=\"240\" bitrate=\"548\" />\n    </media>\n        <media id=\"308\" version=\"1\" title=\"长春综合频道\" image=\"http://cn.daroonsoft.com/images/changchuntv.png\" guide=\"\"  >\n                <ref href=\"rtsp://video.chinactv.com/CTV/\" width=\"320\" height=\"240\" bitrate=\"548\" />\n    </media>\n        <media id=\"170\" version=\"13\" title=\"东南卫视\" image=\"http://cn.daroonsoft.com/images/dongnantv.png\" guide=\"dnws\"  >\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=7\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"mms://video.fjtv.net/setv\" width=\"320\" height=\"240\" bitrate=\"548\" />\n        </media>\n        <media id=\"226\" version=\"8\" title=\"福建海峡卫视\" image=\"http://cn.daroonsoft.com/images/dongnantv.png\" guide=\"\"  >\n                <ref href=\"mms://video.fjtv.net/fjtv9\" width=\"320\" height=\"240\" bitrate=\"548\" />\n                <ref href=\"mms://video.fjtv.net/fjtv10\" width=\"320\" height=\"240\" bitrate=\"548\" />\n        </media>\n        <media id=\"345\" version=\"1\" title=\"福建综合\" image=\"http://cn.daroonsoft.com/images/dongnantv.png\" guide=\"fjzhpd\"  >\n                <ref href=\"mms://video.fjtv.net/fjtv1\" width=\"320\" height=\"240\" bitrate=\"548\" />\n        </media>\n        <media id=\"346\" version=\"1\" title=\"福建公共\" image=\"http://cn.daroonsoft.com/images/dongnantv.png\" guide=\"fjggpd\"  >\n                <ref href=\"mms://video.fjtv.net/fjtv3\" width=\"320\" height=\"240\" bitrate=\"548\" />\n        </media>\n        <media id=\"347\" version=\"1\" title=\"福建新闻\" image=\"http://cn.daroonsoft.com/images/dongnantv.png\" guide=\"fjxwpd\"  >\n                <ref href=\"mms://video.fjtv.net/fjtv4\" width=\"320\" height=\"240\" bitrate=\"548\" />\n        </media>\n        <media id=\"348\" version=\"1\" title=\"福建电视剧\" image=\"http://cn.daroonsoft.com/images/dongnantv.png\" guide=\"fjdsjpd\"  >\n                <ref href=\"mms://video.fjtv.net/fjtv5\" width=\"320\" height=\"240\" bitrate=\"548\" />\n        </media>\n        <media id=\"349\" version=\"1\" title=\"福建都市时尚\" image=\"http://cn.daroonsoft.com/images/dongnantv.png\" guide=\"fjdssspd\"  >\n                <ref href=\"mms://video.fjtv.net/fjtv6\" width=\"320\" height=\"240\" bitrate=\"548\" />\n        </media>\n        <media id=\"350\" version=\"1\" title=\"福建经济生活\" image=\"http://cn.daroonsoft.com/images/dongnantv.png\" guide=\"fjjjshpd\"  >\n                <ref href=\"mms://video.fjtv.net/fjtv7\" width=\"320\" height=\"240\" bitrate=\"548\" />\n        </media>\n        <media id=\"286\" version=\"10\" title=\"厦门卫视\" image=\"http://cn.daroonsoft.com/images/xiamentv.png\" guide=\"xmws\"  >\n                <ref href=\"mms://mediasrv1.iptv.xmg.com.cn/tvhaixia\" width=\"480\" height=\"384\" bitrate=\"544\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=6\" width=\"640\" height=\"480\" bitrate=\"1240\" />\n        </media>\n        <media id=\"171\" version=\"5\" title=\"甘肃卫视\" image=\"http://cn.daroonsoft.com/images/gansutv.png\" guide=\"gsws\"  >\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=34\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n        </media>\n        <media id=\"172\" version=\"8\" title=\"河北卫视\" image=\"http://cn.daroonsoft.com/images/hebeitv.png\" guide=\"hebeiws\"  >\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=24\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n        </media>\n        <media id=\"174\" version=\"10\" title=\"青海卫视\" image=\"http://cn.daroonsoft.com/images/qinghaitv.png\" guide=\"qhws\"  >\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=12\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=71\" width=\"352\" height=\"288\" bitrate=\"512\" />\n        </media>\n    <media id=\"060\" version=\"5\" title=\"珠海1台\" image=\"http://cn.daroonsoft.com/images/zhuhaitv.png\" guide=\"\"  >\n        <ref href=\"http://58.248.254.7:1935/live/izhuhai.sdp/playlist.m3u8\" width=\"320\" height=\"240\" bitrate=\"128\" />\n                <ref href=\"rtmp://live.zhtv.com/live/zhtv1\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n        <media id=\"334\" version=\"5\" title=\"珠海2台\" image=\"http://cn.daroonsoft.com/images/zhuhaitv.png\" guide=\"\"  >\n                <ref href=\"rtmp://live.zhtv.com/live/zhtv2\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n    <media id=\"061\" version=\"11\" title=\"南方卫视\" image=\"http://cn.daroonsoft.com/images/tvs.png\" guide=\"nfwspd\"  >\n        <ref href=\"http://58.248.254.7:1935/live/itvs2.sdp/playlist.m3u8\" width=\"320\" height=\"240\" bitrate=\"128\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=16\" width=\"640\" height=\"480\" bitrate=\"900\" />\n    </media>\n    <media id=\"062\" version=\"6\" title=\"南方影视频道\" image=\"http://cn.daroonsoft.com/images/tvs.png\" guide=\"nfyspd\"  >\n        <ref href=\"http://58.248.254.7:1935/live/itvs4.sdp/playlist.m3u8\" width=\"320\" height=\"240\" bitrate=\"128\" />\n                <ref href=\"rtsp://116.199.127.68/nanfang_movie\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n    <media id=\"063\" version=\"14\" title=\"旅游卫视\" image=\"http://cn.daroonsoft.com/images/nvyoutv.png\" guide=\"lyws\"  >\n        <ref href=\"mms://bupt02.video.edu.cn/LYWS\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=28\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n    </media>\n        <media id=\"352\" version=\"13\" title=\"海南综合\" image=\"http://cn.daroonsoft.com/images/nvyoutv.png\" guide=\"hnzhpd\"  >\n        <ref href=\"rtsp://41.bluehn.com/LIVECAM1\" width=\"384\" height=\"288\" bitrate=\"256\" />\n    </media>\n        <media id=\"353\" version=\"13\" title=\"海南新闻\" image=\"http://cn.daroonsoft.com/images/nvyoutv.png\" guide=\"\"  >\n        <ref href=\"rtsp://40.bluehn.com/LIVECAM2\" width=\"384\" height=\"288\" bitrate=\"256\" />\n    </media>\n        <media id=\"354\" version=\"13\" title=\"海南影视剧\" image=\"http://cn.daroonsoft.com/images/nvyoutv.png\" guide=\"hnysylpd\"  >\n        <ref href=\"rtsp://41.bluehn.com/LIVECAM3\" width=\"384\" height=\"288\" bitrate=\"256\" />\n    </media>\n        <media id=\"355\" version=\"13\" title=\"海南综艺生活\" image=\"http://cn.daroonsoft.com/images/nvyoutv.png\" guide=\"\"  >\n        <ref href=\"rtsp://43.bluehn.com/LIVECAM4\" width=\"384\" height=\"288\" bitrate=\"256\" />\n    </media>\n        <media id=\"356\" version=\"13\" title=\"海南少儿\" image=\"http://cn.daroonsoft.com/images/nvyoutv.png\" guide=\"hnsepd\"  >\n        <ref href=\"rtsp://42.bluehn.com/LIVECAM5\" width=\"384\" height=\"288\" bitrate=\"256\" />\n    </media>\n    <media id=\"064\" version=\"14\" title=\"深圳卫视\" image=\"http://cn.daroonsoft.com/images/shenzhentv.png\" guide=\"szws\"  >\n        <ref href=\"mms://bupt02.video.edu.cn/SZWS\" width=\"576\" height=\"432\" bitrate=\"1440\" />\n                <ref href=\"http://112.231.23.20:554/rtplive/tv29/playlist.m3u8\" width=\"320\" height=\"240\" bitrate=\"128\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=45\" width=\"640\" height=\"480\" bitrate=\"900\" />\n                <ref href=\"rtsp://116.199.127.68/shenzhen\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n    <media id=\"065\" version=\"19\" title=\"广东卫视\" image=\"http://cn.daroonsoft.com/images/guangdongtv.png\" guide=\"gdws\"  >\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=60\" width=\"800\" height=\"448\" bitrate=\"900\" />\n    </media>\n    <media id=\"123\" version=\"9\" title=\"广东珠江\" image=\"http://cn.daroonsoft.com/images/guangdongtv.png\" guide=\"gdzjpd\"  >\n        <ref href=\"http://119.147.126.79:1863/1926463423.flv\" width=\"640\" height=\"480\" bitrate=\"900\" />\n                <ref href=\"http://58.248.254.7:1935/live/igdzj.sdp/playlist.m3u8\" width=\"320\" height=\"240\" bitrate=\"128\" />\n                <ref href=\"rtsp://116.199.127.68/zhujiang\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n        </media>\n    <media id=\"124\" version=\"6\" title=\"广东新闻\" image=\"http://cn.daroonsoft.com/images/guangdongtv.png\" guide=\"gdxwpd\"  >\n        <ref href=\"http://182.131.19.173:1863/2631736979.flv\" width=\"640\" height=\"480\" bitrate=\"900\" />\n    </media>\n    <media id=\"015\" version=\"16\" title=\"广东体育\" image=\"http://cn.daroonsoft.com/images/guangdongtv.png\" guide=\"gdtypd\"  >\n                <ref href=\"rtsp://121.14.129.221/asiangames/live/gdsports-s.sdp\" width=\"320\" height=\"240\" bitrate=\"128\" />\n                <ref href=\"rtsp://121.14.129.221/asiangames/live/gdsports-ah.sdp\" width=\"320\" height=\"240\" bitrate=\"128\" />\n                <ref href=\"rtsp://121.14.129.221/asiangames/live/gdsports-h.sdp\" width=\"320\" height=\"240\" bitrate=\"128\" />\n                <ref href=\"rtsp://116.199.127.68/gdtv_sport\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n                <ref href=\"rtmp://v1.gdtv.cn:1935/live/sports\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n    <media id=\"066\" version=\"4\" title=\"广州影视\" image=\"http://cn.daroonsoft.com/images/guangzhouwstv.png\" guide=\"gzyspd\"  >\n        <ref href=\"http://58.248.254.7:1935/live/igzys.sdp/playlist.m3u8\" width=\"320\" height=\"240\" bitrate=\"128\" />\n                <ref href=\"rtsp://116.199.127.68/gztv_movie\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n        <media id=\"234\" version=\"1\" title=\"广州新闻\" image=\"http://cn.daroonsoft.com/images/guangzhouwstv.png\" guide=\"gzxwpd\"  >\n        <ref href=\"rtsp://live21.gztv.com/gztv_news\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n        <media id=\"235\" version=\"2\" title=\"广州综合\" image=\"http://cn.daroonsoft.com/images/guangzhouwstv.png\" guide=\"gzzhpd\"  >\n        <ref href=\"rtsp://live21.gztv.com/gztv_gz?\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n                <ref href=\"rtsp://116.199.127.68/gztv_gz\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n        <media id=\"369\" version=\"1\" title=\"广州竞赛\" image=\"http://cn.daroonsoft.com/images/guangzhouwstv.png\" guide=\"gzjspd\"  >\n        <ref href=\"rtsp://116.199.127.68/gztv_sport\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n        <media id=\"191\" version=\"3\" title=\"惠州综合\" image=\"http://cn.daroonsoft.com/images/huizhouzonghtv.png\" guide=\"gdhzxwzhpd\"  >\n                <ref href=\"http://58.248.254.7:1935/live/ihzws.sdp/playlist.m3u8\" width=\"480\" height=\"320\" bitrate=\"548\" />\n        </media>\n        <media id=\"335\" version=\"2\" title=\"惠州公共\" image=\"http://cn.daroonsoft.com/images/huizhouzonghtv.png\" guide=\"\"  >\n                <ref href=\"http://live.hzrtv.cn/live/2da8f89ad3974579b573d45f73340d4a?fmt=H264_800K_FLV\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n        </media>\n        <media id=\"192\" version=\"2\" title=\"江门综合\" image=\"http://cn.daroonsoft.com/images/jiangmenzonghtv.png\" guide=\"\"  >\n                <ref href=\"http://58.248.254.7:1935/live/ijmws.sdp/playlist.m3u8\" width=\"480\" height=\"320\" bitrate=\"548\" />\n        </media>\n        <media id=\"193\" version=\"2\" title=\"佛山综合\" image=\"http://cn.daroonsoft.com/images/fstv.png\" guide=\"fsxwzhpd\"  >\n                <ref href=\"http://58.248.254.7:1935/live/ifsws.sdp/playlist.m3u8\" width=\"480\" height=\"320\" bitrate=\"548\" />\n        </media>\n        <media id=\"194\" version=\"2\" title=\"佛山公共\" image=\"http://cn.daroonsoft.com/images/fstv.png\" guide=\"fsggpd\"  >\n                <ref href=\"http://58.248.254.7:1935/live/ifsws2.sdp/playlist.m3u8\" width=\"480\" height=\"320\" bitrate=\"548\" />\n        </media>\n        <media id=\"195\" version=\"2\" title=\"河源综合\" image=\"http://cn.daroonsoft.com/images/hyrtv.png\" guide=\"\"  >\n                <ref href=\"http://58.248.254.7:1935/live/ihyzh.sdp/playlist.m3u8\" width=\"320\" height=\"240\" bitrate=\"128\" />\n        </media>\n        <media id=\"196\" version=\"2\" title=\"河源公共\" image=\"http://cn.daroonsoft.com/images/hyrtv.png\" guide=\"\"  >\n                <ref href=\"http://58.248.254.7:1935/live/ihygg.sdp/playlist.m3u8\" width=\"320\" height=\"240\" bitrate=\"128\" />\n        </media>\n        <media id=\"197\" version=\"2\" title=\"梅州综合\" image=\"http://cn.daroonsoft.com/images/meizhoutv.png\" guide=\"\"  >\n                <ref href=\"http://58.248.254.7:1935/live/imzws.sdp/playlist.m3u8\" width=\"480\" height=\"320\" bitrate=\"548\" />\n        </media>\n        <media id=\"198\" version=\"2\" title=\"云浮综合\" image=\"http://cn.daroonsoft.com/images/yunfuzonghtv.png\" guide=\"\"  >\n                <ref href=\"http://58.248.254.7:1935/live/iyunfu.sdp/playlist.m3u8\" width=\"480\" height=\"320\" bitrate=\"548\" />\n        </media>\n        <media id=\"199\" version=\"3\" title=\"韶关台\" image=\"http://cn.daroonsoft.com/images/shaoguantv.png\" guide=\"\"  >\n                <ref href=\"http://58.248.254.7:1935/live/isgws.sdp/playlist.m3u8\" width=\"320\" height=\"240\" bitrate=\"128\" />\n        </media>\n        <media id=\"200\" version=\"2\" title=\"汕头台\" image=\"http://cn.daroonsoft.com/images/shantoutv.png\" guide=\"\"  >\n                <ref href=\"http://58.248.254.7:1935/live/istws.sdp/playlist.m3u8\" width=\"320\" height=\"240\" bitrate=\"128\" />\n        </media>\n    <media id=\"016\" version=\"16\" title=\"凤凰卫视\" image=\"http://cn.daroonsoft.com/images/Phoenixzwtv.jpg\" guide=\"fhzw\">\n                <ref href=\"mms://222.47.26.81/litv01\" width=\"320\" height=\"240\" bitrate=\"598\" />\n                <ref href=\"rtsp://116.199.127.68/fenghuang\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n    <media id=\"017\" version=\"20\" title=\"凤凰资讯\" image=\"http://cn.daroonsoft.com/images/Phoenixzxtv.jpg\" guide=\"fhzx\">\n        <ref href=\"mms://222.47.26.81/litv03\" width=\"320\" height=\"240\" bitrate=\"256\" />\n                <ref href=\"http://ts.3gv.ifeng.com/live/iphone/zwt/index_256k.m3u8\" width=\"320\" height=\"240\" bitrate=\"256\" />\n        </media>\n    <media id=\"068\" version=\"6\" title=\"阳光卫视\" image=\"http://cn.daroonsoft.com/images/suntv.png\" guide=\"ygws\"  >\n        <ref href=\"rtsp://65.49.26.231/suntv\" width=\"320\" height=\"240\" bitrate=\"548\" />\n    </media>\n    <media id=\"070\" version=\"9\" title=\"星空卫视\" image=\"http://cn.daroonsoft.com/images/xingkongweishi.png\" guide=\"xkws\"  >\n        <ref href=\"mms://222.47.62.74/litv06\" width=\"320\" height=\"240\" bitrate=\"548\" />\n                <ref href=\"rtsp://116.199.127.68/xingkong\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n    <media id=\"164\" version=\"6\" title=\"CHC动作电影\" image=\"http://cn.daroonsoft.com/images/chcdzdy.png\" guide=\"chcdzdy\"  >\n        <ref href=\"rtsp://121.14.129.221/broadcast/pushfeeder/rtpencoder/dongzdy-h.sdp\" width=\"320\" height=\"240\" bitrate=\"256\" />\n                <ref href=\"rtsp://121.14.129.221/broadcast/pushfeeder/rtpencoder/dongzdy-s.sdp\" width=\"176\" height=\"144\" bitrate=\"156\" />\n    </media>\n    <media id=\"165\" version=\"6\" title=\"珠江电影\" image=\"http://cn.daroonsoft.com/images/zjmovie.png\" guide=\"\"  >\n        <ref href=\"rtsp://121.14.129.221/broadcast/pushfeeder/rtpencoder/zjdy-h.sdp\" width=\"320\" height=\"240\" bitrate=\"256\" />\n                <ref href=\"rtsp://121.14.129.221/broadcast/pushfeeder/rtpencoder/zjdy-c.sdp\" width=\"176\" height=\"144\" bitrate=\"156\" />\n    </media>\n    <media id=\"159\" version=\"35\" title=\"澳亚卫视\" image=\"http://cn.daroonsoft.com/images/mastv.png\" guide=\"ayws\"  >\n        <ref href=\"rtsp://59.125.169.12/MASTV_BS_500K\" width=\"640\" height=\"480\" bitrate=\"491\" />\n    </media>\n    <media id=\"160\" version=\"3\" title=\"澳视澳门\" image=\"http://cn.daroonsoft.com/images/aoshi.png\" guide=\"\"  >\n        <ref href=\"mms://media4.tdm.com.mo/ch1\" width=\"320\" height=\"240\" bitrate=\"548\" />\n    </media>\n    <media id=\"161\" version=\"2\" title=\"Canal Macau\" image=\"http://cn.daroonsoft.com/images/aoshi.png\" guide=\"\"  >\n        <ref href=\"mms://media4.tdm.com.mo/ch2\" width=\"320\" height=\"240\" bitrate=\"548\" />\n    </media>\n    <media id=\"162\" version=\"4\" title=\"澳视体育\" image=\"http://cn.daroonsoft.com/images/aoshi.png\" guide=\"\"  >\n        <ref href=\"mms://media4.tdm.com.mo/ch4\" width=\"320\" height=\"240\" bitrate=\"548\" />\n    </media>\n    <media id=\"163\" version=\"4\" title=\"澳视生活\" image=\"http://cn.daroonsoft.com/images/aoshishtv.png\" guide=\"\"  >\n        <ref href=\"mms://media4.tdm.com.mo/ch3\" width=\"320\" height=\"240\" bitrate=\"548\" />\n    </media>\n        <media id=\"294\" version=\"4\" title=\"澳门莲花台\" image=\"http://cn.daroonsoft.com/images/lotus.png\" guide=\"\"  >\n        <ref href=\"mms://222.47.62.74/litv12\" width=\"320\" height=\"240\" bitrate=\"548\" />\n                <ref href=\"mms://222.47.26.81/litv12\" width=\"320\" height=\"240\" bitrate=\"548\" />\n    </media>\n        <media id=\"075\" version=\"11\" title=\"华娱卫视\" image=\"http://cn.daroonsoft.com/images/cetvtv.PNG\" guide=\"hyws\"  >\n        <ref href=\"mms://222.47.62.74/litv13\" width=\"320\" height=\"240\" bitrate=\"548\" />\n                <ref href=\"rtsp://116.199.127.68/huayu\" width=\"720\" height=\"576\" bitrate=\"1044\" />\n    </media>\n        <media id=\"231\" version=\"1\" title=\"东风37台\" image=\"http://cn.daroonsoft.com/images/aziotv.png\" guide=\"\"  >\n                <ref href=\"rtsp://203.69.41.22/TA_AZIO_AZIOT_200_MO\" width=\"320\" height=\"240\" bitrate=\"548\" />\n        </media>\n        <media id=\"236\" version=\"3\" title=\"健康卫视\" image=\"http://cn.daroonsoft.com/images/jktv.png\" guide=\"\"  >\n                <ref href=\"rtsp://mms.jkwshk.com/jkws\" width=\"640\" height=\"480\" bitrate=\"412\" />\n                <ref href=\"http://gslb.tv.sohu.com/live?cid=53\" width=\"640\" height=\"480\" bitrate=\"1044\" />\n        </media>\n        <media id=\"201\" version=\"3\" title=\"邮轮旅游\" image=\"http://cn.daroonsoft.com/images/youlunlvyoutv.png\" guide=\"\"  >\n                <ref href=\"http://58.248.254.7:1935/live/iylly.sdp/playlist.m3u8\" width=\"320\" height=\"240\" bitrate=\"128\" />\n        </media>\n        <media id=\"107\" version=\"5\" title=\"NOW\" image=\"http://cn.daroonsoft.com/images/nowtv.png\" guide=\"\"  >\n                <ref href=\"mms://222.47.26.81/litv14\" width=\"320\" height=\"240\" bitrate=\"548\" />\n        </media>\n        <media id=\"203\" version=\"2\" title=\"韩KBS高清\" image=\"http://cn.daroonsoft.com/images/kbstv.png\" guide=\"\"  >\n                <ref href=\"http://news24kbs-2.gscdn.com/news24_300/_definst_/news24_300.stream/playlist.m3u8\" width=\"480\" height=\"270\" bitrate=\"420\" />\n        </media>\n        <media id=\"204\" version=\"2\" title=\"韩WOWNet\" image=\"http://cn.daroonsoft.com/images/wownettv.png\" guide=\"\"  >\n                <ref href=\"http://wowmlive.shinbnstar.com:1935/live2/wowtv/playlist.m3u8\" width=\"320\" height=\"240\" bitrate=\"128\" />\n        </media>\n        <media id=\"208\" version=\"2\" title=\"日NHK高清\" image=\"http://cn.daroonsoft.com/images/nhktv.png\" guide=\"\"  >\n                <ref href=\"http://plslive-w.nhk.or.jp/nhkworld/app/high.m3u8\" width=\"480\" height=\"272\" bitrate=\"548\" />\n        </media>\n        <media id=\"209\" version=\"2\" title=\"日NHK\" image=\"http://cn.daroonsoft.com/images/nhktv.png\" guide=\"\"  >\n                <ref href=\"http://plslive-w.nhk.or.jp/nhkworld/app/mid.m3u8\" width=\"480\" height=\"272\" bitrate=\"548\" />\n        </media>\n        <media id=\"212\" version=\"4\" title=\"euronews\" image=\"http://cn.daroonsoft.com/images/euronews.png\" guide=\"\"  >\n                <ref href=\"http://media4.lsops.net/live/_definst_/euronews_en_medium.sdp/playlist.m3u8\" width=\"480\" height=\"304\" bitrate=\"548\" />\n                <ref href=\"rtsp://media2.lsops.net/live/euronews_en_high.sdp\" width=\"480\" height=\"304\" bitrate=\"548\" />\n        </media>\n        <media id=\"213\" version=\"6\" title=\"CNN\" image=\"http://cn.daroonsoft.com/images/cnn.png\" guide=\"cnn\"  >\n                <ref href=\"http://media4.lsops.net/live/_definst_/cnn_en_medium.sdp/playlist.m3u8\" width=\"432\" height=\"320\" bitrate=\"548\" />\n        </media>\n        <media id=\"277\" version=\"3\" title=\"星空体育\" image=\"http://cn.daroonsoft.com/images/star_sports.png\" guide=\"\"  >\n                <ref href=\"rtmp://livertmp1.wasu.cn/live3/stars\" width=\"640\" height=\"480\" bitrate=\"412\" />\n        </media>\n\n  </body>\n  <categories>\n        <category id=\"01\" version=\"9\" name=\"中央电视台\" >\n                <item>001</item>\n                <item>002</item>\n                <item>003</item>\n                <item>004</item>\n                <item>005</item>\n                <item>006</item>\n                <item>007</item>\n                <item>008</item>\n                <item>009</item>\n                <item>010</item>\n                <item>011</item>\n                <item>012</item>\n                <item>013</item>\n                <item>014</item>\n                <item>214</item>\n                <item>216</item>\n                <item>072</item>\n                <item>073</item>\n                <item>366</item>\n                <item>370</item>\n        </category>\n        <category id=\"02\" version=\"39\" name=\"地方卫视\" >\n                <item>018</item>\n                <item>027</item>\n                <item>036</item>\n                <item>037</item>\n                <item>038</item>\n                <item>039</item>\n                <item>042</item>\n                <item>043</item>\n                <item>044</item>\n                <item>045</item>\n                <item>046</item>\n                <item>047</item>\n                <item>048</item>\n                <item>049</item>\n                <item>050</item>\n                <item>051</item>\n                <item>052</item>\n                <item>053</item>\n                <item>054</item>\n                <item>055</item>\n                <item>056</item>\n                <item>057</item>\n                <item>058</item>\n                <item>059</item>\n                <item>061</item>\n                <item>064</item>\n                <item>170</item>\n                <item>171</item>\n                <item>172</item>\n                <item>174</item>\n                <item>286</item>\n        </category>\n        <category id=\"03\" version=\"36\" name=\"港澳台电视台\" >\n                <item>016</item>\n                <item>017</item>\n                <item>068</item>\n                <item>070</item>\n                <item>075</item>\n                <item>107</item>\n\t\t        <item>159</item>\n\t\t        <item>160</item>\n\t\t        <item>161</item>\n\t\t        <item>162</item>\n\t\t        <item>163</item>\n                <item>164</item>\n                <item>231</item>\n                <item>294</item>\n        </category>\n        <category id=\"04\" version=\"31\" name=\"国外电视台\" >\n                <item>203</item>\n                <item>204</item>\n                <item>208</item>\n                <item>209</item>\n                <item>212</item>\n                <item>213</item>\n                <item>201</item>\n                <item>277</item>\n        </category>\n        <category id=\"05\" version=\"30\" name=\"体育频道\" >\n                <item>005</item>\n                <item>015</item>\n                <item>094</item>\n                <item>126</item>\n                <item>140</item>\n                <item>322</item>\n                <item>366</item>\n                <item>367</item>\n                <item>368</item>\n                <item>277</item>\n                <item>369</item>\n        </category>\n        <category id=\"06\" version=\"18\" name=\"湖南电视台\" >\n                <item>018</item>\n                <item>022</item>\n                <item>112</item>\n                <item>113</item>\n                <item>114</item>\n        </category>\n        <category id=\"07\" version=\"15\" name=\"上海电视台\" >\n                <item>027</item>\n                <item>108</item>\n                <item>111</item>\n                <item>126</item>\n                <item>127</item>\n                <item>128</item>\n                <item>130</item>\n                <item>131</item>\n                <item>132</item>\n                <item>133</item>\n                <item>372</item>\n                <item>373</item>\n                <item>240</item>\n                <item>320</item>\n                <item>368</item>\n        </category>\n        <category id=\"08\" version=\"6\" name=\"北京电视台\" >\n                <item>036</item>\n                <item>085</item>\n                <item>086</item>\n                <item>087</item>\n                <item>088</item>\n                <item>089</item>\n                <item>090</item>\n                <item>094</item>\n        </category>\n        <category id=\"09\" version=\"8\" name=\"浙江电视台\" >\n                <item>056</item>\n                <item>115</item>\n                <item>116</item>\n                <item>117</item>\n                <item>118</item>\n                <item>119</item>\n                <item>202</item>\n                <item>337</item>\n                <item>338</item>\n                <item>339</item>\n                <item>340</item>\n                <item>341</item>\n                <item>342</item>\n        </category>\n        <category id=\"10\" version=\"6\" name=\"湖北电视台\" >\n                <item>040</item>\n                <item>134</item>\n                <item>140</item>\n                <item>141</item>\n                <item>225</item>\n        </category>\n        <category id=\"11\" version=\"11\" name=\"深圳电视台\" >\n                <item>064</item>\n        </category>\n        <category id=\"12\" version=\"11\" name=\"广东电视台\" >\n                <item>015</item>\n                <item>060</item>\n                <item>061</item>\n                <item>062</item>\n                <item>065</item>\n                <item>066</item>\n                <item>123</item>\n                <item>124</item>\n        <item>165</item>\n                <item>191</item>\n                <item>192</item>\n                <item>193</item>\n                <item>194</item>\n                <item>195</item>\n                <item>196</item>\n                <item>197</item>\n                <item>198</item>\n                <item>199</item>\n                <item>200</item>\n                <item>234</item>\n                <item>235</item>\n                <item>334</item>\n                <item>335</item>\n                <item>369</item>\n        </category>\n        <category id=\"13\" version=\"1\" name=\"四川电视台\" >\n                <item>055</item>\n                <item>295</item>\n                <item>296</item>\n                <item>297</item>\n                <item>298</item>\n                <item>299</item>\n                <item>300</item>\n        \t\t<item>301</item>\n        </category>\n        <category id=\"014\" version=\"1\" name=\"安徽电视台\" >\n                <item>057</item>\n                <item>323</item>\n                <item>324</item>\n                <item>325</item>\n                <item>326</item>\n                <item>327</item>\n                <item>328</item>\n        \t\t<item>329</item>\n        </category>\n        <category id=\"15\" version=\"1\" name=\"吉林电视台\" >\n                <item>059</item>\n                <item>302</item>\n                <item>303</item>\n                <item>304</item>\n                <item>305</item>\n                <item>306</item>\n                <item>307</item>\n        \t\t<item>308</item>\n        </category>\n        <category id=\"16\" version=\"2\" name=\"福建电视台\" >\n                <item>170</item>\n                <item>226</item>\n                <item>345</item>\n                <item>346</item>\n                <item>347</item>\n                <item>348</item>\n                <item>349</item>\n        \t\t<item>350</item>\n        \t\t<item>286</item>\n        </category>\n        <category id=\"17\" version=\"2\" name=\"黑龙江电视台\" >\n                <item>042</item>\n        </category>\n        <category id=\"18\" version=\"1\" name=\"武汉电视台\" >\n                <item>322</item>\n                <item>332</item>\n        </category>\n        <category id=\"19\" version=\"1\" name=\"云南电视台\" >\n                <item>047</item>\n                <item>310</item>\n                <item>311</item>\n                <item>312</item>\n        </category>\n        <category id=\"020\" version=\"1\" name=\"海南电视台\" >\n                <item>063</item>\n                <item>352</item>\n                <item>353</item>\n                <item>354</item>\n                <item>355</item>\n                <item>356</item>\n        </category>\n        <category id=\"21\" version=\"1\" name=\"甘肃电视台\" >\n                <item>171</item>\n        </category>\n        <category id=\"22\" version=\"3\" name=\"陕西电视台\" >\n                <item>045</item>\n        </category>\n        <category id=\"23\" version=\"2\" name=\"其他电视台\" >\n                <item>187</item>\n                <item>236</item>\n        </category>\n  </categories>\n</list>"
  },
  {
    "path": "project.properties",
    "content": "# This file is automatically generated by Android Tools.\n# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n#\n# This file must be checked in Version Control Systems.\n#\n# To customize properties used by the Ant build system use,\n# \"ant.properties\", and override values to adapt the script to your\n# project structure.\n\n# Project target.\ntarget=android-17\nandroid.library.reference.1=../VitamioBundle\n"
  },
  {
    "path": "res/anim/slide_in_bottom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n     /* //device/apps/common/res/anim/slide_in_left.xml ** ** Copyright 2007, \n\tThe Android Open Source Project ** ** Licensed under the Apache License, \n\tVersion 2.0 (the \"License\"); ** you may not use this file except in compliance \n\twith the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 \n\t** ** Unless required by applicable law or agreed to in writing, software \n\t** distributed under the License is distributed on an \"AS IS\" BASIS, ** WITHOUT \n\tWARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the \n\tLicense for the specific language governing permissions and ** limitations \n\tunder the License. */\n-->\n\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n\n    <translate\n        android:duration=\"300\"\n        android:fromYDelta=\"-100%\"\n        android:toYDelta=\"0\" />\n\n    <alpha\n        android:duration=\"300\"\n        android:fromAlpha=\"0.0\"\n        android:toAlpha=\"1.0\" />\n\n</set>"
  },
  {
    "path": "res/anim/slide_in_top.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n     /* //device/apps/common/res/anim/slide_in_right.xml ** ** Copyright \n\t2007, The Android Open Source Project ** ** Licensed under the Apache License, \n\tVersion 2.0 (the \"License\"); ** you may not use this file except in compliance \n\twith the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 \n\t** ** Unless required by applicable law or agreed to in writing, software \n\t** distributed under the License is distributed on an \"AS IS\" BASIS, ** WITHOUT \n\tWARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the \n\tLicense for the specific language governing permissions and ** limitations \n\tunder the License. */\n-->\n\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n\n    <translate\n        android:duration=\"300\"\n        android:fromYDelta=\"100%\"\n        android:toYDelta=\"0\" />\n\n    <alpha\n        android:duration=\"300\"\n        android:fromAlpha=\"0.0\"\n        android:toAlpha=\"1.0\" />\n\n</set>"
  },
  {
    "path": "res/anim/slide_out_bottom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n     /* //device/apps/common/res/anim/slide_out_left.xml ** ** Copyright \n\t2007, The Android Open Source Project ** ** Licensed under the Apache License, \n\tVersion 2.0 (the \"License\"); ** you may not use this file except in compliance \n\twith the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 \n\t** ** Unless required by applicable law or agreed to in writing, software \n\t** distributed under the License is distributed on an \"AS IS\" BASIS, ** WITHOUT \n\tWARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the \n\tLicense for the specific language governing permissions and ** limitations \n\tunder the License. */\n-->\n\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n\n    <translate\n        android:duration=\"300\"\n        android:fromYDelta=\"0\"\n        android:toYDelta=\"-100%\" />\n\n    <alpha\n        android:duration=\"300\"\n        android:fromAlpha=\"1.0\"\n        android:toAlpha=\"0.0\" />\n\n</set>"
  },
  {
    "path": "res/anim/slide_out_top.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n     /* //device/apps/common/res/anim/slide_out_right.xml ** ** Copyright \n\t2007, The Android Open Source Project ** ** Licensed under the Apache License, \n\tVersion 2.0 (the \"License\"); ** you may not use this file except in compliance \n\twith the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 \n\t** ** Unless required by applicable law or agreed to in writing, software \n\t** distributed under the License is distributed on an \"AS IS\" BASIS, ** WITHOUT \n\tWARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the \n\tLicense for the specific language governing permissions and ** limitations \n\tunder the License. */\n-->\n\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n\n    <translate\n        android:duration=\"300\"\n        android:fromYDelta=\"0\"\n        android:toYDelta=\"100%\" />\n\n    <alpha\n        android:duration=\"300\"\n        android:fromAlpha=\"1.0\"\n        android:toAlpha=\"0.0\" />\n\n</set>"
  },
  {
    "path": "res/drawable/alphabet_scroller_bg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<selector\r\n  xmlns:android=\"http://schemas.android.com/apk/res/android\">\r\n    <item android:state_pressed=\"true\" android:drawable=\"@drawable/contact_list_scroll_pressed\" />\r\n    <item android:drawable=\"@drawable/contact_list_scroll_normal\" />\r\n</selector>"
  },
  {
    "path": "res/drawable/home_btn_bg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\r\n\t<item android:state_checked=\"false\" android:drawable=\"@drawable/home_bg_normal\" />\r\n\t<item android:state_checked=\"true\" android:drawable=\"@drawable/home_bg_checked\" />\r\n</selector> "
  },
  {
    "path": "res/drawable/mediacontroller_btn_bg.xml",
    "content": "<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <item android:drawable=\"@color/mediacontroller_bg_pressed\" android:state_focused=\"true\"/>\n    <item android:drawable=\"@color/mediacontroller_bg_pressed\" android:state_pressed=\"true\"/>\n    <item android:drawable=\"@color/transparent\" android:state_enabled=\"false\"/>\n    <item android:drawable=\"@color/transparent\"/>\n\n</selector>"
  },
  {
    "path": "res/drawable/mediacontroller_pause_button.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <item android:drawable=\"@drawable/mediacontroller_pause02\" android:state_focused=\"true\" android:state_pressed=\"false\"/>\n    <item android:drawable=\"@drawable/mediacontroller_pause02\" android:state_focused=\"true\" android:state_pressed=\"true\"/>\n    <item android:drawable=\"@drawable/mediacontroller_pause02\" android:state_focused=\"false\" android:state_pressed=\"true\"/>\n    <item android:drawable=\"@drawable/mediacontroller_pause01\"/>\n\n</selector>"
  },
  {
    "path": "res/drawable/mediacontroller_play_button.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <item android:drawable=\"@drawable/mediacontroller_play02\" android:state_focused=\"true\" android:state_pressed=\"false\"/>\n    <item android:drawable=\"@drawable/mediacontroller_play02\" android:state_focused=\"true\" android:state_pressed=\"true\"/>\n    <item android:drawable=\"@drawable/mediacontroller_play02\" android:state_focused=\"false\" android:state_pressed=\"true\"/>\n    <item android:drawable=\"@drawable/mediacontroller_play01\"/>\n\n</selector>"
  },
  {
    "path": "res/drawable/mediacontroller_seekbar.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n\n    <item\n        android:id=\"@android:id/background\"\n        android:drawable=\"@drawable/mediacontroller_seekbar02\"/>\n    <item android:id=\"@android:id/secondaryProgress\">\n        <clip>\n            <shape>\n                <solid android:color=\"#00000000\" />\n            </shape>\n        </clip>\n    </item>\n    <item android:id=\"@android:id/progress\">\n        <clip>\n            <layer-list>\n                <item\n                    android:bottom=\"2.0dip\"\n                    android:left=\"2.0dip\"\n                    android:right=\"2.0dip\"\n                    android:top=\"2.0dip\">\n                    <bitmap\n                        android:gravity=\"center_vertical|fill_vertical|left\"\n                        android:src=\"@drawable/mediacontroller_seekbar01\"\n                        android:tileMode=\"disabled\" />\n                </item>\n            </layer-list>\n        </clip>\n    </item>\n\n</layer-list>"
  },
  {
    "path": "res/drawable/mediacontroller_seekbar_thumb.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"ring\" >\n\n    <solid android:color=\"#00000000\" />\n\n    <size\n        android:height=\"40dip\"\n        android:width=\"40dip\" />\n\n</shape>"
  },
  {
    "path": "res/drawable/scrubber_control_selector_holo.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2011 The Android Open Source Project Licensed under the \n\tApache License, Version 2.0 (the \"License\"); you may not use this file except \n\tin compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 \n\tUnless required by applicable law or agreed to in writing, software distributed \n\tunder the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES \n\tOR CONDITIONS OF ANY KIND, either express or implied. See the License for \n\tthe specific language governing permissions and limitations under the License. -->\n\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\t<item android:state_enabled=\"false\"\n\t\tandroid:drawable=\"@drawable/scrubber_control_disabled_holo\" />\n\t<item android:state_pressed=\"true\"\n\t\tandroid:drawable=\"@drawable/scrubber_control_pressed_holo\" />\n\t<item android:state_selected=\"true\"\n\t\tandroid:drawable=\"@drawable/scrubber_control_focused_holo\" />\n\t<item android:drawable=\"@drawable/scrubber_control_normal_holo\" />\n</selector>\n"
  },
  {
    "path": "res/drawable/scrubber_progress_horizontal_holo_dark.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2010 The Android Open Source Project Licensed under the \n\tApache License, Version 2.0 (the \"License\"); you may not use this file except \n\tin compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 \n\tUnless required by applicable law or agreed to in writing, software distributed \n\tunder the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES \n\tOR CONDITIONS OF ANY KIND, either express or implied. See the License for \n\tthe specific language governing permissions and limitations under the License. -->\n\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\t<item android:id=\"@android:id/background\" android:drawable=\"@drawable/scrubber_track_holo_dark\" />\n\t<item android:id=\"@android:id/secondaryProgress\">\n\t\t<scale android:scaleWidth=\"100%\" android:drawable=\"@drawable/scrubber_secondary_holo\" />\n\t</item>\n\t<item android:id=\"@android:id/progress\">\n\t\t<scale android:scaleWidth=\"100%\" android:drawable=\"@drawable/scrubber_primary_holo\" />\n\t</item>\n</layer-list>\n"
  },
  {
    "path": "res/layout/activity_video.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<io.vov.vitamio.widget.CenterLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/video_root\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"@android:color/black\"\n    android:orientation=\"horizontal\" >\n\n    <com.nmbb.oplayer.ui.player.VideoView\n        android:id=\"@+id/video\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:fitsSystemWindows=\"true\"\n        android:saveEnabled=\"true\" />\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"horizontal\" >\n\n        <RelativeLayout\n            android:id=\"@+id/video_loading\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_centerInParent=\"true\"\n            android:visibility=\"gone\" >\n\n            <!-- <ImageView\n                android:id=\"@+id/video_loading_progress\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_alignParentTop=\"true\"\n                android:layout_centerHorizontal=\"true\"\n                android:src=\"@drawable/icon\" /> -->\n            <ProgressBar\n                android:id=\"@+id/video_loading_progress\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_alignParentTop=\"true\"\n                android:layout_centerHorizontal=\"true\" />\n\n            <TextView\n                android:id=\"@+id/video_loading_text\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_below=\"@+id/video_loading_progress\"\n                android:layout_centerHorizontal=\"true\"\n                android:paddingTop=\"7.0dip\"\n                android:text=\"@string/video_layout_loading\"\n                android:textColor=\"@android:color/white\"\n                android:textSize=\"20.0sp\" />\n        </RelativeLayout>\n\n        <RelativeLayout\n            android:id=\"@+id/subtitle_container\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentBottom=\"true\"\n            android:layout_marginBottom=\"10.0dip\" >\n\n            <io.vov.vitamio.widget.OutlineTextView\n                android:id=\"@+id/subtitle_text\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_centerHorizontal=\"true\"\n                android:gravity=\"center_vertical|center_horizontal\"\n                android:shadowColor=\"@color/gray\"\n                android:shadowDx=\"1\"\n                android:shadowDy=\"1\"\n                android:shadowRadius=\"2\"\n                android:textColor=\"@android:color/white\"\n                android:textSize=\"18sp\"\n                android:textStyle=\"bold\" />\n\n            <ImageView\n                android:id=\"@+id/subtitle_image\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_centerHorizontal=\"true\"\n                android:contentDescription=\"@string/imageview_content_description\"\n                android:gravity=\"center_vertical|center_horizontal\"\n                android:visibility=\"gone\" />\n        </RelativeLayout>\n    </RelativeLayout>\n\n</io.vov.vitamio.widget.CenterLayout>"
  },
  {
    "path": "res/layout/brightness_volumn.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:background=\"#00000000\"\n    android:orientation=\"horizontal\"\n    android:padding=\"0dip\" >\n\n    <ImageView\n        android:id=\"@+id/operation_bg\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"\n        android:src=\"@drawable/video_volumn_bg\" />\n\n    <FrameLayout\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"bottom|center_horizontal\"\n        android:paddingBottom=\"25dip\" >\n\n        <ImageView\n            android:id=\"@+id/operation_full\"\n            android:layout_width=\"94dip\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"left\"\n            android:src=\"@drawable/video_num_bg\" />\n\n        <ImageView\n            android:id=\"@+id/operation_percent\"\n            android:layout_width=\"0dip\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"left\"\n            android:scaleType=\"matrix\"\n            android:src=\"@drawable/video_num_front\" />\n    </FrameLayout>\n\n</FrameLayout>"
  },
  {
    "path": "res/layout/common_loading.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:layout_width=\"fill_parent\"\r\n    android:layout_height=\"fill_parent\"\r\n    android:id=\"@+id/loading\" \r\n    android:background=\"@null\"\r\n    android:visibility=\"gone\" >\r\n\r\n    <LinearLayout\r\n        android:layout_width=\"wrap_content\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_centerInParent=\"true\" >\r\n\r\n        <ProgressBar\r\n            style=\"?android:attr/progressBarStyleSmallTitle\"\r\n            android:layout_width=\"wrap_content\"\r\n            android:layout_height=\"wrap_content\" />\r\n\r\n        <TextView\r\n            android:layout_width=\"wrap_content\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:textColor=\"#ff274462\"\r\n            android:text=\"@string/loadinfo\" />\r\n    </LinearLayout>\r\n</RelativeLayout>"
  },
  {
    "path": "res/layout/fragment_file.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"fill_parent\"\n    android:layout_height=\"fill_parent\"\n    android:orientation=\"vertical\" >\n\n    <ListView\n        android:id=\"@+id/templist\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"wrap_content\"\n        android:cacheColorHint=\"@android:color/transparent\"\n        android:divider=\"@drawable/ic_line\"\n        android:drawSelectorOnTop=\"false\"\n        android:fadingEdge=\"none\"\n        android:listSelector=\"@android:color/transparent\"\n        android:scrollbars=\"none\"\n        android:visibility=\"gone\" />\n\n    <LinearLayout\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"0dip\"\n        android:layout_weight=\"1.0\"\n        android:orientation=\"horizontal\" >\n\n        <FrameLayout\n            android:layout_width=\"0dip\"\n            android:layout_height=\"fill_parent\"\n            android:layout_weight=\"1.0\"\n            android:orientation=\"vertical\" >\n\n            <ListView\n                android:id=\"@android:id/list\"\n                android:layout_width=\"fill_parent\"\n                android:layout_height=\"fill_parent\"\n                android:cacheColorHint=\"@android:color/transparent\"\n                android:divider=\"@drawable/ic_line\"\n                android:drawSelectorOnTop=\"false\"\n                android:fadingEdge=\"none\"\n                android:listSelector=\"@android:color/transparent\"\n                android:scrollbars=\"none\" />\n\n            <TextView\n                android:id=\"@+id/first_letter_overlay\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_gravity=\"right\"\n                android:layout_marginRight=\"50.0dip\"\n                android:layout_marginTop=\"49.0dip\"\n                android:background=\"@drawable/fast_scroller_overlay\"\n                android:gravity=\"center\"\n                android:paddingBottom=\"5.0dip\"\n                android:scaleType=\"center\"\n                android:textSize=\"43.0dip\"\n                android:visibility=\"gone\" />\n\n            <include layout=\"@layout/common_loading\" />\n        </FrameLayout>\n\n        <ImageView\n            android:id=\"@+id/alphabet_scroller\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"fill_parent\"\n            android:layout_gravity=\"center\"\n            android:paddingRight=\"0dip\"\n            android:scaleType=\"fitXY\"\n            android:src=\"@drawable/alphabet_scroller_bg\" />\n    </LinearLayout>\n\n    <RelativeLayout\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"wrap_content\"\n        android:background=\"@drawable/sd_bar_bg\" >\n\n        <ProgressBar\n            android:id=\"@android:id/progress\"\n            style=\"?android:attr/progressBarStyleSmall\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentLeft=\"true\"\n            android:layout_centerVertical=\"true\"\n            android:layout_marginLeft=\"5dip\"\n            android:visibility=\"gone\" />\n\n        <TextView\n            android:id=\"@+id/sd_block\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentRight=\"true\"\n            android:layout_centerVertical=\"true\"\n            android:layout_marginRight=\"5dip\"\n            android:textColor=\"@color/white\" />\n    </RelativeLayout>\n\n</LinearLayout>"
  },
  {
    "path": "res/layout/fragment_file_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/linearlayout_row\"\n    android:layout_width=\"fill_parent\"\n    android:layout_height=\"wrap_content\" >\n\n    <ImageView\n        android:layout_width=\"92.0dip\"\n        android:layout_height=\"68.0dip\"\n        android:scaleType=\"fitXY\"\n        android:src=\"@drawable/video_back\" />\n\n    <ImageView\n        android:id=\"@+id/thumbnail\"\n        android:layout_width=\"83.0dip\"\n        android:layout_height=\"60.0dip\"\n        layout_gravity=\"center_vertical\"\n        android:layout_centerVertical=\"true\"\n        android:layout_marginLeft=\"4.0dip\"\n        android:background=\"@drawable/default_thumbnail\"\n        android:scaleType=\"fitXY\" />\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentTop=\"true\"\n        android:layout_marginLeft=\"10.0dip\"\n        android:layout_marginTop=\"5.0dip\"\n        android:layout_toRightOf=\"@+id/thumbnail\"\n        android:layout_toLeftOf=\"@+id/status\"\n        android:marqueeRepeatLimit=\"marquee_forever\"\n        android:maxLines=\"2\"\n        android:singleLine=\"false\"\n        android:textColor=\"@color/title\"\n        android:textSize=\"16sp\"\n        android:textStyle=\"normal\" />\n\n    <TextView\n        android:id=\"@+id/file_size\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentBottom=\"true\"\n        android:layout_below=\"@+id/title\"\n        android:layout_marginLeft=\"10.0dip\"\n        android:layout_toRightOf=\"@+id/thumbnail\"\n        android:paddingBottom=\"3.0dip\"\n        android:textColor=\"@color/title\"\n        android:textSize=\"12sp\" />\n\n    <ImageView\n        android:id=\"@+id/status\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentRight=\"true\"\n        android:layout_centerVertical=\"true\"\n        android:layout_marginLeft=\"4.0dip\"\n        android:layout_marginRight=\"4.0dip\"\n        android:visibility=\"gone\" />\n\n</RelativeLayout>"
  },
  {
    "path": "res/layout/fragment_online.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"fill_parent\"\n    android:layout_height=\"fill_parent\" >\n\n    <ListView\n        android:id=\"@android:id/list\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"fill_parent\"\n        android:cacheColorHint=\"@android:color/transparent\"\n        android:divider=\"@drawable/ic_line\"\n        android:drawSelectorOnTop=\"false\"\n        android:fadingEdge=\"none\"\n        android:listSelector=\"#e8e8e8\"\n        android:scrollbars=\"none\" />\n\n    <WebView\n        android:id=\"@+id/webview\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"fill_parent\"\n        android:visibility=\"gone\" >\n    </WebView>\n\n    <include layout=\"@layout/common_loading\" />\n\n    <TextView\n        android:id=\"@+id/url\" android:visibility=\"gone\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"bottom\" android:singleLine=\"true\"\n        android:marqueeRepeatLimit=\"marquee_forever\"\n        android:layout_marginBottom=\"5dip\"\n        android:layout_marginLeft=\"5dip\"\n        android:background=\"@drawable/in_bubble\" />\n\n</FrameLayout>"
  },
  {
    "path": "res/layout/fragment_online_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/linearlayout_row\"\n    android:layout_width=\"fill_parent\"\n    android:layout_height=\"wrap_content\" >\n\n    <ImageView\n        android:id=\"@+id/thumbnail\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        layout_gravity=\"center_vertical\"\n        android:layout_centerVertical=\"true\"\n        android:layout_margin=\"4.0dip\" />\n\n    <ImageView android:id=\"@+id/arrow\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentRight=\"true\"\n        android:layout_centerVertical=\"true\"\n        android:layout_marginRight=\"5.0dip\"\n        android:src=\"@drawable/arrow_right\" />\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_toLeftOf=\"@+id/arrow\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerVertical=\"true\"\n        android:layout_marginRight=\"8.0dip\"\n        android:marqueeRepeatLimit=\"marquee_forever\"\n        android:maxLines=\"2\"\n        android:singleLine=\"false\"\n        android:textColor=\"@color/title\"\n        android:textSize=\"16sp\"\n        android:textStyle=\"normal\" />\n\n</RelativeLayout>"
  },
  {
    "path": "res/layout/fragment_pager.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n\tandroid:orientation=\"vertical\" android:gravity=\"center_horizontal\"\n\tandroid:layout_width=\"fill_parent\" android:layout_height=\"fill_parent\">\n\t<RadioGroup android:gravity=\"center_vertical\"\n\t\tandroid:layout_width=\"fill_parent\" android:layout_height=\"wrap_content\"\n\t\tandroid:orientation=\"horizontal\">\n\t\t<RadioButton android:id=\"@+id/radio_file\" android:checked=\"true\"\n\t\t\tstyle=\"@style/main_tab_bottom\" android:drawableTop=\"@drawable/video_file\"\n\t\t\tandroid:text=\"@string/title_file\" />\n\t\t<RadioButton android:id=\"@+id/radio_online\"\n\t\t\tandroid:drawableTop=\"@drawable/video_online\" style=\"@style/main_tab_bottom\"\n\t\t\tandroid:text=\"@string/title_online\" />\n\t</RadioGroup>\n\t<android.support.v4.view.ViewPager\n\t\tandroid:background=\"@color/background\" android:id=\"@+id/pager\"\n\t\tandroid:layout_width=\"fill_parent\" android:layout_height=\"fill_parent\">\n\t</android.support.v4.view.ViewPager>\n</LinearLayout>\n"
  },
  {
    "path": "res/layout/mediacontroller.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\" >\n\n    <RelativeLayout\n        android:id=\"@+id/mediacontroller\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_margin=\"0.0dip\"\n        android:orientation=\"horizontal\"\n        android:visibility=\"invisible\" >\n\n        <LinearLayout\n            android:id=\"@+id/info_panel\"\n            style=\"@style/InfoPanel_Container\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"@dimen/action_bar_default_height\"\n            android:gravity=\"center_horizontal|center\"\n            android:orientation=\"horizontal\" >\n\n            <ImageButton\n                android:id=\"@+id/mediacontroller_lock\"\n                style=\"@style/MediaController_Button\"\n                android:layout_width=\"@dimen/action_bar_default_height\"\n                android:layout_height=\"match_parent\"\n                android:contentDescription=\"@string/content_desc_lock\"\n                android:src=\"@drawable/mediacontroller_unlock\" />\n\n            <TextView\n                android:id=\"@+id/mediacontroller_file_name\"\n                android:layout_width=\"0dp\"\n                android:layout_height=\"wrap_content\"\n                android:layout_weight=\"1\"\n                android:paddingLeft=\"8dip\"\n                android:singleLine=\"true\"\n                android:textColor=\"@android:color/white\"\n                android:textSize=\"16sp\"\n                android:textStyle=\"bold\" />\n\n            <TextView\n                android:id=\"@+id/download_rate\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:drawableLeft=\"@drawable/video_download_rate\"\n                android:drawablePadding=\"3.0dp\"\n                android:paddingRight=\"12dp\"\n                android:textColor=\"@android:color/white\"\n                android:visibility=\"gone\" />\n\n            <TextView\n                android:id=\"@+id/date_time\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:paddingRight=\"12dp\"\n                android:textColor=\"@android:color/white\" />\n\n            <TextView\n                android:id=\"@+id/battery_level\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:paddingRight=\"12dp\"\n                android:textColor=\"@android:color/white\" />\n\n            <ImageButton\n                android:id=\"@+id/video_menu\"\n                style=\"@style/MediaController_Button\"\n                android:layout_width=\"@dimen/action_bar_default_height\"\n                android:layout_height=\"match_parent\"\n                android:contentDescription=\"@string/imageview_content_description\"\n                android:src=\"@drawable/video_more\" />\n        </LinearLayout>\n\n        <LinearLayout\n            android:id=\"@+id/mediacontroller_controls\"\n            style=\"@style/MediaController_Container\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentBottom=\"true\"\n            android:layout_margin=\"0.0dip\"\n            android:orientation=\"vertical\" >\n\n            <RelativeLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:orientation=\"horizontal\" >\n\n                <TextView\n                    android:id=\"@+id/mediacontroller_time_current\"\n                    style=\"@style/MediaController_Text\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_alignParentLeft=\"true\"\n                    android:layout_centerVertical=\"true\" />\n\n                <SeekBar\n                    android:id=\"@+id/mediacontroller_seekbar\"\n                    style=\"@style/Widget.ZI.SeekBar\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_toLeftOf=\"@+id/mediacontroller_time_total\"\n                    android:layout_toRightOf=\"@+id/mediacontroller_time_current\"\n                    android:focusable=\"true\"\n                    android:max=\"1000\" />\n\n                <TextView\n                    android:id=\"@+id/mediacontroller_time_total\"\n                    style=\"@style/MediaController_Text\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_alignParentRight=\"true\"\n                    android:layout_centerVertical=\"true\" />\n            </RelativeLayout>\n\n            <RelativeLayout\n                android:id=\"@+id/mediacontroller_controls_buttons\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginBottom=\"@dimen/mediacontroller_buttons_bottom_margin\"\n                android:layout_marginTop=\"@dimen/mediacontroller_buttons_top_margin\"\n                android:orientation=\"horizontal\" >\n\n                <ImageButton\n                    android:id=\"@+id/mediacontroller_play_pause\"\n                    style=\"@style/MediaController_Button\"\n                    android:layout_width=\"64dip\"\n                    android:layout_height=\"48dip\"\n                    android:layout_centerInParent=\"true\"\n                    android:contentDescription=\"@string/imageview_content_description\"\n                    android:gravity=\"center\"\n                    android:src=\"@drawable/mediacontroller_pause\" />\n\n                <ImageButton\n                    android:id=\"@+id/mediacontroller_snapshot\"\n                    style=\"@style/MediaController_Button\"\n                    android:layout_width=\"64dip\"\n                    android:layout_height=\"42dip\"\n                    android:layout_centerVertical=\"true\"\n                    android:layout_marginRight=\"@dimen/mediacontroller_button_space\"\n                    android:layout_toLeftOf=\"@id/mediacontroller_play_pause\"\n                    android:contentDescription=\"@string/imageview_content_description\"\n                    android:gravity=\"center\"\n                    android:src=\"@drawable/mediacontroller_snapshot\" />\n\n                <ImageButton\n                    android:id=\"@+id/mediacontroller_screen_size\"\n                    style=\"@style/MediaController_Button\"\n                    android:layout_width=\"64dip\"\n                    android:layout_height=\"42dip\"\n                    android:layout_centerVertical=\"true\"\n                    android:layout_marginLeft=\"@dimen/mediacontroller_button_space\"\n                    android:layout_toRightOf=\"@id/mediacontroller_play_pause\"\n                    android:contentDescription=\"@string/imageview_content_description\"\n                    android:gravity=\"center\"\n                    android:src=\"@drawable/mediacontroller_screen_size\" />\n\n                <!--\n                     <TextView\n                    android:id=\"@+id/mediacontroller_definition\"\n                    style=\"@style/MediaController_Button\"\n                    android:layout_width=\"64dip\"\n                    android:layout_height=\"42dip\"\n                    android:layout_centerVertical=\"true\"\n                    android:layout_marginLeft=\"@dimen/mediacontroller_button_space\"\n                    android:layout_toRightOf=\"@id/mediacontroller_screen_size\"\n                    android:gravity=\"center\"\n                    android:text=\"普清\"\n                    android:textColor=\"@color/white\"\n                    android:textSize=\"18sp\" />\n                -->\n            </RelativeLayout>\n        </LinearLayout>\n    </RelativeLayout>\n\n    <!--\n         <RelativeLayout\n        android:id=\"@+id/operation_container\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"horizontal\" >\n    -->\n\n    <TextView\n        android:id=\"@+id/operation_info\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:background=\"@color/mediacontroller_bg\"\n        android:paddingBottom=\"0dip\"\n        android:paddingLeft=\"8dip\"\n        android:paddingRight=\"8dip\"\n        android:paddingTop=\"0dip\"\n        android:textColor=\"@android:color/white\"\n        android:textSize=\"46sp\"\n        android:textStyle=\"bold\"\n        android:visibility=\"gone\" />\n\n    <include\n        android:id=\"@+id/operation_volume_brightness\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        layout=\"@layout/brightness_volumn\"\n        android:visibility=\"gone\" />\n    <!-- </RelativeLayout> -->\n\n</RelativeLayout>"
  },
  {
    "path": "res/layout/mediaplayer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n\tandroid:orientation=\"vertical\" android:layout_width=\"fill_parent\"\n\tandroid:layout_height=\"fill_parent\">\n\t<SurfaceView android:id=\"@+id/surface\"\n\t\tandroid:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\"\n\t\tandroid:layout_centerHorizontal=\"true\" android:layout_centerVertical=\"true\" />\n</RelativeLayout>"
  },
  {
    "path": "res/layout/my_media_controller.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n\tandroid:background=\"#FFFFFFFF\" android:orientation=\"horizontal\"\n\tandroid:layout_width=\"fill_parent\" android:layout_height=\"74dip\"\n\tandroid:layout_marginLeft=\"0.0dip\" android:layout_marginRight=\"0.0dip\"\n\tandroid:layout_marginBottom=\"0.0dip\" android:layout_alignParentBottom=\"true\">\n\t<ImageButton android:id=\"@+id/mediacontroller_pause\"\n\t\tandroid:background=\"#00000000\" android:layout_width=\"54dip\"\n\t\tandroid:layout_height=\"34dip\" android:layout_marginRight=\"7.0dip\"\n\t\tandroid:layout_alignParentRight=\"true\" android:layout_centerVertical=\"true\"\n\t\tandroid:layout_centerHorizontal=\"true\" android:gravity=\"center\" />\n\t<RelativeLayout android:layout_width=\"fill_parent\"\n\t\tandroid:layout_height=\"wrap_content\" android:layout_marginTop=\"2dip\"\n\t\tandroid:layout_marginBottom=\"2dip\" android:layout_marginLeft=\"7.0dip\"\n\t\tandroid:layout_marginRight=\"7.0dip\" android:layout_toLeftOf=\"@+id/mediacontroller_pause\">\n\t\t<RelativeLayout android:layout_width=\"fill_parent\"\n\t\t\tandroid:layout_height=\"wrap_content\" android:id=\"@+id/times\">\n\t\t\t<TextView android:id=\"@+id/mediacontroller_time_current\"\n\t\t\t\tandroid:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\"\n\t\t\t\tandroid:layout_alignParentLeft=\"true\" android:layout_alignParentTop=\"true\" />\n\t\t\t<TextView android:id=\"@+id/mediacontroller_time_total\"\n\t\t\t\tandroid:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\"\n\t\t\t\tandroid:layout_alignParentRight=\"true\"\n\t\t\t\tandroid:layout_alignParentTop=\"true\" />\n\t\t</RelativeLayout>\n\n\t\t<SeekBar android:id=\"@+id/mediacontroller_progress\"\n\t\t\tandroid:focusable=\"false\" android:layout_width=\"fill_parent\"\n\t\t\tandroid:layout_height=\"wrap_content\" android:layout_below=\"@+id/times\"\n\t\t\tandroid:layout_centerVertical=\"true\" />\n\n\t\t<TextView android:id=\"@+id/mediacontroller_file_name\"\n\t\t\tandroid:ellipsize=\"marquee\" android:layout_width=\"wrap_content\"\n\t\t\tandroid:layout_height=\"wrap_content\" android:singleLine=\"true\"\n\t\t\tandroid:layout_alignParentBottom=\"true\" />\n\t</RelativeLayout>\n</RelativeLayout>\n"
  },
  {
    "path": "res/layout/videoview.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"fill_parent\"\n    android:layout_height=\"fill_parent\"\n    android:orientation=\"vertical\" >\n\n    <io.vov.vitamio.widget.VideoView\n        android:id=\"@+id/surface_view\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"fill_parent\"\n        android:layout_centerHorizontal=\"true\"\n        android:layout_centerVertical=\"true\" />\n\n    <LinearLayout\n        android:id=\"@+id/video_loading\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:gravity=\"center_vertical\" >\n\n        <ProgressBar\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\" />\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:paddingTop=\"7.0dip\"\n            android:text=\"@string/video_layout_loading\"\n            android:textColor=\"@color/white\"\n            android:textSize=\"20.0sp\" />\n    </LinearLayout>\n\n    <FrameLayout\n        android:id=\"@+id/operation_volume_brightness\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:background=\"#00000000\"\n        android:orientation=\"horizontal\"\n        android:padding=\"0dip\"\n        android:visibility=\"invisible\" >\n\n        <ImageView\n            android:id=\"@+id/operation_bg\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center\"\n            android:src=\"@drawable/video_volumn_bg\" />\n\n        <FrameLayout\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"bottom|center_horizontal\"\n            android:paddingBottom=\"25dip\" >\n\n            <ImageView\n                android:id=\"@+id/operation_full\"\n                android:layout_width=\"94dip\"\n                android:layout_height=\"wrap_content\"\n                android:layout_gravity=\"left\"\n                android:src=\"@drawable/video_num_bg\" />\n\n            <ImageView\n                android:id=\"@+id/operation_percent\"\n                android:layout_width=\"0dip\"\n                android:layout_height=\"wrap_content\"\n                android:layout_gravity=\"left\"\n                android:scaleType=\"matrix\"\n                android:src=\"@drawable/video_num_front\" />\n        </FrameLayout>\n    </FrameLayout>\n\n</RelativeLayout>"
  },
  {
    "path": "res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n    <color name=\"white\">#ffffffff</color>\r\n    <color name=\"black\">#ff000000</color>\r\n    <color name=\"blue\">#ff0000ff</color>\r\n    <color name=\"green\">#ff00ff00</color>\r\n    <color name=\"red\">#ffff0000</color>\r\n    <color name=\"higtlight\">#ff0078f0</color>\r\n    <color name=\"durationtext\">#ff7d7d7d</color>\r\n    <color name=\"background\">#ffc3ddea</color>\r\n    <color name=\"yellow\">#ffffcc00</color>\r\n    <color name=\"title\">#ff274462</color>\r\n    <color name=\"gray\">#808080ff</color>\r\n    <color name=\"transparent\">#00000000</color>\r\n    <color name=\"mediacontroller_bg_pressed\">#ff53c1bd</color>\r\n    <color name=\"mediacontroller_bg\">#99000000</color>\r\n    <color name=\"background_dark\">#f4f4f4</color>\r\n</resources>\r\n"
  },
  {
    "path": "res/values/dimens.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<resources>\r\n\r\n    <dimen name=\"LargeTextSize\">16.0dip</dimen>\r\n    <dimen name=\"BasicTextSize\">15.0dip</dimen>\r\n    <dimen name=\"TitleTextSize\">18.0dip</dimen>\r\n    <dimen name=\"SmallTextSize\">14.0dip</dimen>\r\n    <dimen name=\"SmallerTextSize\">13.0dip</dimen>\r\n    <dimen name=\"LargestTextSize\">30.0dip</dimen>\r\n    <dimen name=\"ChattingContentMinHeight\">49.0dip</dimen>\r\n    <dimen name=\"ChuZhuangWH\">40.0dip</dimen>\r\n    <dimen name=\"action_bar_default_height\">48dp</dimen>\r\n    <dimen name=\"mediacontroller_button_space\">32dp</dimen>\r\n    <dimen name=\"mediacontroller_buttons_top_margin\">2dp</dimen>\r\n    <dimen name=\"mediacontroller_buttons_bottom_margin\">0dp</dimen>\r\n\r\n</resources>"
  },
  {
    "path": "res/values/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <string name=\"app_name\">开播视频</string>\n    <string name=\"version_name\">1.0</string>\n    <string name=\"title_file\">本地视频</string>\n    <string name=\"title_online\">在线视频</string>\n    <string name=\"init_decoders\">初始化播放器...</string>\n    <string name=\"loadinfo\">载入中，请稍后...</string>\n    <string name=\"file_oper\">文件操作</string>\n    <string name=\"file_rename\">重命名</string>\n    <string name=\"file_rename_failed\">重命名失败</string>\n    <string name=\"file_rename_exists\">文件已存在</string>\n    <string name=\"file_delete\">删除</string>\n    <string name=\"file_delete_confirm\">确定删除 (%s) ？</string>\n    <string name=\"video_layout_loading\">正在缓冲...</string>\n    <string name=\"vitamio_theme_app_name\">VPlayer codec</string>\n    <string name=\"VideoView_error_title\">Cannot play video</string>\n    <string name=\"VideoView_error_text_invalid_progressive_playback\">Sorry, this video is not valid for streaming to\n\t\tthis device.</string>\n    <string name=\"VideoView_error_text_unknown\">对不起,这个视频不能播放。</string>\n    <string name=\"VideoView_error_button\">OK</string>\n    <string name=\"mediacontroller_play_pause\">Play/Pause</string>\n    <string name=\"imageview_content_description\"></string>\n    <string name=\"content_desc_lock\">锁定</string>\n    <string name=\"video_original\">100%</string>\n    <string name=\"video_fit_screen\">全屏</string>\n    <string name=\"video_stretch\">拉伸</string>\n    <string name=\"video_crop\">裁剪</string>\n    <string name=\"video_screen_locked\">屏幕已锁定</string>\n    <string name=\"video_screen_unlocked\">屏幕锁定已解除</string>\n    <string name=\"video_layout_buffering_progress\">缓冲: %.2f%%</string>\n    <string name=\"video_cannot_play\">对不起,这个视频不能播放。</string>\n    <string name=\"file_explorer_sdcard_not_available\">SD卡无法读取</string>\n    <string name=\"video_screenshot_save_in\">截图存放在 %s.</string>\n    <string name=\"video_screenshot_failed\">截图失败</string>\n    <string name=\"closing_file\">正在退出…</string>\n\n</resources> <!-- <string name=\"VideoView_error_text_unknown\">Sorry, this video cannot be played.</string> -->\n"
  },
  {
    "path": "res/values/styles.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n\r\n    <!--\r\n        Base application theme, dependent on API level. This theme is replaced\r\n        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.\r\r\r\n    -->\r\n    <style name=\"AppBaseTheme\" parent=\"android:Theme.Light\">\r\n        <!--\r\n            Theme customizations available in newer API levels can go in\r\n            res/values-vXX/styles.xml, while customizations related to\r\n            backward-compatibility can go here.\r\r\r\n        -->\r\n    </style>\r\n\r\n    <!-- Application theme. -->\r\n    <style name=\"AppTheme\" parent=\"AppBaseTheme\">\r\n        <item name=\"android:windowNoTitle\">true</item>\r\n        <item name=\"android:windowBackground\">@color/background_dark</item>\r\n        <!-- All customizations that are NOT specific to a particular API-level can go here. -->\r\n    </style>\r\n\r\n    <style name=\"Widget.ZI.SeekBar\" parent=\"android:Widget.SeekBar\">\r\n        <item name=\"android:progressDrawable\">@drawable/scrubber_progress_horizontal_holo_dark</item>\r\n        <item name=\"android:indeterminateDrawable\">@drawable/scrubber_progress_horizontal_holo_dark</item>\r\n        <item name=\"android:minHeight\">13dip</item>\r\n        <item name=\"android:maxHeight\">13dip</item>\r\n        <item name=\"android:thumb\">@drawable/scrubber_control_selector_holo</item>\r\n        <item name=\"android:thumbOffset\">16dip</item>\r\n        <item name=\"android:paddingLeft\">16dip</item>\r\n        <item name=\"android:paddingRight\">16dip</item>\r\n    </style>\r\n\r\n    <style name=\"main_tab_bottom\">\r\n        <item name=\"android:textSize\">12.0sp</item>\r\n        <item name=\"android:textColor\">#ffffffff</item>\r\n        <item name=\"android:ellipsize\">marquee</item>\r\n        <item name=\"android:gravity\">center_horizontal</item>\r\n        <item name=\"android:paddingTop\">2.0dip</item>\r\n        <!-- <item name=\"android:paddingTop\">5.0dip</item> -->\r\n        <item name=\"android:layout_width\">fill_parent</item>\r\n        <item name=\"android:layout_height\">wrap_content</item>\r\n        <item name=\"android:button\">@null</item>\r\n        <item name=\"android:singleLine\">true</item>\r\n        <!-- <item name=\"android:drawablePadding\">3.0dip</item> -->\r\n        <item name=\"android:layout_weight\">1.0</item>\r\n        <item name=\"android:background\">@drawable/home_btn_bg</item>\r\n    </style>\r\n\r\n    <style name=\"MediaController_SeekBar\">\r\n        <item name=\"android:minHeight\">16dip</item>\r\n        <item name=\"android:maxHeight\">16dip</item>\r\n        <item name=\"android:progressDrawable\">@drawable/mediacontroller_seekbar</item>\r\n        <item name=\"android:thumb\">@drawable/mediacontroller_seekbar_thumb</item>\r\n    </style>\r\n\r\n    <style name=\"MediaController_Text\">\r\n        <item name=\"android:textColor\">#ffffffff</item>\r\n        <item name=\"android:textSize\">14sp</item>\r\n        <item name=\"android:textStyle\">bold</item>\r\n    </style>\r\n\r\n    <style name=\"InfoPanel_Container\">\r\n        <item name=\"android:background\">@color/mediacontroller_bg</item>\r\n    </style>\r\n\r\n    <style name=\"MediaController_Container\">\r\n        <item name=\"android:background\">@color/mediacontroller_bg</item>\r\n        <item name=\"android:paddingTop\">4dip</item>\r\n        <item name=\"android:paddingBottom\">8dip</item>\r\n        <item name=\"android:paddingLeft\">8dip</item>\r\n        <item name=\"android:paddingRight\">8dip</item>\r\n    </style>\r\n\r\n    <style name=\"MediaController_Button\">\r\n        <item name=\"android:background\">@drawable/mediacontroller_btn_bg</item>\r\n    </style>\r\n\r\n    <style name=\"MediaController_Text\">\r\n        <item name=\"android:textColor\">#ffffffff</item>\r\n        <item name=\"android:textSize\">14sp</item>\r\n        <item name=\"android:textStyle\">bold</item>\r\n    </style>\r\n\r\n</resources>"
  },
  {
    "path": "res/values-large/dimens.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<resources>\r\n    <dimen name=\"ChuZhuangWH\">48.0dip</dimen>\r\n</resources>"
  },
  {
    "path": "res/values-small/dimens.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<resources>\r\n    <dimen name=\"ChuZhuangWH\">32.0dip</dimen>\r\n</resources>"
  },
  {
    "path": "res/values-sw600dp/dimens.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<resources>\n    \n    <dimen name=\"action_bar_default_height\">56dp</dimen>\n    <dimen name=\"mediacontroller_buttons_top_margin\">8dp</dimen>\n    <dimen name=\"mediacontroller_buttons_bottom_margin\">2dp</dimen>\n\n</resources>"
  },
  {
    "path": "res/values-v11/styles.xml",
    "content": "<resources>\n\n    <!--\n        Base application theme for API 11+. This theme completely replaces\n        AppBaseTheme from res/values/styles.xml on API 11+ devices.\n    -->\n    <style name=\"AppBaseTheme\" parent=\"android:Theme.Holo.Light\">\n        <!-- API 11 theme customizations can go here. -->\n    </style>\n\n</resources>"
  },
  {
    "path": "res/values-v14/styles.xml",
    "content": "<resources>\n\n    <!--\n        Base application theme for API 14+. This theme completely replaces\n        AppBaseTheme from BOTH res/values/styles.xml and\n        res/values-v11/styles.xml on API 14+ devices.\n    -->\n    <style name=\"AppBaseTheme\" parent=\"android:Theme.Holo.Light.DarkActionBar\">\n        <!-- API 14 theme customizations can go here. -->\n    </style>\n\n</resources>"
  },
  {
    "path": "res/values-xlarge/dimens.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<resources>\r\n\r\n    <dimen name=\"ChuZhuangWH\">64.0dip</dimen>\r\n    <dimen name=\"action_bar_default_height\">56dp</dimen>\r\n\r\n</resources>"
  },
  {
    "path": "src/com/nmbb/oplayer/OPlayerApplication.java",
    "content": "package com.nmbb.oplayer;\n\nimport android.app.Application;\nimport android.content.Context;\nimport android.os.Environment;\n\nimport com.nmbb.oplayer.util.FileUtils;\n\npublic class OPlayerApplication extends Application {\n\n\tprivate static OPlayerApplication mApplication;\n\n\t/** OPlayer SD卡缓存路径 */\n\tpublic static final String OPLAYER_CACHE_BASE = Environment.getExternalStorageDirectory() + \"/oplayer\";\n\t/** 视频截图缓冲路径 */\n\tpublic static final String OPLAYER_VIDEO_THUMB = OPLAYER_CACHE_BASE + \"/thumb/\";\n\t/** 首次扫描 */\n\tpublic static final String PREF_KEY_FIRST = \"application_first\";\n\n\t@Override\n\tpublic void onCreate() {\n\t\tsuper.onCreate();\n\t\tmApplication = this;\n\n\t\tinit();\n\t}\n\n\tprivate void init() {\n\t\t//创建缓存目录\n\t\tFileUtils.createIfNoExists(OPLAYER_CACHE_BASE);\n\t\tFileUtils.createIfNoExists(OPLAYER_VIDEO_THUMB);\n\t}\n\n\tpublic static OPlayerApplication getApplication() {\n\t\treturn mApplication;\n\t}\n\n\tpublic static Context getContext() {\n\t\treturn mApplication;\n\t}\n\n\t/** 销毁 */\n\tpublic void destory() {\n\t\tmApplication = null;\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/OPreference.java",
    "content": "package com.nmbb.oplayer;\n\nimport java.util.Map.Entry;\n\nimport android.content.ContentValues;\nimport android.content.Context;\nimport android.content.SharedPreferences;\n\n/** 存储系统设置 */\npublic class OPreference {\n\n\tprivate static final String PREFERENCE_NAME = \"preference.db\";\n\n\tprivate SharedPreferences mPreference;\n\n\tpublic OPreference(Context ctx) {\n\t\tmPreference = ctx.getApplicationContext().getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);\n\t}\n\n\tpublic boolean putStringAndCommit(String key, String value) {\n\t\treturn mPreference.edit().putString(key, value).commit();\n\t}\n\n\tpublic boolean putIntAndCommit(String key, int value) {\n\t\treturn mPreference.edit().putInt(key, value).commit();\n\t}\n\n\tpublic boolean putBooleanAndCommit(String key, boolean value) {\n\t\treturn mPreference.edit().putBoolean(key, value).commit();\n\t}\n\n\tpublic boolean putIntAndCommit(ContentValues values) {\n\t\tSharedPreferences.Editor editor = mPreference.edit();\n\t\tfor (Entry<String, Object> value : values.valueSet()) {\n\t\t\teditor.putString(value.getKey(), value.getValue().toString());\n\t\t}\n\t\treturn editor.commit();\n\t}\n\n\tpublic String getString(String key) {\n\t\treturn getString(key, \"\");\n\t}\n\n\tpublic String getString(String key, String defValue) {\n\t\treturn mPreference.getString(key, defValue);\n\t}\n\n\tpublic int getInt(String key) {\n\t\treturn getInt(key, -1);\n\t}\n\n\tpublic int getInt(String key, int defValue) {\n\t\treturn mPreference.getInt(key, defValue);\n\t}\n\n\tpublic boolean getBoolean(String key) {\n\t\treturn getBoolean(key, false);\n\t}\n\n\tpublic boolean getBoolean(String key, boolean defValue) {\n\t\treturn mPreference.getBoolean(key, defValue);\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/business/FileBusiness.java",
    "content": "package com.nmbb.oplayer.business;\r\n\r\nimport java.sql.SQLException;\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\nimport com.j256.ormlite.dao.Dao;\r\nimport com.j256.ormlite.stmt.QueryBuilder;\r\nimport com.nmbb.oplayer.database.SQLiteHelperOrm;\r\nimport com.nmbb.oplayer.exception.Logger;\r\nimport com.nmbb.oplayer.po.POMedia;\r\n\r\npublic final class FileBusiness {\r\n\r\n\tprivate static final String TABLE_NAME = \"files\";\r\n\tprivate static final String TAG = \"FileBusiness\";\r\n\r\n\tpublic static List<POMedia> getAllSortFiles() {\r\n\t\tSQLiteHelperOrm db = new SQLiteHelperOrm();\r\n\t\ttry {\r\n\t\t\tDao<POMedia, Long> dao = db.getDao(POMedia.class);\r\n\t\t\tQueryBuilder<POMedia, Long> query = dao.queryBuilder();\r\n\t\t\tquery.orderBy(\"title_key\", true);\r\n\t\t\treturn dao.query(query.prepare());\r\n\t\t} catch (SQLException e) {\r\n\t\t\tLogger.e(e);\r\n\t\t} finally {\r\n\t\t\tif (db != null)\r\n\t\t\t\tdb.close();\r\n\t\t}\r\n\t\treturn new ArrayList<POMedia>();\r\n\t\t//\t\tnew DbHelper<POMedia>().queryForAll(POMedia.class);\r\n\t}\r\n\r\n\t//\t/** 获取所有已经排好序的列表 */\r\n\t//\tpublic static ArrayList<PFile> getAllSortFiles(final Context ctx) {\r\n\t//\t\tArrayList<PFile> result = new ArrayList<PFile>();\r\n\t//\t\tSQLiteHelper sqlite = new SQLiteHelper(ctx);\r\n\t//\t\tSQLiteDatabase db = sqlite.getReadableDatabase();\r\n\t//\t\tCursor c = null;\r\n\t//\t\ttry {\r\n\t//\t\t\tc = db.rawQuery(\"SELECT \" + FilesColumns.COL_ID + \",\" + FilesColumns.COL_TITLE + \",\" + FilesColumns.COL_TITLE_PINYIN + \",\" + FilesColumns.COL_PATH + \",\" + FilesColumns.COL_DURATION + \",\" + FilesColumns.COL_POSITION + \",\" + FilesColumns.COL_LAST_ACCESS_TIME + \",\" + FilesColumns.COL_THUMB + \",\" + FilesColumns.COL_FILE_SIZE + \" FROM files\", null);\r\n\t//\t\t\twhile (c.moveToNext()) {\r\n\t//\t\t\t\tPFile po = new PFile();\r\n\t//\t\t\t\tint index = 0;\r\n\t//\t\t\t\tpo._id = c.getLong(index++);\r\n\t//\t\t\t\tpo.title = c.getString(index++);\r\n\t//\t\t\t\tpo.title_pinyin = c.getString(index++);\r\n\t//\t\t\t\tpo.path = c.getString(index++);\r\n\t//\t\t\t\tpo.duration = c.getInt(index++);\r\n\t//\t\t\t\tpo.position = c.getInt(index++);\r\n\t//\t\t\t\tpo.last_access_time = c.getLong(index++);\r\n\t//\t\t\t\tpo.thumb = c.getString(index++);\r\n\t//\t\t\t\tpo.file_size = c.getLong(index++);\r\n\t//\t\t\t\tresult.add(po);\r\n\t//\t\t\t}\r\n\t//\t\t} finally {\r\n\t//\t\t\tif (c != null)\r\n\t//\t\t\t\tc.close();\r\n\t//\t\t}\r\n\t//\t\tdb.close();\r\n\t//\r\n\t//\t\tCollections.sort(result, new Comparator<PFile>() {\r\n\t//\r\n\t//\t\t\t@Override\r\n\t//\t\t\tpublic int compare(PFile f1, PFile f2) {\r\n\t//\t\t\t\tchar c1 = f1.title_pinyin.length() == 0 ? ' ' : f1.title_pinyin.charAt(0);\r\n\t//\t\t\t\tchar c2 = f2.title_pinyin.length() == 0 ? ' ' : f2.title_pinyin.charAt(0);\r\n\t//\t\t\t\treturn c1 == c2 ? 0 : (c1 > c2 ? 1 : -1);\r\n\t//\t\t\t}//相等返回0，-1 f2 > f2，-1\r\n\t//\r\n\t//\t\t});\r\n\t//\t\treturn result;\r\n\t//\t}\r\n\t//\r\n\t//\t/** 重命名文件 */\r\n\t//\tpublic static void renameFile(final Context ctx, final PFile p) {\r\n\t//\t\tSQLiteHelper sqlite = new SQLiteHelper(ctx);\r\n\t//\t\tSQLiteDatabase db = sqlite.getWritableDatabase();\r\n\t//\t\ttry {\r\n\t//\t\t\tContentValues values = new ContentValues();\r\n\t//\t\t\tvalues.put(FilesColumns.COL_TITLE, p.title);\r\n\t//\t\t\tvalues.put(FilesColumns.COL_TITLE_PINYIN, PinyinUtils.chineneToSpell(p.title.charAt(0) + \"\"));\r\n\t//\t\t\tvalues.put(FilesColumns.COL_PATH, p.path);\r\n\t//\t\t\tdb.update(TABLE_NAME, values, FilesColumns.COL_ID + \" = ?\", new String[] { p._id + \"\" });\r\n\t//\t\t} catch (Exception e) {\r\n\t//\t\t\te.printStackTrace();\r\n\t//\t\t} finally {\r\n\t//\t\t\ttry {\r\n\t//\t\t\t\tdb.close();\r\n\t//\t\t\t} catch (Exception e) {\r\n\t//\t\t\t}\r\n\t//\t\t}\r\n\t//\t}\r\n\t//\r\n\t//\t/** 删除文件 */\r\n\t//\tpublic static int deleteFile(final Context ctx, final PFile p) {\r\n\t//\t\tSQLiteHelper sqlite = new SQLiteHelper(ctx);\r\n\t//\t\tSQLiteDatabase db = sqlite.getWritableDatabase();\r\n\t//\t\tint result = -1;\r\n\t//\t\ttry {\r\n\t//\t\t\tresult = db.delete(TABLE_NAME, FilesColumns.COL_ID + \" = ?\", new String[] { p._id + \"\" });\r\n\t//\t\t} catch (Exception e) {\r\n\t//\t\t\te.printStackTrace();\r\n\t//\t\t} finally {\r\n\t//\t\t\ttry {\r\n\t//\t\t\t\tdb.close();\r\n\t//\t\t\t} catch (Exception e) {\r\n\t//\t\t\t}\r\n\t//\t\t}\r\n\t//\t\treturn result;\r\n\t//\t}\r\n\t//\r\n\t//\tpublic static void insertFile(final Context ctx, final PFile p) {\r\n\t//\t\tSQLiteHelper sqlite = new SQLiteHelper(ctx);\r\n\t//\t\tSQLiteDatabase db = sqlite.getWritableDatabase();\r\n\t//\t\ttry {\r\n\t//\t\t\tContentValues values = new ContentValues();\r\n\t//\t\t\tvalues.put(FilesColumns.COL_TITLE, p.title);\r\n\t//\t\t\tvalues.put(FilesColumns.COL_TITLE_PINYIN, PinyinUtils.chineneToSpell(p.title.charAt(0) + \"\"));\r\n\t//\t\t\tvalues.put(FilesColumns.COL_PATH, p.path);\r\n\t//\t\t\tvalues.put(FilesColumns.COL_LAST_ACCESS_TIME, System.currentTimeMillis());\r\n\t//\t\t\tvalues.put(FilesColumns.COL_FILE_SIZE, p.file_size);\r\n\t//\t\t\tdb.insert(TABLE_NAME, \"\", values);\r\n\t//\t\t} catch (Exception e) {\r\n\t//\t\t\te.printStackTrace();\r\n\t//\t\t} finally {\r\n\t//\t\t\ttry {\r\n\t//\t\t\t\tdb.close();\r\n\t//\t\t\t} catch (Exception e) {\r\n\t//\t\t\t}\r\n\t//\t\t}\r\n\t//\t}\r\n\t//\r\n\t//\t/** 批量提取视频的缩略图已经视频的宽高 */\r\n\t//\tpublic static ArrayList<PFile> batchBuildThumbnail(final Context ctx, final ArrayList<File> files) {\r\n\t//\t\tArrayList<PFile> result = new ArrayList<PFile>();\r\n\t//\r\n\t//\t\tfor (File f : files) {\r\n\t//\t\t\tPFile pf = new PFile();\r\n\t//\t\t\ttry {\r\n\t//\t\t\t\tif (f.exists() && f.canRead()) {\r\n\t//\t\t\t\t\t//取出视频的一帧图像\r\n\t////\t\t\t\t\tBitmap bitmap = ThumbnailUtils.createVideoThumbnail(ctx, f.getAbsolutePath(), Video.Thumbnails.MINI_KIND);\r\n\t////\t\t\t\t\tif (bitmap == null) {\r\n\t////\t\t\t\t\t\t//缩略图创建失败\r\n\t////\t\t\t\t\t\tbitmap = Bitmap.createBitmap(ThumbnailUtils.TARGET_SIZE_MINI_THUMBNAIL_WIDTH, ThumbnailUtils.TARGET_SIZE_MINI_THUMBNAIL_HEIGHT, Bitmap.Config.RGB_565);\r\n\t////\t\t\t\t\t\tLog.e(TAG, \"batchBuildThumbnail createBitmap faild : \" + f.getAbsolutePath());\r\n\t////\t\t\t\t\t}\r\n\t////\r\n\t////\t\t\t\t\tpf.width = bitmap.getWidth();\r\n\t////\t\t\t\t\tpf.height = bitmap.getHeight();\r\n\t////\r\n\t////\t\t\t\t\t//缩略图\r\n\t////\t\t\t\t\tbitmap = ThumbnailUtils.extractThumbnail(bitmap, ThumbnailUtils.dipToPX(ctx, ThumbnailUtils.TARGET_SIZE_MICRO_THUMBNAIL_WIDTH), ThumbnailUtils.dipToPX(ctx, ThumbnailUtils.TARGET_SIZE_MICRO_THUMBNAIL_HEIGHT), ThumbnailUtils.OPTIONS_RECYCLE_INPUT);\r\n\t////\t\t\t\t\tif (bitmap != null) {\r\n\t////\t\t\t\t\t\tFile thum = new File(f.getParent(), f.getName() + \".jpg\");\r\n\t////\t\t\t\t\t\tpf.thumb = thum.getAbsolutePath();\r\n\t////\t\t\t\t\t\t//thum.createNewFile();\r\n\t////\t\t\t\t\t\tFileOutputStream iStream = new FileOutputStream(thum);\r\n\t////\t\t\t\t\t\tbitmap.compress(Bitmap.CompressFormat.JPEG, 85, iStream);\r\n\t////\t\t\t\t\t\tiStream.close();\r\n\t////\t\t\t\t\t}\r\n\t////\r\n\t////\t\t\t\t\tif (bitmap != null)\r\n\t////\t\t\t\t\t\tbitmap.recycle();\r\n\t//\t\t\t\t\t\r\n\t//\t\t\t\t}\r\n\t//\t\t\t} catch (Exception e) {\r\n\t//\t\t\t\tLog.e(TAG, e);\r\n\t//\t\t\t\tcontinue;\r\n\t//\t\t\t} finally {\r\n\t//\t\t\t\tresult.add(pf);\r\n\t//\t\t\t}\r\n\t//\t\t}\r\n\t//\r\n\t//\t\treturn result;\r\n\t//\t}\r\n\t//\r\n\t//\t/** 批量插入数据 */\r\n\t//\tpublic static void batchInsertFiles(final Context ctx, final ArrayList<File> files) {\r\n\t//\t\tSQLiteHelper sqlite = new SQLiteHelper(ctx);\r\n\t//\t\tSQLiteDatabase db = sqlite.getWritableDatabase();\r\n\t//\t\ttry {\r\n\t//\t\t\tdb.beginTransaction();\r\n\t//\r\n\t//\t\t\tSQLiteStatement stat = db.compileStatement(\"INSERT INTO files(\" + FilesColumns.COL_TITLE + \",\" + FilesColumns.COL_TITLE_PINYIN + \",\" + FilesColumns.COL_PATH + \",\" + FilesColumns.COL_LAST_ACCESS_TIME + \",\" + FilesColumns.COL_FILE_SIZE + \") VALUES(?,?,?,?,?)\");\r\n\t//\t\t\tfor (File f : files) {\r\n\t//\t\t\t\tString name = f.getName();\r\n\t//\t\t\t\tint index = 1;\r\n\t//\t\t\t\tstat.bindString(index++, name);// title\r\n\t//\t\t\t\tstat.bindString(index++, PinyinUtils.chineneToSpell(name.charAt(0) + \"\"));// title_pinyin\r\n\t//\t\t\t\tstat.bindString(index++, f.getPath());// path\r\n\t//\t\t\t\tstat.bindLong(index++, System.currentTimeMillis());// last_access_time\r\n\t//\t\t\t\tstat.bindLong(index++, f.length());\r\n\t//\t\t\t\tstat.execute();\r\n\t//\t\t\t}\r\n\t//\t\t\tdb.setTransactionSuccessful();\r\n\t//\t\t} catch (BadHanyuPinyinOutputFormatCombination e) {\r\n\t//\t\t\te.printStackTrace();\r\n\t//\t\t} catch (Exception e) {\r\n\t//\t\t\te.printStackTrace();\r\n\t//\t\t} finally {\r\n\t//\t\t\tdb.endTransaction();\r\n\t//\t\t\ttry {\r\n\t//\t\t\t\tdb.close();\r\n\t//\t\t\t} catch (Exception e) {\r\n\t//\t\t\t}\r\n\t//\t\t}\r\n\t//\t}\r\n}\r\n"
  },
  {
    "path": "src/com/nmbb/oplayer/database/DbHelper.java",
    "content": "package com.nmbb.oplayer.database;\n\nimport java.sql.SQLException;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\nimport android.content.ContentValues;\n\nimport com.j256.ormlite.dao.Dao;\nimport com.j256.ormlite.stmt.UpdateBuilder;\nimport com.nmbb.oplayer.exception.Logger;\n\n@SuppressWarnings({ \"unchecked\", \"rawtypes\" })\npublic class DbHelper<T> {\n\n\t/** 新增一条记录 */\n\tpublic int create(T po) {\n\t\tSQLiteHelperOrm db = new SQLiteHelperOrm();\n\t\ttry {\n\t\t\tDao dao = db.getDao(po.getClass());\n\t\t\treturn dao.create(po);\n\t\t} catch (SQLException e) {\n\t\t\tLogger.e(e);\n\t\t} finally {\n\t\t\tif (db != null)\n\t\t\t\tdb.close();\n\t\t}\n\t\treturn -1;\n\t}\n\n\tpublic boolean exists(T po, Map<String, Object> where) {\n\t\tSQLiteHelperOrm db = new SQLiteHelperOrm();\n\t\ttry {\n\t\t\tDao dao = db.getDao(po.getClass());\n\t\t\tif (dao.queryForFieldValues(where).size() > 0) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} catch (SQLException e) {\n\t\t\tLogger.e(e);\n\t\t} finally {\n\t\t\tif (db != null)\n\t\t\t\tdb.close();\n\t\t}\n\t\treturn false;\n\t}\n\n\tpublic int createIfNotExists(T po, Map<String, Object> where) {\n\t\tSQLiteHelperOrm db = new SQLiteHelperOrm();\n\t\ttry {\n\t\t\tDao dao = db.getDao(po.getClass());\n\t\t\tif (dao.queryForFieldValues(where).size() < 1) {\n\t\t\t\treturn dao.create(po);\n\t\t\t}\n\t\t} catch (SQLException e) {\n\t\t\tLogger.e(e);\n\t\t} finally {\n\t\t\tif (db != null)\n\t\t\t\tdb.close();\n\t\t}\n\t\treturn -1;\n\t}\n\n\t/** 查询一条记录 */\n\tpublic List<T> queryForEq(Class<T> c, String fieldName, Object value) {\n\t\tSQLiteHelperOrm db = new SQLiteHelperOrm();\n\t\ttry {\n\t\t\tDao dao = db.getDao(c);\n\t\t\treturn dao.queryForEq(fieldName, value);\n\t\t} catch (SQLException e) {\n\t\t\tLogger.e(e);\n\t\t} finally {\n\t\t\tif (db != null)\n\t\t\t\tdb.close();\n\t\t}\n\t\treturn new ArrayList<T>();\n\t}\n\n\t/** 删除一条记录 */\n\tpublic int remove(T po) {\n\t\tSQLiteHelperOrm db = new SQLiteHelperOrm();\n\t\ttry {\n\t\t\tDao dao = db.getDao(po.getClass());\n\t\t\treturn dao.delete(po);\n\t\t} catch (SQLException e) {\n\t\t\tLogger.e(e);\n\t\t} finally {\n\t\t\tif (db != null)\n\t\t\t\tdb.close();\n\t\t}\n\t\treturn -1;\n\t}\n\n\t/**\n\t * 根据特定条件更新特定字段\n\t * \n\t * @param c\n\t * @param values\n\t * @param columnName where字段\n\t * @param value where值\n\t * @return\n\t */\n\tpublic int update(Class<T> c, ContentValues values, String columnName, Object value) {\n\t\tSQLiteHelperOrm db = new SQLiteHelperOrm();\n\t\ttry {\n\t\t\tDao dao = db.getDao(c);\n\t\t\tUpdateBuilder<T, Long> updateBuilder = dao.updateBuilder();\n\t\t\tupdateBuilder.where().eq(columnName, value);\n\t\t\tfor (String key : values.keySet()) {\n\t\t\t\tupdateBuilder.updateColumnValue(key, values.get(key));\n\t\t\t}\n\t\t\treturn updateBuilder.update();\n\t\t} catch (SQLException e) {\n\t\t\tLogger.e(e);\n\t\t} finally {\n\t\t\tif (db != null)\n\t\t\t\tdb.close();\n\t\t}\n\t\treturn -1;\n\t}\n\n\t/** 更新一条记录 */\n\tpublic int update(T po) {\n\t\tSQLiteHelperOrm db = new SQLiteHelperOrm();\n\t\ttry {\n\n\t\t\tDao dao = db.getDao(po.getClass());\n\t\t\treturn dao.update(po);\n\t\t} catch (SQLException e) {\n\t\t\tLogger.e(e);\n\t\t} finally {\n\t\t\tif (db != null)\n\t\t\t\tdb.close();\n\t\t}\n\t\treturn -1;\n\t}\n\n\t/** 查询所有记录 */\n\tpublic List<T> queryForAll(Class<T> c) {\n\t\tSQLiteHelperOrm db = new SQLiteHelperOrm();\n\t\ttry {\n\t\t\tDao dao = db.getDao(c);\n\t\t\treturn dao.queryForAll();\n\t\t} catch (SQLException e) {\n\t\t\tLogger.e(e);\n\t\t} finally {\n\t\t\tif (db != null)\n\t\t\t\tdb.close();\n\t\t}\n\t\treturn new ArrayList<T>();\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/database/SQLiteHelperOrm.java",
    "content": "package com.nmbb.oplayer.database;\r\n\r\nimport java.sql.SQLException;\r\n\r\nimport android.content.Context;\r\nimport android.database.sqlite.SQLiteDatabase;\r\n\r\nimport com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;\r\nimport com.j256.ormlite.support.ConnectionSource;\r\nimport com.j256.ormlite.table.TableUtils;\r\nimport com.nmbb.oplayer.OPlayerApplication;\r\nimport com.nmbb.oplayer.exception.Logger;\r\nimport com.nmbb.oplayer.po.POMedia;\r\n\r\npublic class SQLiteHelperOrm extends OrmLiteSqliteOpenHelper {\r\n\tprivate static final String DATABASE_NAME = \"oplayer.db\";\r\n\tprivate static final int DATABASE_VERSION = 1;\r\n\r\n\tpublic SQLiteHelperOrm(Context context) {\r\n\t\tsuper(context, DATABASE_NAME, null, DATABASE_VERSION);\r\n\t}\r\n\r\n\tpublic SQLiteHelperOrm() {\r\n\t\tsuper(OPlayerApplication.getContext(), DATABASE_NAME, null, DATABASE_VERSION);\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void onCreate(SQLiteDatabase db, ConnectionSource connectionSource) {\r\n\t\ttry {\r\n\t\t\tTableUtils.createTable(connectionSource, POMedia.class);\r\n\t\t} catch (SQLException e) {\r\n\t\t\tLogger.e(e);\r\n\t\t}\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int arg2, int arg3) {\r\n\t\ttry {\r\n\t\t\tTableUtils.dropTable(connectionSource, POMedia.class, true);\r\n\t\t\tonCreate(db, connectionSource);\r\n\t\t} catch (SQLException e) {\r\n\t\t\tLogger.e(e);\r\n\t\t}\r\n\t}\r\n}"
  },
  {
    "path": "src/com/nmbb/oplayer/exception/Logger.java",
    "content": "package com.nmbb.oplayer.exception;\r\n\r\nimport android.util.Log;\r\n\r\npublic class Logger {\r\n\r\n\tprivate static boolean isLog = true;\r\n\tprivate static final String TAG = \"OPlayer\";\r\n\r\n\tpublic static void setLog(boolean isLog) {\r\n\t\tLogger.isLog = isLog;\r\n\t}\r\n\r\n\tpublic static boolean getIsLog() {\r\n\t\treturn isLog;\r\n\t}\r\n\r\n\tpublic static void d(String tag, String msg) {\r\n\t\tif (isLog) {\r\n\t\t\tLog.d(tag, msg);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic static void d(String msg) {\r\n\t\tLog.d(TAG, msg);\r\n\t}\r\n\r\n\t/**\r\n\t * Send a {@link #DEBUG} log message and log the exception.\r\n\t * \r\n\t * @param tag Used to identify the source of a log message. It usually\r\n\t * identifies the class or activity where the log call occurs.\r\n\t * @param msg The message you would like logged.\r\n\t * @param tr An exception to log\r\n\t */\r\n\tpublic static void d(String tag, String msg, Throwable tr) {\r\n\t\tif (isLog) {\r\n\t\t\tLog.d(tag, msg, tr);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic static void e(Throwable tr) {\r\n\t\tif (isLog) {\r\n\t\t\tLog.e(TAG, \"\", tr);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic static void i(String msg) {\r\n\t\tif (isLog) {\r\n\t\t\tLog.i(TAG, msg);\r\n\t\t}\r\n\t}\r\n\t\r\n\tpublic static void i(String tag, String msg) {\r\n\t\tif (isLog) {\r\n\t\t\tLog.i(tag, msg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Send a {@link #INFO} log message and log the exception.\r\n\t * \r\n\t * @param tag Used to identify the source of a log message. It usually\r\n\t * identifies the class or activity where the log call occurs.\r\n\t * @param msg The message you would like logged.\r\n\t * @param tr An exception to log\r\n\t */\r\n\tpublic static void i(String tag, String msg, Throwable tr) {\r\n\t\tif (isLog) {\r\n\t\t\tLog.i(tag, msg, tr);\r\n\t\t}\r\n\r\n\t}\r\n\r\n\t/**\r\n\t * Send an {@link #ERROR} log message.\r\n\t * \r\n\t * @param tag Used to identify the source of a log message. It usually\r\n\t * identifies the class or activity where the log call occurs.\r\n\t * @param msg The message you would like logged.\r\n\t */\r\n\tpublic static void e(String tag, String msg) {\r\n\t\tif (isLog) {\r\n\t\t\tLog.e(tag, msg);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic static void e(String msg) {\r\n\t\tif (isLog) {\r\n\t\t\tLog.e(TAG, msg);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Send a {@link #ERROR} log message and log the exception.\r\n\t * \r\n\t * @param tag Used to identify the source of a log message. It usually\r\n\t * identifies the class or activity where the log call occurs.\r\n\t * @param msg The message you would like logged.\r\n\t * @param tr An exception to log\r\n\t */\r\n\tpublic static void e(String tag, String msg, Throwable tr) {\r\n\t\tif (isLog) {\r\n\t\t\tLog.e(tag, msg, tr);\r\n\t\t}\r\n\t}\r\n\t\r\n\tpublic static void e(String msg, Throwable tr) {\r\n\t\tif (isLog) {\r\n\t\t\tLog.e(TAG, msg, tr);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic static void systemErr(String msg) {\r\n\t\t// if (true) {\r\n\t\tif (isLog) {\r\n\t\t\tif (msg != null) {\r\n\t\t\t\tLog.e(TAG, msg);\r\n\t\t\t}\r\n\r\n\t\t}\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "src/com/nmbb/oplayer/po/OnlineVideo.java",
    "content": "package com.nmbb.oplayer.po;\n\nimport java.util.ArrayList;\n\npublic class OnlineVideo {\n\tpublic String id;\n\t/** 标题 */\n\tpublic String title;\n\tpublic String desc;\n\t/** LOGO */\n\tpublic int iconId = 0;\n\tpublic String icon_url;\n\t/** 播放地址 */\n\tpublic String url;\n\t/** 备用链接 */\n\tpublic ArrayList<String> backup_url;\n\t/** 是否目录 */\n\tpublic boolean is_category = false;\n\t/** 0视频 1电视 */\n\tpublic int category;\n\t/** */\n\tpublic int level = 1;\n\n\tpublic OnlineVideo() {\n\n\t}\n\n\tpublic OnlineVideo(String title, int iconId, int category) {\n\t\tthis.title = title;\n\t\tthis.iconId = iconId;\n\t\tthis.category = category;\n\t}\n\n\tpublic OnlineVideo(String title, int iconId, int category, String url) {\n\t\tthis.title = title;\n\t\tthis.iconId = iconId;\n\t\tthis.category = category;\n\t\tthis.url = url;\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/po/PFile.java",
    "content": "package com.nmbb.oplayer.po;\r\n\r\nimport android.content.Context;\r\nimport android.database.Cursor;\r\nimport android.graphics.Bitmap;\r\n\r\npublic final class PFile {\r\n\t\r\n\tpublic long _id;\r\n\t/** 视频标题 */\r\n\tpublic String title;\r\n\t/** 视频标题拼音 */\r\n\tpublic String title_pinyin;\r\n\t/** 视频路径 */\r\n\tpublic String path;\r\n\t/** 最后一次访问时间 */\r\n\tpublic long last_access_time;\r\n\t/** 视频时长 */\r\n\tpublic int duration;\r\n\t/** 视频播放进度 */\r\n\tpublic int position;\r\n\t/** 视频缩略图 */\r\n\tpublic String thumb;\r\n\t/** 文件大小 */\r\n\tpublic long file_size;\r\n\t/** 文件状态0 - 10 分别代表 下载 0-100% */\r\n\tpublic int status = -1;\r\n\t/** 文件临时大小 用于下载 */\r\n\tpublic long temp_file_size = -1L;\r\n\t/** 视频宽度 */\r\n\tpublic int width;\r\n\t/** 视频高度 */\r\n\tpublic int height;\r\n\r\n\tpublic PFile() {\r\n\r\n\t}\r\n\r\n\tpublic PFile(Cursor c) {\r\n\t\t//Video.Media._ID, Video.Media.TITLE, Video.Media.TITLE_KEY, Video.Media.SIZE, Video.Media.DURATION, Video.Media.DATA, Video.Media.WIDTH, Video.Media.HEIGHT\r\n\t\t_id = c.getLong(0);\r\n\t\ttitle = c.getString(1);\r\n\t\ttitle_pinyin = c.getString(2);\r\n\t\tfile_size = c.getLong(3);\r\n\t\tduration = c.getInt(4);\r\n\t\tpath = c.getString(5);\r\n\t\twidth = c.getInt(6);\r\n\t\theight = c.getInt(7);\r\n\t}\r\n\r\n\t/** 获取缩略图 */\r\n\tpublic Bitmap getThumb(Context ctx) {\r\n\t\treturn null;\r\n//\t\treturn Video.Thumbnails.getThumbnail(ctx.getApplicationContext(), ctx.getContentResolver(), _id, Video.Thumbnails.MICRO_KIND, null);\r\n\t}\r\n}\r\n"
  },
  {
    "path": "src/com/nmbb/oplayer/po/POMedia.java",
    "content": "package com.nmbb.oplayer.po;\n\nimport java.io.File;\n\nimport com.j256.ormlite.field.DatabaseField;\nimport com.j256.ormlite.table.DatabaseTable;\n\n/**\n * 视频PO类\n * \n * @author 农民伯伯\n * @see http://www.cnblogs.com/over140\n * \n */\n@DatabaseTable(tableName = \"media\")\npublic class POMedia {\n\t@DatabaseField(generatedId = true)\n\tpublic long _id;\n\t/** 视频标题 */\n\t@DatabaseField\n\tpublic String title;\n\t/** 视频标题拼音 */\n\t@DatabaseField\n\tpublic String title_key;\n\t/** 视频路径 */\n\t@DatabaseField\n\tpublic String path;\n\t/** 最后一次访问时间 */\n\t@DatabaseField\n\tpublic long last_access_time;\n\t/** 最后一次修改时间 */\n\t@DatabaseField\n\tpublic long last_modify_time;\n\t/** 视频时长 */\n\t@DatabaseField\n\tpublic int duration;\n\t/** 视频播放进度 */\n\t@DatabaseField\n\tpublic int position;\n\t/** 视频缩略图路径 */\n\t@DatabaseField\n\tpublic String thumb_path;\n\t/** 文件大小 */\n\t@DatabaseField\n\tpublic long file_size;\n\t/** 视频宽度 */\n\t@DatabaseField\n\tpublic int width;\n\t/** 视频高度 */\n\t@DatabaseField\n\tpublic int height;\n\t/** MIME类型 */\n\tpublic String mime_type;\n\t/** 0 本地视频 1 网络视频 */\n\tpublic int type = 0;\n\n\t/** 文件状态0 - 10 分别代表 下载 0-100% */\n\tpublic int status = -1;\n\t/** 文件临时大小 用于下载 */\n\tpublic long temp_file_size = -1L;\n\n\tpublic POMedia() {\n\n\t}\n\n\tpublic POMedia(File f) {\n\t\ttitle = f.getName();\n\t\tpath = f.getAbsolutePath();\n\t\tlast_modify_time = f.lastModified();\n\t\tfile_size = f.length();\n\t}\n\n\tpublic POMedia(String path, String mimeType) {\n\t\tthis(new File(path));\n\t\tthis.mime_type = mimeType;\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/preference/PreferenceUtils.java",
    "content": "package com.nmbb.oplayer.preference;\r\n\r\nimport android.content.Context;\r\nimport android.content.SharedPreferences;\r\nimport android.content.SharedPreferences.Editor;\r\nimport android.preference.PreferenceManager;\r\n\r\nimport com.nmbb.oplayer.OPlayerApplication;\r\n\r\npublic final class PreferenceUtils {\r\n\r\n\t/** 清空数据 */\r\n\tpublic static void reset(final Context ctx) {\r\n\t\tSharedPreferences.Editor edit = PreferenceManager.getDefaultSharedPreferences(ctx).edit();\r\n\t\tedit.clear();\r\n\t\tedit.commit();\r\n\t}\r\n\r\n\tpublic static String getString(String key, String defValue) {\r\n\t\treturn PreferenceManager.getDefaultSharedPreferences(OPlayerApplication.getContext()).getString(key, defValue);\r\n\t}\r\n\r\n\tpublic static long getLong(String key, long defValue) {\r\n\t\treturn PreferenceManager.getDefaultSharedPreferences(OPlayerApplication.getContext()).getLong(key, defValue);\r\n\t}\r\n\r\n\tpublic static float getFloat(String key, float defValue) {\r\n\t\treturn PreferenceManager.getDefaultSharedPreferences(OPlayerApplication.getContext()).getFloat(key, defValue);\r\n\t}\r\n\r\n\tpublic static void put(String key, String value) {\r\n\t\tputString(key, value);\r\n\t}\r\n\r\n\tpublic static void put(String key, int value) {\r\n\t\tputInt(key, value);\r\n\t}\r\n\r\n\tpublic static void put(String key, float value) {\r\n\t\tputFloat(key, value);\r\n\t}\r\n\r\n\tpublic static void put(String key, boolean value) {\r\n\t\tputBoolean(key, value);\r\n\t}\r\n\r\n\tpublic static void putFloat(String key, float value) {\r\n\t\tSharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(OPlayerApplication.getContext());\r\n\t\tEditor editor = sharedPreferences.edit();\r\n\t\teditor.putFloat(key, value);\r\n\t\teditor.commit();\r\n\t}\r\n\r\n\tpublic static SharedPreferences getPreferences() {\r\n\t\treturn PreferenceManager.getDefaultSharedPreferences(OPlayerApplication.getContext());\r\n\t}\r\n\r\n\tpublic static int getInt(String key, int defValue) {\r\n\t\treturn PreferenceManager.getDefaultSharedPreferences(OPlayerApplication.getContext()).getInt(key, defValue);\r\n\t}\r\n\r\n\tpublic static boolean getBoolean(String key, boolean defValue) {\r\n\t\treturn PreferenceManager.getDefaultSharedPreferences(OPlayerApplication.getContext()).getBoolean(key, defValue);\r\n\t}\r\n\r\n\tpublic static void putStringProcess(String key, String value) {\r\n\t\tSharedPreferences sharedPreferences = OPlayerApplication.getContext().getSharedPreferences(\"preference_mu\", Context.MODE_MULTI_PROCESS);\r\n\t\tEditor editor = sharedPreferences.edit();\r\n\t\teditor.putString(key, value);\r\n\t\teditor.commit();\r\n\t}\r\n\r\n\tpublic static String getStringProcess(String key, String defValue) {\r\n\t\tSharedPreferences sharedPreferences = OPlayerApplication.getContext().getSharedPreferences(\"preference_mu\", Context.MODE_MULTI_PROCESS);\r\n\t\treturn sharedPreferences.getString(key, defValue);\r\n\t}\r\n\r\n\tpublic static boolean hasString(String key) {\r\n\t\tSharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(OPlayerApplication.getContext());\r\n\t\treturn sharedPreferences.contains(key);\r\n\t}\r\n\r\n\tpublic static void putString(String key, String value) {\r\n\t\tSharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(OPlayerApplication.getContext());\r\n\t\tEditor editor = sharedPreferences.edit();\r\n\t\teditor.putString(key, value);\r\n\t\teditor.commit();\r\n\t}\r\n\r\n\tpublic static void putLong(String key, long value) {\r\n\t\tSharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(OPlayerApplication.getContext());\r\n\t\tEditor editor = sharedPreferences.edit();\r\n\t\teditor.putLong(key, value);\r\n\t\teditor.commit();\r\n\t}\r\n\r\n\tpublic static void putBoolean(String key, boolean value) {\r\n\t\tSharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(OPlayerApplication.getContext());\r\n\t\tEditor editor = sharedPreferences.edit();\r\n\t\teditor.putBoolean(key, value);\r\n\t\teditor.commit();\r\n\t}\r\n\r\n\tpublic static void putInt(String key, int value) {\r\n\t\tSharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(OPlayerApplication.getContext());\r\n\t\tEditor editor = sharedPreferences.edit();\r\n\t\teditor.putInt(key, value);\r\n\t\teditor.commit();\r\n\t}\r\n\r\n\tpublic static void remove(String... keys) {\r\n\t\tif (keys != null) {\r\n\t\t\tSharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(OPlayerApplication.getContext());\r\n\t\t\tEditor editor = sharedPreferences.edit();\r\n\t\t\tfor (String key : keys) {\r\n\t\t\t\teditor.remove(key);\r\n\t\t\t}\r\n\t\t\teditor.commit();\r\n\t\t}\r\n\t}\r\n}\r\n"
  },
  {
    "path": "src/com/nmbb/oplayer/receiver/MediaScannerReceiver.java",
    "content": "package com.nmbb.oplayer.receiver;\n\nimport android.content.BroadcastReceiver;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.os.Environment;\n\nimport com.nmbb.oplayer.service.MediaScannerService;\n\n/** 文件扫描 */\npublic class MediaScannerReceiver extends BroadcastReceiver {\n\n\tpublic static final String ACTION_MEDIA_SCANNER_SCAN_FILE = \"\";\n\tpublic static final String ACTION_MEDIA_SCANNER_SCAN_DIRECTORY = \"\";\n\n\t@Override\n\tpublic void onReceive(Context context, Intent intent) {\n\t\tString action = intent.getAction();\n\t\tUri uri = intent.getData();\n\n\t\tif (action.equals(Intent.ACTION_BOOT_COMPLETED)) {\n\t\t\t//扫描整个SD卡目录 \n\t\t\t//FIXME 处理多个SD卡的问题\n\t\t\t//\t\t\tEnvironment.getExternalStorageDirectory().getParentFile();\n\t\t\tscanDirectory(context, Environment.getExternalStorageDirectory().getAbsolutePath());\n\t\t} else if (uri.getScheme().equals(\"file\")) {\n\t\t\tString path = uri.getPath();\n\t\t\tif (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {\n\t\t\t\tscanDirectory(context, path);\n\t\t\t} else if (action.equals(ACTION_MEDIA_SCANNER_SCAN_FILE) && path != null) {\n\t\t\t\tscanFile(context, path);\n\t\t\t} else if (action.equals(ACTION_MEDIA_SCANNER_SCAN_DIRECTORY) && path != null) {\n\t\t\t\tscanDirectory(context, path);\n\t\t\t}\n\t\t}\n\t}\n\n\t/** 扫描文件夹 */\n\tprivate void scanDirectory(Context context, String volume) {\n\t\tBundle args = new Bundle();\n\t\targs.putString(MediaScannerService.EXTRA_DIRECTORY, volume);\n\t\tcontext.startService(new Intent(context, MediaScannerService.class).putExtras(args));\n\t}\n\n\tprivate void scanFile(Context context, String path) {\n\t\tBundle args = new Bundle();\n\t\targs.putString(MediaScannerService.EXTRA_FILE_PATH, path);\n\t\tcontext.startService(new Intent(context, MediaScannerService.class).putExtras(args));\n\t}\n\t//\tprivate static boolean isScanning = false;\n\t//\t//\tprivate boolean isScanningStarted = false;\n\t//\tprivate IReceiverNotify mNotify;\n\t//\n\t//\tpublic MediaScannerReceiver() {\n\t//\t}\n\t//\n\t//\tpublic MediaScannerReceiver(IReceiverNotify notify) {\n\t//\t\tmNotify = notify;\n\t//\t}\n\t//\n\t//\tpublic static boolean isScanning(Context ctx) {\n\t//\t\treturn isServiceRunning(ctx, \"io.vov.vitamio.MediaScannerService\");\n\t//\t}\n\t//\n\t//\t@Override\n\t//\tpublic void onReceive(Context context, Intent intent) {\n\t//\t\tfinal String action = intent.getAction();\n\t//\t\tLog.i(\"MediaScannerReceiver\", action);\n\t//\t}\n\t//\n\t//\t/** 服务是否正在运行 */\n\t//\tpublic static boolean isServiceRunning(Context ctx, String name) {\n\t//\t\tActivityManager manager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);\n\t//\t\tfor (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {\n\t//\t\t\tif (name.equals(service.service.getClassName()))\n\t//\t\t\t\treturn true;\n\t//\t\t}\n\t//\t\treturn false;\n\t//\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/service/FileDownloadService.java",
    "content": "package com.nmbb.oplayer.service;\r\n\r\nimport android.app.Service;\r\nimport android.content.Intent;\r\nimport android.os.IBinder;\r\n\r\npublic class FileDownloadService extends Service {\r\n\r\n\t@Override\r\n\tpublic IBinder onBind(Intent intent) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\t\r\n}\r\n"
  },
  {
    "path": "src/com/nmbb/oplayer/service/MediaScannerService.java",
    "content": "package com.nmbb.oplayer.service;\n\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport android.app.ActivityManager;\nimport android.app.ActivityManager.RunningServiceInfo;\nimport android.app.Service;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.os.Binder;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.IBinder;\nimport android.os.Message;\nimport com.nmbb.oplayer.OPlayerApplication;\nimport com.nmbb.oplayer.OPreference;\nimport com.nmbb.oplayer.database.DbHelper;\nimport com.nmbb.oplayer.exception.Logger;\nimport com.nmbb.oplayer.po.POMedia;\nimport com.nmbb.oplayer.util.FileUtils;\nimport com.nmbb.oplayer.util.PinyinUtils;\nimport com.nmbb.oplayer.util.StringUtils;\n\n/** 媒体扫描 */\npublic class MediaScannerService extends Service implements Runnable {\n\n\tprivate static final String SERVICE_NAME = \"com.nmbb.oplayer.service.MediaScannerService\";\n\t/** 扫描文件夹 */\n\tpublic static final String EXTRA_DIRECTORY = \"scan_directory\";\n\t/** 扫描文件 */\n\tpublic static final String EXTRA_FILE_PATH = \"scan_file\";\n\tpublic static final String EXTRA_MIME_TYPE = \"mimetype\";\n\n\tpublic static final int SCAN_STATUS_NORMAL = -1;\n\t/** 开始扫描 */\n\tpublic static final int SCAN_STATUS_START = 0;\n\t/** 正在扫描 扫描到一个视频文件 */\n\tpublic static final int SCAN_STATUS_RUNNING = 1;\n\t/** 扫描完成 */\n\tpublic static final int SCAN_STATUS_END = 2;\n\t/**  */\n\tprivate ArrayList<IMediaScannerObserver> observers = new ArrayList<IMediaScannerObserver>();\n\tprivate ConcurrentHashMap<String, String> mScanMap = new ConcurrentHashMap<String, String>();\n\n\t/** 当前状态 */\n\tprivate volatile int mServiceStatus = SCAN_STATUS_NORMAL;\n\tprivate DbHelper<POMedia> mDbHelper;\n\tprivate Map<String, Object> mDbWhere = new HashMap<String, Object>(2);\n\n\t@Override\n\tpublic void onCreate() {\n\t\tsuper.onCreate();\n\n\t\tmDbHelper = new DbHelper<POMedia>();\n\t}\n\n\t/** 是否正在运行 */\n\tpublic static boolean isRunning() {\n\t\tActivityManager manager = (ActivityManager) OPlayerApplication.getContext().getSystemService(Context.ACTIVITY_SERVICE);\n\t\tfor (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {\n\t\t\tif (SERVICE_NAME.equals(service.service.getClassName()))\n\t\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic int onStartCommand(Intent intent, int flags, int startId) {\n\t\tif (intent != null)\n\t\t\tparseIntent(intent);\n\n\t\treturn super.onStartCommand(intent, flags, startId);\n\t}\n\n\t/** 解析Intent */\n\tprivate void parseIntent(final Intent intent) {\n\t\tfinal Bundle arguments = intent.getExtras();\n\t\tif (arguments != null) {\n\t\t\tif (arguments.containsKey(EXTRA_DIRECTORY)) {\n\t\t\t\tString directory = arguments.getString(EXTRA_DIRECTORY);\n\t\t\t\tLogger.i(\"onStartCommand:\" + directory);\n\t\t\t\t//扫描文件夹\n\t\t\t\tif (!mScanMap.containsKey(directory))\n\t\t\t\t\tmScanMap.put(directory, \"\");\n\t\t\t} else if (arguments.containsKey(EXTRA_FILE_PATH)) {\n\t\t\t\t//单文件\n\t\t\t\tString filePath = arguments.getString(EXTRA_FILE_PATH);\n\t\t\t\tLogger.i(\"onStartCommand:\" + filePath);\n\t\t\t\tif (!StringUtils.isEmpty(filePath)) {\n\t\t\t\t\tif (!mScanMap.containsKey(filePath))\n\t\t\t\t\t\tmScanMap.put(filePath, arguments.getString(EXTRA_MIME_TYPE));\n\t\t\t\t\t//\t\t\t\t\tscanFile(filePath, arguments.getString(EXTRA_MIME_TYPE));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (mServiceStatus == SCAN_STATUS_NORMAL || mServiceStatus == SCAN_STATUS_END) {\n\t\t\tnew Thread(this).start();\n\t\t\t//scan();\n\t\t}\n\t}\n\n\t@Override\n\tpublic void run() {\n\t\tscan();\n\t}\n\n\t/** 扫描 */\n\tprivate void scan() {\n\t\t//开始扫描\n\t\tnotifyObservers(SCAN_STATUS_START, null);\n\n\t\twhile (mScanMap.keySet().size() > 0) {\n\n\t\t\tString path = \"\";\n\t\t\tfor (String key : mScanMap.keySet()) {\n\t\t\t\tpath = key;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (mScanMap.containsKey(path)) {\n\t\t\t\tString mimeType = mScanMap.get(path);\n\t\t\t\tif (\"\".equals(mimeType)) {\n\t\t\t\t\tscanDirectory(path);\n\t\t\t\t} else {\n\t\t\t\t\tscanFile(path, mimeType);\n\t\t\t\t}\n\n\t\t\t\t//扫描完成一个\n\t\t\t\tmScanMap.remove(path);\n\t\t\t}\n\n\t\t\t//任务之间歇息一秒\n\t\t\ttry {\n\t\t\t\tThread.sleep(1000);\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\tLogger.e(e);\n\t\t\t}\n\t\t}\n\n\t\t//全部扫描完成\n\t\tnotifyObservers(SCAN_STATUS_END, null);\n\n\t\t//第一次扫描\n\t\tOPreference pref = new OPreference(this);\n\t\tif (pref.getBoolean(OPlayerApplication.PREF_KEY_FIRST, true))\n\t\t\tpref.putBooleanAndCommit(OPlayerApplication.PREF_KEY_FIRST, false);\n\n\t\t//停止服务\n\t\tstopSelf();\n\t}\n\n\tprivate Handler mHandler = new Handler() {\n\t\t@Override\n\t\tpublic void handleMessage(Message msg) {\n\t\t\tsuper.handleMessage(msg);\n\t\t\tfor (IMediaScannerObserver s : observers) {\n\t\t\t\tif (s != null) {\n\t\t\t\t\ts.update(msg.what, (POMedia) msg.obj);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t/** 扫描文件 */\n\tprivate void scanFile(String path, String mimeType) {\n\t\tsave(new POMedia(path, mimeType));\n\t}\n\n\t/** 扫描文件夹 */\n\tprivate void scanDirectory(String path) {\n\t\teachAllMedias(new File(path));\n\t}\n\n\t/** 递归查找视频 */\n\tprivate void eachAllMedias(File f) {\n\t\tif (f != null && f.exists() && f.isDirectory()) {\n\t\t\tFile[] files = f.listFiles();\n\t\t\tif (files != null) {\n\t\t\t\tfor (File file : f.listFiles()) {\n\t\t\t\t\t//\t\t\t\t\tLogger.i(f.getAbsolutePath());\n\t\t\t\t\tif (file.isDirectory()) {\n\t\t\t\t\t\t//忽略.开头的文件夹\n\t\t\t\t\t\tif (!file.getAbsolutePath().startsWith(\".\"))\n\t\t\t\t\t\t\teachAllMedias(file);\n\t\t\t\t\t} else if (file.exists() && file.canRead() && FileUtils.isVideo(file)) {\n\t\t\t\t\t\tsave(new POMedia(file));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * 保存入库\n\t * \n\t * @throws FileNotFoundException\n\t */\n\tprivate void save(POMedia media) {\n\t\tmDbWhere.put(\"path\", media.path);\n\t\tmDbWhere.put(\"last_modify_time\", media.last_modify_time);\n\t\t//检测\n\t\tif (!mDbHelper.exists(media, mDbWhere)) {\n\t\t\ttry {\n\t\t\t\tif (media.title != null && media.title.length() > 0)\n\t\t\t\t\tmedia.title_key = PinyinUtils.chineneToSpell(media.title.charAt(0) + \"\");\n\t\t\t} catch (Exception ex) {\n\t\t\t\tLogger.e(ex);\n\t\t\t}\n\t\t\tmedia.last_access_time = System.currentTimeMillis();\n\n\t\t\t//提取缩略图\n\t\t\t//\t\t\textractThumbnail(media);\n\t\t\tmedia.mime_type = FileUtils.getMimeType(media.path);\n\n\t\t\t//入库\n\t\t\tmDbHelper.create(media);\n\n\t\t\t//扫描到一个\n\t\t\tnotifyObservers(SCAN_STATUS_RUNNING, media);\n\t\t}\n\t}\n\n\t/** 提取生成缩略图 */\n\tprivate void extractThumbnail(POMedia media) {\n//\t\tfinal Context ctx = OPlayerApplication.getContext();\n//\t\t//\t\tThumbnailUtils.\n//\t\tBitmap bitmap = ThumbnailUtils.createVideoThumbnail(media.path, Images.Thumbnails.MINI_KIND);\n//\t\ttry {\n//\t\t\tif (bitmap == null) {\n//\t\t\t\t//缩略图创建失败\n//\t\t\t\tbitmap = Bitmap.createBitmap(ThumbnailUtils.TARGET_SIZE_MINI_THUMBNAIL_WIDTH, ThumbnailUtils.TARGET_SIZE_MINI_THUMBNAIL_HEIGHT, Bitmap.Config.RGB_565);\n//\t\t\t}\n//\n//\t\t\tmedia.width = bitmap.getWidth();\n//\t\t\tmedia.height = bitmap.getHeight();\n//\n//\t\t\t//缩略图\n//\t\t\tbitmap = ThumbnailUtils.extractThumbnail(bitmap, ConvertUtils.dipToPX(ctx, ThumbnailUtils.TARGET_SIZE_MICRO_THUMBNAIL_WIDTH), ConvertUtils.dipToPX(ctx, ThumbnailUtils.TARGET_SIZE_MICRO_THUMBNAIL_HEIGHT), ThumbnailUtils.OPTIONS_RECYCLE_INPUT);\n//\t\t\tif (bitmap != null) {\n//\t\t\t\t//将缩略图存到视频当前路径\n//\t\t\t\tFile thum = new File(OPlayerApplication.OPLAYER_VIDEO_THUMB, UUID.randomUUID().toString());\n//\t\t\t\tmedia.thumb_path = thum.getAbsolutePath();\n//\t\t\t\t//thum.createNewFile();\n//\t\t\t\tFileOutputStream iStream = new FileOutputStream(thum);\n//\t\t\t\tbitmap.compress(Bitmap.CompressFormat.JPEG, 85, iStream);\n//\t\t\t\tiStream.close();\n//\t\t\t}\n//\n//\t\t\t//入库\n//\n//\t\t} catch (Exception ex) {\n//\t\t\tLogger.e(ex);\n//\t\t} finally {\n//\t\t\tif (bitmap != null)\n//\t\t\t\tbitmap.recycle();\n//\n//\t\t}\n\t}\n\n\t// ~~~ 状态改变 \n\n\t/** 通知状态改变 */\n\tprivate void notifyObservers(int flag, POMedia media) {\n\t\tmHandler.sendMessage(mHandler.obtainMessage(flag, media));\n\t}\n\n\t/** 增加观察者 */\n\tpublic void addObserver(IMediaScannerObserver s) {\n\t\tsynchronized (this) {\n\t\t\tif (!observers.contains(s)) {\n\t\t\t\tobservers.add(s);\n\t\t\t}\n\t\t}\n\t}\n\n\t/** 删除观察者 */\n\tpublic synchronized void deleteObserver(IMediaScannerObserver s) {\n\t\tobservers.remove(s);\n\t}\n\n\t/** 删除所有观察者 */\n\tpublic synchronized void deleteObservers() {\n\t\tobservers.clear();\n\t}\n\n\tpublic interface IMediaScannerObserver {\n\t\t/**\n\t\t * \n\t\t * @param flag 0 开始扫描 1 正在扫描 2 扫描完成\n\t\t * @param file 扫描到的视频文件\n\t\t */\n\t\tpublic void update(int flag, POMedia media);\n\t}\n\n\t// ~~~ Binder \n\n\tprivate final MediaScannerServiceBinder mBinder = new MediaScannerServiceBinder();\n\n\tpublic class MediaScannerServiceBinder extends Binder {\n\t\tpublic MediaScannerService getService() {\n\t\t\treturn MediaScannerService.this;\n\t\t}\n\t}\n\n\t@Override\n\tpublic IBinder onBind(Intent intent) {\n\t\treturn mBinder;\n\t}\n\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/FragmentBase.java",
    "content": "package com.nmbb.oplayer.ui;\r\n\r\nimport com.nmbb.oplayer.R;\r\n\r\nimport android.content.BroadcastReceiver;\r\nimport android.content.IntentFilter;\r\nimport android.database.ContentObserver;\r\nimport android.net.Uri;\r\nimport android.os.Bundle;\r\nimport android.support.v4.app.Fragment;\r\nimport android.view.LayoutInflater;\r\nimport android.view.View;\r\nimport android.view.ViewGroup;\r\nimport android.widget.ListView;\r\n\r\npublic class FragmentBase extends Fragment {\r\n\r\n\tprotected ListView mListView;\r\n\tprotected View mLoadingLayout;\r\n\tprotected MainActivity mParent;\r\n\r\n\t@Override\r\n\tpublic void onCreate(Bundle savedInstanceState) {\r\n\t\tsuper.onCreate(savedInstanceState);\r\n\t\tmParent = (MainActivity) getActivity();\r\n\t}\r\n\r\n\t@Override\r\n\tpublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\r\n\t\tView v = inflater.inflate(R.layout.fragment_file, container, false);\r\n\t\tmListView = (ListView) v.findViewById(android.R.id.list);\r\n\t\tmLoadingLayout = v.findViewById(R.id.loading);\r\n\t\treturn v;\r\n\t}\r\n\r\n\tpublic boolean onBackPressed() {\r\n\t\treturn false;\r\n\t}\r\n\r\n\tpublic void registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {\r\n\t\tif (mParent != null)\r\n\t\t\tmParent.registerReceiver(receiver, filter);\r\n\t}\r\n\r\n\tpublic void unregisterReceiver(BroadcastReceiver receiver) {\r\n\t\tif (mParent != null)\r\n\t\t\tmParent.unregisterReceiver(receiver);\r\n\t}\r\n\r\n\tpublic void registerContentObserver(Uri uri, boolean notifyForDescendents, ContentObserver observer) {\r\n\t\tif (mParent != null)\r\n\t\t\tmParent.getContentResolver().registerContentObserver(uri, notifyForDescendents, observer);\r\n\t}\r\n\r\n\tpublic void unregisterContentObserver(ContentObserver observer) {\r\n\t\tif (mParent != null)\r\n\t\t\tmParent.getContentResolver().unregisterContentObserver(observer);\r\n\t}\r\n}\r\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/FragmentFileOld.java",
    "content": "package com.nmbb.oplayer.ui;\r\n\r\nimport java.io.File;\r\nimport java.util.ArrayList;\r\nimport java.util.HashMap;\r\nimport java.util.List;\r\n\r\nimport android.app.AlertDialog;\r\nimport android.content.ComponentName;\r\nimport android.content.Context;\r\nimport android.content.DialogInterface;\r\nimport android.content.Intent;\r\nimport android.content.ServiceConnection;\r\nimport android.net.Uri;\r\nimport android.os.AsyncTask;\r\nimport android.os.Bundle;\r\nimport android.os.Handler;\r\nimport android.os.IBinder;\r\nimport android.os.Message;\r\nimport android.view.ContextMenu;\r\nimport android.view.ContextMenu.ContextMenuInfo;\r\nimport android.view.LayoutInflater;\r\nimport android.view.MenuItem;\r\nimport android.view.MotionEvent;\r\nimport android.view.View;\r\nimport android.view.View.OnTouchListener;\r\nimport android.view.ViewGroup;\r\nimport android.widget.AdapterView;\r\nimport android.widget.AdapterView.OnItemClickListener;\r\nimport android.widget.EditText;\r\nimport android.widget.ImageView;\r\nimport android.widget.ListView;\r\nimport android.widget.TextView;\r\nimport android.widget.Toast;\r\n\r\nimport com.nmbb.oplayer.R;\r\nimport com.nmbb.oplayer.business.FileBusiness;\r\nimport com.nmbb.oplayer.database.DbHelper;\r\nimport com.nmbb.oplayer.po.POMedia;\r\nimport com.nmbb.oplayer.service.MediaScannerService;\r\nimport com.nmbb.oplayer.service.MediaScannerService.IMediaScannerObserver;\r\nimport com.nmbb.oplayer.service.MediaScannerService.MediaScannerServiceBinder;\r\nimport com.nmbb.oplayer.ui.base.ArrayAdapter;\r\nimport com.nmbb.oplayer.ui.helper.FileDownloadHelper;\r\nimport com.nmbb.oplayer.ui.player.VideoActivity;\r\nimport com.nmbb.oplayer.util.FileUtils;\r\n\r\npublic class FragmentFileOld extends FragmentBase implements\r\n\t\tOnItemClickListener, IMediaScannerObserver {\r\n\r\n\tprivate FileAdapter mAdapter;\r\n\tprivate FileAdapter mDownloadAdapter;\r\n\tprivate TextView first_letter_overlay;\r\n\tprivate ImageView alphabet_scroller;\r\n\t/** 临时列表 */\r\n\tprivate ListView mTempListView;\r\n\tprivate MainActivity mParent;\r\n\tprivate TextView mSDAvailable;\r\n\t/** 左下角进度显示 */\r\n\tprivate View mProgress;\r\n\r\n\tprivate MediaScannerService mMediaScannerService;\r\n\r\n\tprivate ServiceConnection mMediaScannerServiceConnection = new ServiceConnection() {\r\n\r\n\t\t@Override\r\n\t\tpublic void onServiceDisconnected(ComponentName name) {\r\n\t\t\tmMediaScannerService = null;\r\n\t\t}\r\n\r\n\t\t@Override\r\n\t\tpublic void onServiceConnected(ComponentName name, IBinder service) {\r\n\t\t\tmMediaScannerService = ((MediaScannerServiceBinder) service)\r\n\t\t\t\t\t.getService();\r\n\t\t\tmMediaScannerService.addObserver(FragmentFileOld.this);\r\n\t\t\t// Toast.makeText(ComponentServiceActivity.this, \"Service绑定成功!\",\r\n\t\t\t// Toast.LENGTH_SHORT).show();\r\n\t\t}\r\n\t};\r\n\r\n\t@Override\r\n\tpublic View onCreateView(LayoutInflater inflater, ViewGroup container,\r\n\t\t\tBundle savedInstanceState) {\r\n\t\tView v = super.onCreateView(inflater, container, savedInstanceState);\r\n\t\t// ~~~~~~~~~ 绑定控件\r\n\t\tfirst_letter_overlay = (TextView) v\r\n\t\t\t\t.findViewById(R.id.first_letter_overlay);\r\n\t\talphabet_scroller = (ImageView) v.findViewById(R.id.alphabet_scroller);\r\n\t\tmTempListView = (ListView) v.findViewById(R.id.templist);\r\n\t\tmSDAvailable = (TextView) v.findViewById(R.id.sd_block);\r\n\t\tmProgress = v.findViewById(android.R.id.progress);\r\n\r\n\t\t// ~~~~~~~~~ 绑定事件\r\n\t\talphabet_scroller.setClickable(true);\r\n\t\talphabet_scroller.setOnTouchListener(asOnTouch);\r\n\t\tmListView.setOnItemClickListener(this);\r\n\t\tmTempListView.setOnItemClickListener(this);\r\n\t\tmListView.setOnCreateContextMenuListener(OnListViewMenu);\r\n\t\tmTempListView.setOnCreateContextMenuListener(OnTempListViewMenu);\r\n\r\n\t\t// ~~~~~~~~~ 加载数据\r\n\t\tmParent = (MainActivity) getActivity();\r\n\t\t// if (new SQLiteHelper(getActivity()).isEmpty())\r\n\t\t// new ScanVideoTask().execute();\r\n\t\t// else\r\n\t\tnew DataTask().execute();\r\n\r\n\t\tgetActivity().bindService(\r\n\t\t\t\tnew Intent(getActivity().getApplicationContext(),\r\n\t\t\t\t\t\tMediaScannerService.class),\r\n\t\t\t\tmMediaScannerServiceConnection, Context.BIND_AUTO_CREATE);\r\n\t\treturn v;\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void onStart() {\r\n\t\tsuper.onStart();\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void onDestroy() {\r\n\t\tgetActivity().unbindService(mMediaScannerServiceConnection);\r\n\t\tsuper.onDestroy();\r\n\t}\r\n\r\n\t/**\r\n\t * \r\n\t * @param flag\r\n\t *            0 开始扫描 1 正在扫描 2 扫描完成\r\n\t * @param file\r\n\t *            扫描到的视频文件\r\n\t */\r\n\t@Override\r\n\tpublic void update(int flag, POMedia media) {\r\n\t\t// Logger.i(flag + \" \" + media.path);\r\n\t\tswitch (flag) {\r\n\t\tcase MediaScannerService.SCAN_STATUS_START:\r\n\r\n\t\t\tbreak;\r\n\t\tcase MediaScannerService.SCAN_STATUS_END:// 扫描完成\r\n\t\t\tif (mProgress != null)\r\n\t\t\t\tmProgress.setVisibility(View.GONE);\r\n\t\t\tnew DataTask().execute();\r\n\t\t\tbreak;\r\n\t\tcase MediaScannerService.SCAN_STATUS_RUNNING:// 扫到一个文件\r\n\t\t\tif (mAdapter != null && media != null) {\r\n\t\t\t\tmAdapter.add(media);\r\n\t\t\t\tmAdapter.notifyDataSetChanged();\r\n\t\t\t}\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void onResume() {\r\n\t\tsuper.onResume();\r\n\r\n\t\t// SD卡剩余数量\r\n\t\tmSDAvailable.setText(FileUtils.showFileAvailable());\r\n\r\n\t\tif (MediaScannerService.isRunning())\r\n\t\t\tmProgress.setVisibility(View.VISIBLE);\r\n\t\telse\r\n\t\t\tmProgress.setVisibility(View.GONE);\r\n\t}\r\n\r\n\tListView.OnCreateContextMenuListener OnListViewMenu = new ListView.OnCreateContextMenuListener() {\r\n\t\t@Override\r\n\t\tpublic void onCreateContextMenu(ContextMenu menu, View v,\r\n\t\t\t\tContextMenuInfo menuInfo) {\r\n\t\t\tmenu.setHeaderTitle(R.string.file_oper);\r\n\t\t\tmenu.add(0, 0, 0, R.string.file_rename);\r\n\t\t\tmenu.add(0, 1, 0, R.string.file_delete);\r\n\t\t}\r\n\t};\r\n\r\n\tListView.OnCreateContextMenuListener OnTempListViewMenu = new ListView.OnCreateContextMenuListener() {\r\n\r\n\t\t@Override\r\n\t\tpublic void onCreateContextMenu(ContextMenu menu, View v,\r\n\t\t\t\tContextMenuInfo menuInfo) {\r\n\t\t\tmenu.setHeaderTitle(R.string.file_oper);\r\n\t\t\tmenu.add(0, 2, 0, R.string.file_rename);\r\n\t\t\tmenu.add(0, 3, 0, R.string.file_delete);\r\n\t\t}\r\n\t};\r\n\r\n\t@Override\r\n\tpublic boolean onContextItemSelected(MenuItem item) {\r\n\t\tContextMenuInfo info = item.getMenuInfo();\r\n\t\tAdapterView.AdapterContextMenuInfo contextMenuInfo = (AdapterView.AdapterContextMenuInfo) info;\r\n\t\tint position = contextMenuInfo.position;\r\n\t\tswitch (item.getItemId()) {\r\n\t\tcase 0:\r\n\t\t\trenameFile(mAdapter, mAdapter.getItem(position), position);\r\n\t\t\tbreak;\r\n\t\tcase 1:\r\n\t\t\tdeleteFile(mAdapter, mAdapter.getItem(position), position);\r\n\t\t\tbreak;\r\n\t\tcase 2:\r\n\t\t\trenameFile(mDownloadAdapter, mDownloadAdapter.getItem(position),\r\n\t\t\t\t\tposition);\r\n\t\t\tbreak;\r\n\t\tcase 3:\r\n\t\t\tdeleteFile(mDownloadAdapter, mDownloadAdapter.getItem(position),\r\n\t\t\t\t\tposition);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\treturn super.onContextItemSelected(item);\r\n\t};\r\n\r\n\t/** 删除文件 */\r\n\tprivate void deleteFile(final FileAdapter adapter, final POMedia f,\r\n\t\t\tfinal int position) {\r\n\t\tnew AlertDialog.Builder(getActivity())\r\n\t\t\t\t.setIcon(android.R.drawable.ic_dialog_alert)\r\n\t\t\t\t.setTitle(R.string.file_delete)\r\n\t\t\t\t.setMessage(getString(R.string.file_delete_confirm, f.title))\r\n\t\t\t\t.setNegativeButton(android.R.string.yes,\r\n\t\t\t\t\t\tnew DialogInterface.OnClickListener() {\r\n\t\t\t\t\t\t\t@Override\r\n\t\t\t\t\t\t\tpublic void onClick(DialogInterface dialog,\r\n\t\t\t\t\t\t\t\t\tint which) {\r\n\t\t\t\t\t\t\t\ttry {\r\n\t\t\t\t\t\t\t\t\tFile file = new File(f.path);\r\n\t\t\t\t\t\t\t\t\tif (file.canRead() && file.exists())\r\n\t\t\t\t\t\t\t\t\t\tfile.delete();\r\n\r\n\t\t\t\t\t\t\t\t\t// FileBusiness.deleteFile(getActivity(),\r\n\t\t\t\t\t\t\t\t\t// f);\r\n\t\t\t\t\t\t\t\t\tnew DbHelper<POMedia>().remove(f);\r\n\t\t\t\t\t\t\t\t\tadapter.delete(position);\r\n\t\t\t\t\t\t\t\t} catch (Exception e) {\r\n\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t}).setPositiveButton(android.R.string.no, null).show();\r\n\t}\r\n\r\n\t/** 重命名文件 */\r\n\tprivate void renameFile(final FileAdapter adapter, final POMedia f,\r\n\t\t\tfinal int position) {\r\n\t\tfinal EditText et = new EditText(getActivity());\r\n\t\tet.setText(f.title);\r\n\t\tnew AlertDialog.Builder(getActivity())\r\n\t\t\t\t.setTitle(R.string.file_rename)\r\n\t\t\t\t.setIcon(android.R.drawable.ic_dialog_info)\r\n\t\t\t\t.setView(et)\r\n\t\t\t\t.setNegativeButton(android.R.string.yes,\r\n\t\t\t\t\t\tnew DialogInterface.OnClickListener() {\r\n\r\n\t\t\t\t\t\t\t@Override\r\n\t\t\t\t\t\t\tpublic void onClick(DialogInterface dialog,\r\n\t\t\t\t\t\t\t\t\tint which) {\r\n\t\t\t\t\t\t\t\tString name = et.getText().toString().trim();\r\n\t\t\t\t\t\t\t\tif (name == null || name.trim().equals(\"\")\r\n\t\t\t\t\t\t\t\t\t\t|| name.trim().equals(f.title))\r\n\t\t\t\t\t\t\t\t\treturn;\r\n\r\n\t\t\t\t\t\t\t\ttry {\r\n\t\t\t\t\t\t\t\t\tFile fromFile = new File(f.path);\r\n\t\t\t\t\t\t\t\t\tFile nf = new File(fromFile.getParent(),\r\n\t\t\t\t\t\t\t\t\t\t\tname.trim());\r\n\t\t\t\t\t\t\t\t\tif (nf.exists()) {\r\n\t\t\t\t\t\t\t\t\t\tToast.makeText(getActivity(),\r\n\t\t\t\t\t\t\t\t\t\t\t\tR.string.file_rename_exists,\r\n\t\t\t\t\t\t\t\t\t\t\t\tToast.LENGTH_LONG).show();\r\n\t\t\t\t\t\t\t\t\t} else if (fromFile.renameTo(nf)) {\r\n\t\t\t\t\t\t\t\t\t\tf.title = name;\r\n\t\t\t\t\t\t\t\t\t\tf.path = nf.getPath();\r\n\t\t\t\t\t\t\t\t\t\t// FileBusiness.renameFile(getActivity(),\r\n\t\t\t\t\t\t\t\t\t\t// f);\r\n\r\n\t\t\t\t\t\t\t\t\t\tnew DbHelper<POMedia>().update(f);\r\n\t\t\t\t\t\t\t\t\t\tadapter.notifyDataSetChanged();\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t} catch (SecurityException se) {\r\n\t\t\t\t\t\t\t\t\tToast.makeText(getActivity(),\r\n\t\t\t\t\t\t\t\t\t\t\tR.string.file_rename_failed,\r\n\t\t\t\t\t\t\t\t\t\t\tToast.LENGTH_LONG).show();\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t}).setPositiveButton(android.R.string.no, null).show();\r\n\t}\r\n\r\n\tpublic Handler mDownloadHandler = new Handler() {\r\n\t\t@Override\r\n\t\tpublic void handleMessage(Message msg) {\r\n\t\t\tPOMedia p;\r\n\t\t\tString url = msg.obj.toString();\r\n\t\t\tswitch (msg.what) {\r\n\t\t\tcase FileDownloadHelper.MESSAGE_START:// 开始下载\r\n\t\t\t\tp = new POMedia();\r\n\t\t\t\tp.path = mParent.mFileDownload.mDownloadUrls.get(url);\r\n\t\t\t\tp.title = new File(p.path).getName();\r\n\t\t\t\tp.status = 0;\r\n\t\t\t\tp.file_size = 0;\r\n\t\t\t\tif (mDownloadAdapter == null) {\r\n\t\t\t\t\tmDownloadAdapter = new FileAdapter(getActivity(),\r\n\t\t\t\t\t\t\tnew ArrayList<POMedia>());\r\n\t\t\t\t\tmDownloadAdapter.add(p, url);\r\n\t\t\t\t\tmTempListView.setAdapter(mDownloadAdapter);\r\n\t\t\t\t\tmTempListView.setVisibility(View.VISIBLE);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tmDownloadAdapter.add(p, url);\r\n\t\t\t\t\tmDownloadAdapter.notifyDataSetChanged();\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase FileDownloadHelper.MESSAGE_PROGRESS:// 正在下载\r\n\t\t\t\tp = mDownloadAdapter.getItem(url);\r\n\t\t\t\tp.temp_file_size = msg.arg1;\r\n\t\t\t\tp.file_size = msg.arg2;\r\n\t\t\t\tint status = (int) ((msg.arg1 * 1.0 / msg.arg2) * 10);\r\n\t\t\t\tif (status > 10)\r\n\t\t\t\t\tstatus = 10;\r\n\t\t\t\tp.status = status;\r\n\t\t\t\tmDownloadAdapter.notifyDataSetChanged();\r\n\t\t\t\tbreak;\r\n\t\t\tcase FileDownloadHelper.MESSAGE_STOP:// 下载结束\r\n\t\t\t\tp = mDownloadAdapter.getItem(url);\r\n\t\t\t\tnew DbHelper<POMedia>().create(p);\r\n\t\t\t\t// FileBusiness.insertFile(getActivity(), p);\r\n\t\t\t\tbreak;\r\n\t\t\tcase FileDownloadHelper.MESSAGE_ERROR:\r\n\t\t\t\tToast.makeText(getActivity(), url, Toast.LENGTH_LONG).show();\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tsuper.handleMessage(msg);\r\n\t\t}\r\n\t};\r\n\r\n\t/** 单击启动播放 */\r\n\t@Override\r\n\tpublic void onItemClick(AdapterView<?> parent, View view, int position,\r\n\t\t\tlong id) {\r\n\t\tfinal POMedia f = parent == mListView ? mAdapter.getItem(position)\r\n\t\t\t\t: mDownloadAdapter.getItem(position);\r\n\t\tIntent intent = new Intent(getActivity(), VideoActivity.class);\r\n\t\tintent.setData(Uri.parse(f.path));\r\n\t\t// intent.putExtra(\"path\", f.path);\r\n\t\tintent.putExtra(\"displayName\", f.title);\r\n\t\tstartActivity(intent);\r\n\t}\r\n\r\n\tprivate class DataTask extends AsyncTask<Void, Void, List<POMedia>> {\r\n\r\n\t\t@Override\r\n\t\tprotected void onPreExecute() {\r\n\t\t\tsuper.onPreExecute();\r\n\t\t\tmLoadingLayout.setVisibility(View.VISIBLE);\r\n\t\t\tmListView.setVisibility(View.GONE);\r\n\t\t}\r\n\r\n\t\t@Override\r\n\t\tprotected List<POMedia> doInBackground(Void... params) {\r\n\t\t\treturn FileBusiness.getAllSortFiles();\r\n\t\t}\r\n\r\n\t\t@Override\r\n\t\tprotected void onPostExecute(List<POMedia> result) {\r\n\t\t\tsuper.onPostExecute(result);\r\n\r\n\t\t\tmAdapter = new FileAdapter(getActivity(), result);\r\n\t\t\tmListView.setAdapter(mAdapter);\r\n\r\n\t\t\tmLoadingLayout.setVisibility(View.GONE);\r\n\t\t\tmListView.setVisibility(View.VISIBLE);\r\n\t\t}\r\n\t}\r\n\r\n\tprivate class FileAdapter extends ArrayAdapter<POMedia> {\r\n\r\n\t\tprivate HashMap<String, POMedia> maps = new HashMap<String, POMedia>();\r\n\r\n\t\tpublic FileAdapter(Context ctx, List<POMedia> l) {\r\n\t\t\tsuper(ctx, l);\r\n\t\t\tmaps.clear();\r\n\t\t}\r\n\r\n\t\t@Override\r\n\t\tpublic View getView(int position, View convertView, ViewGroup parent) {\r\n\t\t\tfinal POMedia f = getItem(position);\r\n\t\t\tif (convertView == null) {\r\n\t\t\t\tfinal LayoutInflater mInflater = getActivity()\r\n\t\t\t\t\t\t.getLayoutInflater();\r\n\t\t\t\tconvertView = mInflater.inflate(R.layout.fragment_file_item,\r\n\t\t\t\t\t\tnull);\r\n\t\t\t}\r\n\t\t\t((TextView) convertView.findViewById(R.id.title)).setText(f.title);\r\n\r\n\t\t\t// 显示文件大小\r\n\t\t\tString file_size;\r\n\t\t\tif (f.temp_file_size > 0) {\r\n\t\t\t\tfile_size = FileUtils.showFileSize(f.temp_file_size) + \" / \"\r\n\t\t\t\t\t\t+ FileUtils.showFileSize(f.file_size);\r\n\t\t\t} else {\r\n\t\t\t\tfile_size = FileUtils.showFileSize(f.file_size);\r\n\t\t\t}\r\n\t\t\t((TextView) convertView.findViewById(R.id.file_size))\r\n\t\t\t\t\t.setText(file_size);\r\n\r\n\t\t\t// 显示进度表\r\n\t\t\tfinal ImageView status = (ImageView) convertView\r\n\t\t\t\t\t.findViewById(R.id.status);\r\n\t\t\tif (f.status > -1) {\r\n\t\t\t\tint resStauts = getStatusImage(f.status);\r\n\t\t\t\tif (resStauts > 0) {\r\n\t\t\t\t\tif (status.getVisibility() != View.VISIBLE)\r\n\t\t\t\t\t\tstatus.setVisibility(View.VISIBLE);\r\n\t\t\t\t\tstatus.setImageResource(resStauts);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (status.getVisibility() != View.GONE)\r\n\t\t\t\t\tstatus.setVisibility(View.GONE);\r\n\t\t\t}\r\n\t\t\treturn convertView;\r\n\t\t}\r\n\r\n\t\tpublic void add(POMedia item, String url) {\r\n\t\t\tsuper.add(item);\r\n\t\t\tif (!maps.containsKey(url))\r\n\t\t\t\tmaps.put(url, item);\r\n\t\t}\r\n\r\n\t\tpublic void delete(int position) {\r\n\t\t\tsynchronized (mLock) {\r\n\t\t\t\tmObjects.remove(position);\r\n\t\t\t}\r\n\t\t\tnotifyDataSetChanged();\r\n\t\t}\r\n\r\n\t\tpublic POMedia getItem(String url) {\r\n\t\t\treturn maps.get(url);\r\n\t\t}\r\n\t}\r\n\r\n\tprivate int getStatusImage(int status) {\r\n\t\tint resStauts = -1;\r\n\t\tswitch (status) {\r\n\t\tcase 0:\r\n\t\t\tresStauts = R.drawable.down_btn_0;\r\n\t\t\tbreak;\r\n\t\tcase 1:\r\n\t\t\tresStauts = R.drawable.down_btn_1;\r\n\t\t\tbreak;\r\n\t\tcase 2:\r\n\t\t\tresStauts = R.drawable.down_btn_2;\r\n\t\t\tbreak;\r\n\t\tcase 3:\r\n\t\t\tresStauts = R.drawable.down_btn_3;\r\n\t\t\tbreak;\r\n\t\tcase 4:\r\n\t\t\tresStauts = R.drawable.down_btn_4;\r\n\t\t\tbreak;\r\n\t\tcase 5:\r\n\t\t\tresStauts = R.drawable.down_btn_5;\r\n\t\t\tbreak;\r\n\t\tcase 6:\r\n\t\t\tresStauts = R.drawable.down_btn_6;\r\n\t\t\tbreak;\r\n\t\tcase 7:\r\n\t\t\tresStauts = R.drawable.down_btn_7;\r\n\t\t\tbreak;\r\n\t\tcase 8:\r\n\t\t\tresStauts = R.drawable.down_btn_8;\r\n\t\t\tbreak;\r\n\t\tcase 9:\r\n\t\t\tresStauts = R.drawable.down_btn_9;\r\n\t\t\tbreak;\r\n\t\tcase 10:\r\n\t\t\tresStauts = R.drawable.down_btn_10;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\treturn resStauts;\r\n\t}\r\n\r\n\t/**\r\n\t * A-Z\r\n\t */\r\n\tprivate OnTouchListener asOnTouch = new OnTouchListener() {\r\n\r\n\t\t@Override\r\n\t\tpublic boolean onTouch(View v, MotionEvent event) {\r\n\t\t\tswitch (event.getAction()) {\r\n\t\t\tcase MotionEvent.ACTION_DOWN:// 0\r\n\t\t\t\talphabet_scroller.setPressed(true);\r\n\t\t\t\tfirst_letter_overlay.setVisibility(View.VISIBLE);\r\n\t\t\t\tmathScrollerPosition(event.getY());\r\n\t\t\t\tbreak;\r\n\t\t\tcase MotionEvent.ACTION_UP:// 1\r\n\t\t\t\talphabet_scroller.setPressed(false);\r\n\t\t\t\tfirst_letter_overlay.setVisibility(View.GONE);\r\n\t\t\t\tbreak;\r\n\t\t\tcase MotionEvent.ACTION_MOVE:\r\n\t\t\t\tmathScrollerPosition(event.getY());\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\treturn false;\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * 显示字符\r\n\t * \r\n\t * @param y\r\n\t */\r\n\tprivate void mathScrollerPosition(float y) {\r\n\t\tint height = alphabet_scroller.getHeight();\r\n\t\tfloat charHeight = height / 28.0f;\r\n\t\tchar c = 'A';\r\n\t\tif (y < 0)\r\n\t\t\ty = 0;\r\n\t\telse if (y > height)\r\n\t\t\ty = height;\r\n\r\n\t\tint index = (int) (y / charHeight) - 1;\r\n\t\tif (index < 0)\r\n\t\t\tindex = 0;\r\n\t\telse if (index > 25)\r\n\t\t\tindex = 25;\r\n\r\n\t\tString key = String.valueOf((char) (c + index));\r\n\t\tfirst_letter_overlay.setText(key);\r\n\r\n\t\tint position = 0;\r\n\t\tif (index == 0)\r\n\t\t\tmListView.setSelection(0);\r\n\t\telse if (index == 25)\r\n\t\t\tmListView.setSelection(mAdapter.getCount() - 1);\r\n\t\telse {\r\n\t\t\tif (mAdapter != null && mAdapter.getAll() != null) {\r\n\t\t\t\tfor (POMedia item : mAdapter.getAll()) {\r\n\t\t\t\t\tif (item.title_key.startsWith(key)) {\r\n\t\t\t\t\t\tmListView.setSelection(position);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tposition++;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// ~~~~~~~~~~~~~~ 后续弃用，直接使用Vitamio提供的\r\n\r\n\t// /** 扫描SD卡 */\r\n\t// private class ScanVideoTask extends AsyncTask<Void, File,\r\n\t// ArrayList<PFile>> {\r\n\t// private ProgressDialog pd;\r\n\t// private ArrayList<File> files = new ArrayList<File>();\r\n\t//\r\n\t// @Override\r\n\t// protected void onPreExecute() {\r\n\t// super.onPreExecute();\r\n\t// pd = new ProgressDialog(getActivity());\r\n\t// pd.setMessage(\"正在扫描视频文件...\");\r\n\t// pd.setCanceledOnTouchOutside(false);\r\n\t// pd.setCancelable(false);\r\n\t// pd.show();\r\n\t// }\r\n\t//\r\n\t// @Override\r\n\t// protected ArrayList<PFile> doInBackground(Void... params) {\r\n\t// // ~~~ 遍历文件夹\r\n\t// eachAllMedias(Environment.getExternalStorageDirectory());\r\n\t//\r\n\t// // ~~~ 提取缩略图、视频尺寸等。\r\n\t// FileBusiness.batchBuildThumbnail(getActivity(), files);\r\n\t//\r\n\t// // ~~~ 入库\r\n\t// FileBusiness.batchInsertFiles(getActivity(), files);\r\n\t//\r\n\t// // ~~~ 查询数据\r\n\t// return FileBusiness.getAllSortFiles(getActivity());\r\n\t// }\r\n\t//\r\n\t// @Override\r\n\t// protected void onProgressUpdate(final File... values) {\r\n\t// pd.setMessage(values[0].getName());\r\n\t// }\r\n\t//\r\n\t// /** 遍历所有文件夹，查找出视频文件 */\r\n\t// public void eachAllMedias(File f) {\r\n\t// if (f != null && f.exists() && f.isDirectory()) {\r\n\t// File[] files = f.listFiles();\r\n\t// if (files != null) {\r\n\t// for (File file : f.listFiles()) {\r\n\t// if (file.isDirectory()) {\r\n\t// eachAllMedias(file);\r\n\t// } else if (file.exists() && file.canRead() && FileUtils.isVideo(file)) {\r\n\t// this.files.add(file);\r\n\t// }\r\n\t// publishProgress(file);\r\n\t// }\r\n\t// }\r\n\t// }\r\n\t// }\r\n\t//\r\n\t// @Override\r\n\t// protected void onPostExecute(ArrayList<PFile> result) {\r\n\t// super.onPostExecute(result);\r\n\t// mAdapter = new FileAdapter(getActivity(), result);\r\n\t// mListView.setAdapter(mAdapter);\r\n\t// pd.dismiss();\r\n\t// }\r\n\t// }\r\n}\r\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/FragmentOnline.java",
    "content": "package com.nmbb.oplayer.ui;\r\n\r\nimport java.lang.reflect.InvocationTargetException;\r\nimport java.lang.reflect.Method;\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\nimport com.nmbb.oplayer.R;\r\nimport com.nmbb.oplayer.po.OnlineVideo;\r\nimport com.nmbb.oplayer.ui.base.ArrayAdapter;\r\nimport com.nmbb.oplayer.ui.helper.XmlReaderHelper;\r\nimport com.nmbb.oplayer.ui.player.VideoActivity;\r\nimport com.nmbb.oplayer.util.FileUtils;\r\n\r\nimport android.app.AlertDialog;\r\nimport android.app.Dialog;\r\nimport android.content.Context;\r\nimport android.content.DialogInterface;\r\nimport android.content.DialogInterface.OnClickListener;\r\nimport android.content.Intent;\r\nimport android.graphics.Bitmap;\r\nimport android.net.Uri;\r\nimport android.os.Bundle;\r\nimport android.os.Environment;\r\nimport android.text.TextUtils;\r\nimport android.view.KeyEvent;\r\nimport android.view.LayoutInflater;\r\nimport android.view.View;\r\nimport android.view.View.OnKeyListener;\r\nimport android.view.ViewGroup;\r\nimport android.webkit.WebView;\r\nimport android.webkit.WebViewClient;\r\nimport android.widget.AdapterView;\r\nimport android.widget.AdapterView.OnItemClickListener;\r\nimport android.widget.ImageView;\r\nimport android.widget.ListView;\r\nimport android.widget.TextView;\r\nimport android.widget.Toast;\r\n\r\npublic class FragmentOnline extends FragmentBase implements OnItemClickListener {\r\n\r\n\t/** 缓存视频列表 */\r\n\tprivate static ArrayList<String[]> mOnlineList = new ArrayList<String[]>();\r\n\t/** 缓存视频LOGO列表 */\r\n\tprivate static ArrayList<Integer> mOnlineLogoList = new ArrayList<Integer>();\r\n\tprivate WebView mWebView;\r\n\tprivate ListView mListView;\r\n\t/** 网页正在加载 */\r\n\tprivate View mLoading;\r\n\t/** 历史记录 */\r\n\tprivate List<String> mHistory = new ArrayList<String>();\r\n\t/** 显示当前正在加载的url */\r\n\tprivate TextView mUrl;\r\n\tprivate String mTitle;\r\n\tprivate final static ArrayList<OnlineVideo> root = new ArrayList<OnlineVideo>();\r\n\tprivate ArrayList<OnlineVideo> tvs;\r\n\tprivate final static ArrayList<OnlineVideo> videos = new ArrayList<OnlineVideo>();\r\n\tprivate int level = 1;\r\n\tprivate DataAdapter mAdapter;\r\n\r\n\t@Override\r\n\tpublic View onCreateView(LayoutInflater inflater, ViewGroup container,\r\n\t\t\tBundle savedInstanceState) {\r\n\t\tView mView = inflater.inflate(R.layout.fragment_online, container,\r\n\t\t\t\tfalse);\r\n\t\tmListView = (ListView) mView.findViewById(android.R.id.list);\r\n\t\tmWebView = (WebView) mView.findViewById(R.id.webview);\r\n\t\tmUrl = (TextView) mView.findViewById(R.id.url);\r\n\t\tmLoading = mView.findViewById(R.id.loading);\r\n\r\n\t\tmListView.setOnItemClickListener(this);\r\n\t\tinitWebView();\r\n\t\tmAdapter = new DataAdapter(getActivity());\r\n\t\tmListView.setAdapter(new DataAdapter(getActivity()));\r\n\t\treturn mView;\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void onItemClick(AdapterView<?> parent, View view, int position,\r\n\t\t\tlong id) {\r\n\t\tfinal OnlineVideo item = mAdapter.getItem(position);\r\n\t\tswitch (level) {\r\n\t\tcase 1:// 顶级\r\n\t\t\tlevel = 2;\r\n\t\t\tif (position == 0) {\r\n\t\t\t\t// 直播 \r\n\t\t\t\tif (tvs == null)\r\n\t\t\t\t\ttvs = XmlReaderHelper.getAllCategory(getActivity());\r\n\t\t\t\tmAdapter.replace(tvs);\r\n\t\t\t} else {\r\n\t\t\t\t// 视频 \r\n\t\t\t\tmAdapter.replace(videos);\r\n\t\t\t}\r\n\t\t\tmListView.setAdapter(mAdapter);\r\n\t\t\tbreak;\r\n\t\tcase 2://\r\n\t\t\tlevel = 3;\r\n\t\t\tif (item.id != null) {\r\n\t\t\t\t// 直播\r\n\t\t\t\tmAdapter.replace(XmlReaderHelper.getVideos(getActivity(),\r\n\t\t\t\t\t\titem.id));\r\n\t\t\t\tmListView.setAdapter(mAdapter);\r\n\t\t\t} else {\r\n\t\t\t\tclearAndLoad(item.url);\r\n\t\t\t}\r\n\t\t\tbreak;\r\n\t\tcase 3:\r\n\t\t\tlevel = 4;\r\n\t\t\t// clearAndLoad(item.url);\r\n\t\t\tIntent intent = new Intent(getActivity(), VideoActivity.class);\r\n\t\t\tintent.setData(Uri.parse(item.url));\r\n\t\t\t// intent.putExtra(\"path\", item.url);\r\n\t\t\tintent.putExtra(\r\n\t\t\t\t\t\"displayName                                                                                                                                                                                            \",\r\n\t\t\t\t\titem.title);\r\n\t\t\tstartActivity(intent);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\tprivate void clearAndLoad(String url) {\r\n\t\tmLoading.setVisibility(View.VISIBLE);\r\n\t\tmWebView.setVisibility(View.GONE);\r\n\t\tmListView.setVisibility(View.GONE);\r\n\t\tmHistory.clear();\r\n\t\tmWebView.clearView();\r\n\t\tmWebView.loadUrl(url);\r\n\t}\r\n\r\n\t@Override\r\n\tpublic boolean onBackPressed() {\r\n\t\tswitch (level) {\r\n\t\tcase 1:\r\n\t\t\treturn super.onBackPressed();\r\n\t\tcase 2:\r\n\t\t\tlevel = 1;\r\n\t\t\tmAdapter.replace(root);\r\n\t\t\tbreak;\r\n\t\tcase 3://\r\n\t\t\tlevel = 2;\r\n\t\t\tif (mListView == null || mListView.getVisibility() == View.VISIBLE) {\r\n\t\t\t\tmAdapter.replace(tvs);\r\n\t\t\t} else {\r\n\t\t\t\tswitchWebViewToListView();\r\n\t\t\t}\r\n\t\t\tbreak;\r\n\t\tcase 4:\r\n\t\t\tlevel = 3;\r\n\t\t\tswitchWebViewToListView();\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tmListView.setAdapter(mAdapter);\r\n\t\treturn true;\r\n\t}\r\n\r\n\tprivate void switchWebViewToListView() {\r\n\t\tmWebView.clearView();\r\n\t\tmUrl.setVisibility(View.GONE);\r\n\t\tmListView.setVisibility(View.VISIBLE);\r\n\t\tmWebView.setVisibility(View.GONE);\r\n\t\tmLoading.setVisibility(View.GONE);\r\n\t}\r\n\r\n\t/** 初始化WebView */\r\n\tprivate void initWebView() {\r\n\t\tmWebView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);\r\n\t\tmWebView.getSettings().setJavaScriptEnabled(true);\r\n\t\tmWebView.getSettings().setPluginsEnabled(true);\r\n\r\n\t\tmWebView.setWebViewClient(new WebViewClient() {\r\n\r\n\t\t\t/** 页面开始加载 */\r\n\t\t\t@Override\r\n\t\t\tpublic void onPageStarted(WebView view, String url, Bitmap favicon) {\r\n\t\t\t\tsuper.onPageStarted(view, url, favicon);\r\n\t\t\t\tmUrl.setText(url);\r\n\t\t\t\tmUrl.setVisibility(View.VISIBLE);\r\n\t\t\t}\r\n\r\n\t\t\t/** 页面加载完成 */\r\n\t\t\t@Override\r\n\t\t\tpublic void onPageFinished(WebView view, String url) {\r\n\t\t\t\tsuper.onPageFinished(view, url);\r\n\t\t\t\tmLoading.setVisibility(View.GONE);\r\n\t\t\t\tmWebView.setVisibility(View.VISIBLE);\r\n\t\t\t\tif (!mHistory.contains(url))\r\n\t\t\t\t\tmHistory.add(0, url);\r\n\t\t\t\tmUrl.setVisibility(View.GONE);\r\n\t\t\t\t// 取得title\r\n\t\t\t\tmTitle = view.getTitle();\r\n\t\t\t};\r\n\r\n\t\t\t/** 页面跳转 */\r\n\t\t\t@Override\r\n\t\t\tpublic boolean shouldOverrideUrlLoading(WebView view,\r\n\t\t\t\t\tfinal String url) {\r\n\t\t\t\tif (FileUtils.isVideoOrAudio(url)) {\r\n\t\t\t\t\tDialog dialog = new AlertDialog.Builder(getActivity())\r\n\t\t\t\t\t\t\t.setIcon(android.R.drawable.btn_star)\r\n\t\t\t\t\t\t\t.setTitle(\"播放/下载\").setMessage(url)\r\n\t\t\t\t\t\t\t.setPositiveButton(\"播放\", new OnClickListener() {\r\n\t\t\t\t\t\t\t\t@Override\r\n\t\t\t\t\t\t\t\tpublic void onClick(DialogInterface dialog,\r\n\t\t\t\t\t\t\t\t\t\tint which) {\r\n\t\t\t\t\t\t\t\t\tIntent intent = new Intent(getActivity(),\r\n\t\t\t\t\t\t\t\t\t\t\tVideoPlayerActivity.class);\r\n\t\t\t\t\t\t\t\t\tintent.putExtra(\"path\", url);\r\n\t\t\t\t\t\t\t\t\tintent.putExtra(\"title\", mTitle);\r\n\t\t\t\t\t\t\t\t\tstartActivity(intent);\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}).setNeutralButton(\"下载\", new OnClickListener() {\r\n\t\t\t\t\t\t\t\t@Override\r\n\t\t\t\t\t\t\t\tpublic void onClick(DialogInterface dialog,\r\n\t\t\t\t\t\t\t\t\t\tint which) {\r\n\t\t\t\t\t\t\t\t\tif (Environment.MEDIA_MOUNTED\r\n\t\t\t\t\t\t\t\t\t\t\t.equals(Environment\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t.getExternalStorageState())) {\r\n\t\t\t\t\t\t\t\t\t\tMainActivity activity = (MainActivity) getActivity();\r\n\t\t\t\t\t\t\t\t\t\tString savePath = Environment\r\n\t\t\t\t\t\t\t\t\t\t\t\t.getExternalStorageDirectory()\r\n\t\t\t\t\t\t\t\t\t\t\t\t+ \"/\";\r\n\t\t\t\t\t\t\t\t\t\tif (TextUtils.isEmpty(mTitle))\r\n\t\t\t\t\t\t\t\t\t\t\tsavePath += FileUtils\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t.getUrlFileName(url);\r\n\t\t\t\t\t\t\t\t\t\telse {\r\n\t\t\t\t\t\t\t\t\t\t\tsavePath += mTitle\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t+ \".\"\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t+ FileUtils\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.getUrlExtension(url);\r\n\t\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t\tactivity.mFileDownload.newDownloadFile(\r\n\t\t\t\t\t\t\t\t\t\t\t\turl, savePath);\r\n\t\t\t\t\t\t\t\t\t\tToast.makeText(\r\n\t\t\t\t\t\t\t\t\t\t\t\tgetActivity(),\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"正在下载 ..\"\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t+ FileUtils\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.getUrlFileName(savePath)\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t+ \" ，可从本地视频查看进度！\",\r\n\t\t\t\t\t\t\t\t\t\t\t\tToast.LENGTH_LONG).show();\r\n\t\t\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\t\t\tToast.makeText(getActivity(),\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"请检测SD卡!\", Toast.LENGTH_LONG)\r\n\t\t\t\t\t\t\t\t\t\t\t\t.show();\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}).setNegativeButton(\"取消\", null).create();\r\n\t\t\t\t\tdialog.show();\r\n\t\t\t\t\treturn true;\r\n\t\t\t\t}\r\n\t\t\t\treturn false;\r\n\t\t\t};\r\n\t\t});\r\n\r\n\t\t/** 处理后退键 */\r\n\t\tmWebView.setOnKeyListener(new OnKeyListener() {\r\n\t\t\t@Override\r\n\t\t\tpublic boolean onKey(View v, int keyCode, KeyEvent event) {\r\n\t\t\t\tif ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView != null\r\n\t\t\t\t\t\t&& mWebView.canGoBack()) {\r\n\t\t\t\t\tif (mHistory.size() > 1) {\r\n\t\t\t\t\t\tmHistory.remove(0);\r\n\t\t\t\t\t\tmWebView.loadUrl(mHistory.get(0));\r\n\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\t/** 数据适配 */\r\n\tprivate class DataAdapter extends ArrayAdapter<OnlineVideo> {\r\n\r\n\t\tpublic DataAdapter(Context ctx) {\r\n\t\t\tsuper(ctx, root);\r\n\t\t}\r\n\r\n\t\t@Override\r\n\t\tpublic View getView(int position, View convertView, ViewGroup parent) {\r\n\t\t\tfinal OnlineVideo item = getItem(position);\r\n\t\t\tif (convertView == null) {\r\n\t\t\t\tfinal LayoutInflater mInflater = getActivity()\r\n\t\t\t\t\t\t.getLayoutInflater();\r\n\t\t\t\tconvertView = mInflater.inflate(R.layout.fragment_online_item,\r\n\t\t\t\t\t\tnull);\r\n\t\t\t}\r\n\t\t\tImageView thumbnail = (ImageView) convertView\r\n\t\t\t\t\t.findViewById(R.id.thumbnail);\r\n\t\t\tif (item.iconId > 0)\r\n\t\t\t\tthumbnail.setImageResource(item.iconId);\r\n\t\t\telse\r\n\t\t\t\tthumbnail.setImageDrawable(null);\r\n\t\t\t((TextView) convertView.findViewById(R.id.title))\r\n\t\t\t\t\t.setText(item.title);\r\n\r\n\t\t\treturn convertView;\r\n\t\t}\r\n\r\n\t}\r\n\r\n\t// ~~~~~~~~~~~~~处理FLASH退出的问题 ~~~~~~~~\r\n\r\n\tprivate void callHiddenWebViewMethod(String name) {\r\n\t\tif (mWebView != null) {\r\n\t\t\ttry {\r\n\t\t\t\tMethod method = WebView.class.getMethod(name);\r\n\t\t\t\tmethod.invoke(mWebView);\r\n\t\t\t} catch (NoSuchMethodException e) {\r\n\t\t\t} catch (IllegalAccessException e) {\r\n\t\t\t} catch (InvocationTargetException e) {\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void onPause() {\r\n\t\tsuper.onPause();\r\n\t\tif (mWebView != null) {\r\n\t\t\tmWebView.pauseTimers();\r\n\t\t\tif (getActivity().isFinishing()) {\r\n\t\t\t\tmWebView.loadUrl(\"about:blank\");\r\n\t\t\t}\r\n\t\t\tcallHiddenWebViewMethod(\"onPause\");\r\n\t\t}\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void onResume() {\r\n\t\tsuper.onResume();\r\n\t\tif (mWebView != null) {\r\n\t\t\tmWebView.resumeTimers();\r\n\t\t\tcallHiddenWebViewMethod(\"onResume\");\r\n\t\t}\r\n\t}\r\n\r\n\tstatic {\r\n\r\n\t\t// private final static String[] CATEGORY = { \"电视直播\", \"视频网站\" };\r\n\t\troot.add(new OnlineVideo(\"电视直播\", R.drawable.logo_cntv, 1));\r\n\t\troot.add(new OnlineVideo(\"视频网站\", R.drawable.logo_youku, 0));\r\n\r\n\t\tvideos.add(new OnlineVideo(\"优酷视频\", R.drawable.logo_youku, 0,\r\n\t\t\t\t\"http://3g.youku.com\"));\r\n\t\tvideos.add(new OnlineVideo(\"搜狐视频\", R.drawable.logo_sohu, 0,\r\n\t\t\t\t\"http://m.tv.sohu.com\"));\r\n\t\tvideos.add(new OnlineVideo(\"乐视TV\", R.drawable.logo_letv, 0,\r\n\t\t\t\t\"http://m.letv.com\"));\r\n\t\tvideos.add(new OnlineVideo(\"爱奇异\", R.drawable.logo_iqiyi, 0,\r\n\t\t\t\t\"http://3g.iqiyi.com/\"));\r\n\t\tvideos.add(new OnlineVideo(\"PPTV\", R.drawable.logo_pptv, 0,\r\n\t\t\t\t\"http://m.pptv.com/\"));\r\n\t\tvideos.add(new OnlineVideo(\"腾讯视频\", R.drawable.logo_qq, 0,\r\n\t\t\t\t\"http://3g.v.qq.com/\"));\r\n\t\tvideos.add(new OnlineVideo(\"56.com\", R.drawable.logo_56, 0,\r\n\t\t\t\t\"http://m.56.com/\"));\r\n\t\tvideos.add(new OnlineVideo(\"新浪视频\", R.drawable.logo_sina, 0,\r\n\t\t\t\t\"http://video.sina.cn/\"));\r\n\t\tvideos.add(new OnlineVideo(\"土豆视频\", R.drawable.logo_tudou, 0,\r\n\t\t\t\t\"http://m.tudou.com\"));\r\n\t}\r\n}\r\n\r\n/*\r\n * private boolean loadVideo(final String url) { if (StringUtils.isEmpty(url))\r\n * return false;\r\n * \r\n * mCurrentUrl = url;\r\n * \r\n * new AsyncTask<Void, Void, OnlineVideo>() {\r\n * \r\n * @Override protected OnlineVideo doInBackground(Void... params) {\r\n * Log.d(\"Youku\", url); if (url.startsWith(\"http://m.youku.com\")) { return\r\n * VideoHelper.getYoukuVideo(url); } return null; }\r\n * \r\n * @Override protected void onPostExecute(OnlineVideo result) {\r\n * super.onPostExecute(result); if (result != null) { Intent intent = new\r\n * Intent(getActivity(), VideoPlayerActivity.class); intent.putExtra(\"path\",\r\n * result.url); intent.putExtra(\"title\", result.title); startActivity(intent); }\r\n * else { mWebView.loadUrl(url); } } }.execute(); return true; }\r\n */\r\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/MainActivity.java",
    "content": "package com.nmbb.oplayer.ui;\r\n\r\n\r\nimport android.content.Intent;\r\nimport android.os.Bundle;\r\nimport android.os.Environment;\r\nimport android.support.v4.app.Fragment;\r\nimport android.support.v4.app.FragmentActivity;\r\nimport android.support.v4.app.FragmentPagerAdapter;\r\nimport android.support.v4.view.ViewPager;\r\nimport android.view.View;\r\nimport android.view.View.OnClickListener;\r\nimport android.widget.RadioButton;\r\n\r\nimport com.nmbb.oplayer.OPlayerApplication;\r\nimport com.nmbb.oplayer.OPreference;\r\nimport com.nmbb.oplayer.R;\r\nimport com.nmbb.oplayer.service.MediaScannerService;\r\nimport com.nmbb.oplayer.ui.helper.FileDownloadHelper;\r\nimport com.nmbb.oplayer.ui.vitamio.LibsChecker;\r\n\r\npublic class MainActivity extends FragmentActivity implements OnClickListener {\r\n\r\n\t\r\n\tprivate ViewPager mPager;\r\n\tprivate RadioButton mRadioFile;\r\n\tprivate RadioButton mRadioOnline;\r\n\tpublic FileDownloadHelper mFileDownload;\r\n\r\n\t@Override\r\n\tprotected void onCreate(Bundle savedInstanceState) {\r\n\t\tsuper.onCreate(savedInstanceState);\r\n\r\n\t\tif (!LibsChecker.checkVitamioLibs(this, R.string.init_decoders))\r\n\t\t\treturn;\r\n\r\n\t\tOPreference pref = new OPreference(this);\r\n\t\t//\t首次运行，扫描SD卡\r\n\t\tif (pref.getBoolean(OPlayerApplication.PREF_KEY_FIRST, true)) {\r\n\t\t\tgetApplicationContext().startService(new Intent(getApplicationContext(), MediaScannerService.class).putExtra(MediaScannerService.EXTRA_DIRECTORY, Environment.getExternalStorageDirectory().getAbsolutePath()));\r\n\t\t}\r\n\r\n\t\tsetContentView(R.layout.fragment_pager);\r\n\r\n\t\t// ~~~~~~ 绑定控件\r\n\t\tmPager = (ViewPager) findViewById(R.id.pager);\r\n\t\tmRadioFile = (RadioButton) findViewById(R.id.radio_file);\r\n\t\tmRadioOnline = (RadioButton) findViewById(R.id.radio_online);\r\n\r\n\t\t// ~~~~~~ 绑定事件\r\n\t\tmRadioFile.setOnClickListener(this);\r\n\t\tmRadioOnline.setOnClickListener(this);\r\n\t\tmPager.setOnPageChangeListener(mPagerListener);\r\n\r\n\t\t// ~~~~~~ 绑定数据\r\n\t\tmPager.setAdapter(mAdapter);\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void onBackPressed() {\r\n\t\tif (getFragmentByPosition(mPager.getCurrentItem()).onBackPressed())\r\n\t\t\treturn;\r\n\t\telse\r\n\t\t\tsuper.onBackPressed();\r\n\t}\r\n\r\n\t@Override\r\n\tprotected void onDestroy() {\r\n\t\tsuper.onDestroy();\r\n\t\tif (mFileDownload != null)\r\n\t\t\tmFileDownload.stopALl();\r\n\t}\r\n\r\n\t/** 查找Fragment */\r\n\tprivate FragmentBase getFragmentByPosition(int position) {\r\n\t\treturn (FragmentBase) getSupportFragmentManager().findFragmentByTag(\"android:switcher:\" + mPager.getId() + \":\" + position);\r\n\t}\r\n\r\n\tprivate FragmentPagerAdapter mAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {\r\n\r\n\t\t/** 仅执行一次 */\r\n\t\t@Override\r\n\t\tpublic Fragment getItem(int position) {\r\n\t\t\tFragment result = null;\r\n\t\t\tswitch (position) {\r\n\t\t\tcase 1:\r\n\t\t\t\tresult = new FragmentOnline();// 在线视频\r\n\t\t\t\tbreak;\r\n\t\t\tcase 0:\r\n\t\t\tdefault:\r\n\t\t\t\tresult = new FragmentFileOld();// 本地视频\r\n\t\t\t\tmFileDownload = new FileDownloadHelper(((FragmentFileOld) result).mDownloadHandler);\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n\t\t@Override\r\n\t\tpublic int getCount() {\r\n\t\t\treturn 2;\r\n\t\t}\r\n\t};\r\n\r\n\tprivate ViewPager.SimpleOnPageChangeListener mPagerListener = new ViewPager.SimpleOnPageChangeListener() {\r\n\t\t@Override\r\n\t\tpublic void onPageSelected(int position) {\r\n\t\t\tswitch (position) {\r\n\t\t\tcase 0:// 本地视频\r\n\t\t\t\tmRadioFile.setChecked(true);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 1:// 在线视频\r\n\t\t\t\tmRadioOnline.setChecked(true);\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t@Override\r\n\tpublic void onClick(View v) {\r\n\t\tswitch (v.getId()) {\r\n\t\tcase R.id.radio_file:\r\n\t\t\tmPager.setCurrentItem(0);\r\n\t\t\tbreak;\r\n\t\tcase R.id.radio_online:\r\n\t\t\tmPager.setCurrentItem(1);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n}\r\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/PlayerActivity.java",
    "content": "/*\n * Copyright (C) 2011 VOV IO (http://vov.io/)\n */\n\npackage com.nmbb.oplayer.ui;\n\nimport com.nmbb.oplayer.R;\n\nimport io.vov.vitamio.MediaPlayer;\nimport io.vov.vitamio.MediaPlayer.OnBufferingUpdateListener;\nimport io.vov.vitamio.MediaPlayer.OnCompletionListener;\nimport io.vov.vitamio.MediaPlayer.OnPreparedListener;\nimport io.vov.vitamio.MediaPlayer.OnVideoSizeChangedListener;\nimport android.app.Activity;\nimport android.os.Bundle;\nimport android.os.Environment;\nimport android.util.Log;\nimport android.view.SurfaceHolder;\nimport android.view.SurfaceView;\n\npublic class PlayerActivity extends Activity implements OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback {\n\n\tprivate static final String TAG = \"MediaPlayerDemo\";\n\tprivate int mVideoWidth;\n\tprivate int mVideoHeight;\n\tprivate MediaPlayer mMediaPlayer;\n\tprivate SurfaceView mPreview;\n\tprivate SurfaceHolder holder;\n\tprivate String path = Environment.getExternalStorageDirectory() + \"/Moon.mp4\";\n\n\tprivate boolean mIsVideoSizeKnown = false;\n\tprivate boolean mIsVideoReadyToBePlayed = false;\n\n\t@Override\n\tpublic void onCreate(Bundle icicle) {\n\t\tsuper.onCreate(icicle);\n\t\tsetContentView(R.layout.mediaplayer);\n\t\tmPreview = (SurfaceView) findViewById(R.id.surface);\n\t\tholder = mPreview.getHolder();\n\t\tholder.addCallback(this);\n\t}\n\n\tprivate void playVideo() {\n\t\tdoCleanUp();\n\t\ttry {\n\t\t\tmMediaPlayer = new MediaPlayer(this);\n\t\t\tmMediaPlayer.setDataSource(path);\n\t\t\tmMediaPlayer.setDisplay(holder);\n\t\t\tmMediaPlayer.prepareAsync();\n\t\t\tmMediaPlayer.setScreenOnWhilePlaying(true);\n\t\t\tmMediaPlayer.setOnBufferingUpdateListener(this);\n\t\t\tmMediaPlayer.setOnCompletionListener(this);\n\t\t\tmMediaPlayer.setOnPreparedListener(this);\n\t\t\tmMediaPlayer.setOnVideoSizeChangedListener(this);\n\t\t} catch (Exception e) {\n\t\t\tLog.e(TAG, \"error: \" + e.getMessage(), e);\n\t\t}\n\t}\n\n\t@Override\n  public void onBufferingUpdate(MediaPlayer arg0, int percent) {\n\t\tLog.d(TAG, \"onBufferingUpdate percent:\" + percent);\n\n\t}\n\n\t@Override\n  public void onCompletion(MediaPlayer arg0) {\n\t\tLog.d(TAG, \"onCompletion called\");\n\t\tmMediaPlayer.release();\n\t}\n\n\t@Override\n  public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {\n\t\tLog.v(TAG, \"onVideoSizeChanged called\");\n\t\tif (width == 0 || height == 0) {\n\t\t\tLog.e(TAG, \"invalid video width(\" + width + \") or height(\" + height + \")\");\n\t\t\treturn;\n\t\t}\n\t\tmIsVideoSizeKnown = true;\n\t\tmVideoWidth = width;\n\t\tmVideoHeight = height;\n\t\tif (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {\n\t\t\tstartVideoPlayback();\n\t\t}\n\t}\n\n\t@Override\n  public void onPrepared(MediaPlayer mediaplayer) {\n\t\tLog.d(TAG, \"onPrepared called\");\n\t\tmIsVideoReadyToBePlayed = true;\n\t\tif (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {\n\t\t\tstartVideoPlayback();\n\t\t}\n\t}\n\n\t@Override\n  public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) {\n\t\tLog.d(TAG, \"surfaceChanged called\" + i + \"  \" + j + \"   \" + k);\n\t}\n\n\t@Override\n  public void surfaceDestroyed(SurfaceHolder surfaceholder) {\n\t\tLog.d(TAG, \"surfaceDestroyed called\");\n\t}\n\n\t@Override\n  public void surfaceCreated(SurfaceHolder holder) {\n\t\tLog.d(TAG, \"surfaceCreated called\");\n\t\tplayVideo();\n\t}\n\n\t@Override\n\tprotected void onPause() {\n\t\tsuper.onPause();\n\t\treleaseMediaPlayer();\n\t\tdoCleanUp();\n\t}\n\n\t@Override\n\tprotected void onDestroy() {\n\t\tsuper.onDestroy();\n\t\treleaseMediaPlayer();\n\t\tdoCleanUp();\n\t}\n\n\tprivate void releaseMediaPlayer() {\n\t\tif (mMediaPlayer != null) {\n\t\t\tmMediaPlayer.release();\n\t\t\tmMediaPlayer = null;\n\t\t}\n\t}\n\n\tprivate void doCleanUp() {\n\t\tmVideoWidth = 0;\n\t\tmVideoHeight = 0;\n\t\tmIsVideoReadyToBePlayed = false;\n\t\tmIsVideoSizeKnown = false;\n\t}\n\n\tprivate void startVideoPlayback() {\n\t\tLog.v(TAG, \"startVideoPlayback\");\n\t\tholder.setFixedSize(mVideoWidth, mVideoHeight);\n\t\tmMediaPlayer.start();\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/VideoPlayerActivity.java",
    "content": "/*\n * Copyright (C) 2011 VOV IO (http://vov.io/)\n */\n\npackage com.nmbb.oplayer.ui;\n\nimport com.nmbb.oplayer.R;\nimport com.nmbb.oplayer.exception.Logger;\nimport com.nmbb.oplayer.ui.vitamio.LibsChecker;\n\nimport io.vov.vitamio.MediaPlayer;\nimport io.vov.vitamio.MediaPlayer.OnCompletionListener;\nimport io.vov.vitamio.MediaPlayer.OnInfoListener;\nimport io.vov.vitamio.widget.MediaController;\nimport io.vov.vitamio.widget.VideoView;\nimport android.app.Activity;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.content.pm.ActivityInfo;\nimport android.content.res.Configuration;\nimport android.media.AudioManager;\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.os.Environment;\nimport android.os.Handler;\nimport android.os.Message;\nimport android.text.TextUtils;\nimport android.view.Display;\nimport android.view.GestureDetector.SimpleOnGestureListener;\nimport android.view.GestureDetector;\nimport android.view.MotionEvent;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.view.WindowManager;\nimport android.widget.ImageView;\n\npublic class VideoPlayerActivity extends Activity implements OnCompletionListener, OnInfoListener {\n\n\tprivate String mPath;\n\tprivate String mTitle;\n\tprivate VideoView mVideoView;\n\tprivate View mVolumeBrightnessLayout;\n\tprivate ImageView mOperationBg;\n\tprivate ImageView mOperationPercent;\n\tprivate AudioManager mAudioManager;\n\t/** 最大声音 */\n\tprivate int mMaxVolume;\n\t/** 当前声音 */\n\tprivate int mVolume = -1;\n\t/** 当前亮度 */\n\tprivate float mBrightness = -1f;\n\t/** 当前缩放模式 */\n\tprivate int mLayout = VideoView.VIDEO_LAYOUT_ZOOM;\n\tprivate GestureDetector mGestureDetector;\n\tprivate MediaController mMediaController;\n\tprivate View mLoadingView;\n\n\t@Override\n\tpublic void onCreate(Bundle bundle) {\n\t\tsuper.onCreate(bundle);\n\n\t\t// ~~~ 检测Vitamio是否解压解码包\n\t\tif (!LibsChecker.checkVitamioLibs(this, R.string.init_decoders))\n\t\t\treturn;\n\n\t\t// ~~~ 获取播放地址和标题\n\t\tIntent intent = getIntent();\n\t\tmPath = intent.getStringExtra(\"path\");\n\t\tmTitle = intent.getStringExtra(\"title\");\n\t\tif (TextUtils.isEmpty(mPath)) {\n\t\t\tmPath = Environment.getExternalStorageDirectory() + \"/video/你太猖狂.flv\";\n\n\t\t} else if (intent.getData() != null)\n\t\t\tmPath = intent.getData().toString();\n\n\t\t// ~~~ 绑定控件\n\t\tsetContentView(R.layout.videoview);\n\t\tmVideoView = (VideoView) findViewById(R.id.surface_view);\n\t\tmVolumeBrightnessLayout = findViewById(R.id.operation_volume_brightness);\n\t\tmOperationBg = (ImageView) findViewById(R.id.operation_bg);\n\t\tmOperationPercent = (ImageView) findViewById(R.id.operation_percent);\n\t\tmLoadingView = findViewById(R.id.video_loading);\n\n\t\t// ~~~ 绑定事件\n\t\tmVideoView.setOnCompletionListener(this);\n\t\tmVideoView.setOnInfoListener(this);\n\n\t\t// ~~~ 绑定数据\n\t\tmAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);\n\t\tmMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);\n\t\tif (mPath.startsWith(\"http:\"))\n\t\t\tmVideoView.setVideoURI(Uri.parse(mPath));\n\t\telse\n\t\t\tmVideoView.setVideoPath(mPath);\n\n\t\t//设置显示名称\n\t\tmMediaController = new MediaController(this);\n\t\tmMediaController.setFileName(mTitle);\n\t\tmVideoView.setMediaController(mMediaController);\n\t\tmVideoView.requestFocus();\n\n\t\tmGestureDetector = new GestureDetector(this, new MyGestureListener());\n\t\tsetRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);\n\t}\n\n\t@Override\n\tprotected void onPause() {\n\t\tsuper.onPause();\n\t\tif (mVideoView != null)\n\t\t\tmVideoView.pause();\n\t}\n\n\t@Override\n\tprotected void onResume() {\n\t\tsuper.onResume();\n\t\tif (mVideoView != null)\n\t\t\tmVideoView.resume();\n\t}\n\n\t@Override\n\tprotected void onDestroy() {\n\t\tsuper.onDestroy();\n\t\tif (mVideoView != null)\n\t\t\tmVideoView.stopPlayback();\n\t}\n\n\t@Override\n\tpublic boolean onTouchEvent(MotionEvent event) {\n\t\tif (mGestureDetector.onTouchEvent(event))\n\t\t\treturn true;\n\n\t\t// 处理手势结束\n\t\tswitch (event.getAction() & MotionEvent.ACTION_MASK) {\n\t\tcase MotionEvent.ACTION_UP:\n\t\t\tendGesture();\n\t\t\tbreak;\n\t\t}\n\n\t\treturn super.onTouchEvent(event);\n\t}\n\n\t/** 手势结束 */\n\tprivate void endGesture() {\n\t\tmVolume = -1;\n\t\tmBrightness = -1f;\n\n\t\t// 隐藏\n\t\tmDismissHandler.removeMessages(0);\n\t\tmDismissHandler.sendEmptyMessageDelayed(0, 500);\n\t}\n\n\tprivate class MyGestureListener extends SimpleOnGestureListener {\n\n\t\t/** 双击 */\n\t\t@Override\n\t\tpublic boolean onDoubleTap(MotionEvent e) {\n\t\t\tif (mLayout == VideoView.VIDEO_LAYOUT_ZOOM)\n\t\t\t\tmLayout = VideoView.VIDEO_LAYOUT_ORIGIN;\n\t\t\telse\n\t\t\t\tmLayout++;\n\t\t\tif (mVideoView != null)\n\t\t\t\tmVideoView.setVideoLayout(mLayout, 0);\n\t\t\treturn true;\n\t\t}\n\n\t\t/** 滑动 */\n\t\t@Override\n\t\tpublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {\n\t\t\tfloat mOldX = e1.getX(), mOldY = e1.getY();\n\t\t\tint y = (int) e2.getRawY();\n\t\t\tDisplay disp = getWindowManager().getDefaultDisplay();\n\t\t\tint windowWidth = disp.getWidth();\n\t\t\tint windowHeight = disp.getHeight();\n\n\t\t\tif (mOldX > windowWidth * 4.0 / 5)// 右边滑动\n\t\t\t\tonVolumeSlide((mOldY - y) / windowHeight);\n\t\t\telse if (mOldX < windowWidth / 5.0)// 左边滑动\n\t\t\t\tonBrightnessSlide((mOldY - y) / windowHeight);\n\n\t\t\treturn super.onScroll(e1, e2, distanceX, distanceY);\n\t\t}\n\t}\n\n\t/** 定时隐藏 */\n\tprivate Handler mDismissHandler = new Handler() {\n\t\t@Override\n\t\tpublic void handleMessage(Message msg) {\n\t\t\tmVolumeBrightnessLayout.setVisibility(View.GONE);\n\t\t}\n\t};\n\n\t/**\n\t * 滑动改变声音大小\n\t * \n\t * @param percent\n\t */\n\tprivate void onVolumeSlide(float percent) {\n\t\tif (mVolume == -1) {\n\t\t\tmVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);\n\t\t\tif (mVolume < 0)\n\t\t\t\tmVolume = 0;\n\n\t\t\t// 显示\n\t\t\tmOperationBg.setImageResource(R.drawable.video_volumn_bg);\n\t\t\tmVolumeBrightnessLayout.setVisibility(View.VISIBLE);\n\t\t}\n\n\t\tint index = (int) (percent * mMaxVolume) + mVolume;\n\t\tif (index > mMaxVolume)\n\t\t\tindex = mMaxVolume;\n\t\telse if (index < 0)\n\t\t\tindex = 0;\n\n\t\t// 变更声音\n\t\tmAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0);\n\n\t\t// 变更进度条\n\t\tViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();\n\t\tlp.width = findViewById(R.id.operation_full).getLayoutParams().width * index / mMaxVolume;\n\t\tmOperationPercent.setLayoutParams(lp);\n\t}\n\n\t/**\n\t * 滑动改变亮度\n\t * \n\t * @param percent\n\t */\n\tprivate void onBrightnessSlide(float percent) {\n\t\tif (mBrightness < 0) {\n\t\t\tmBrightness = getWindow().getAttributes().screenBrightness;\n\t\t\tif (mBrightness <= 0.00f)\n\t\t\t\tmBrightness = 0.50f;\n\t\t\tif (mBrightness < 0.01f)\n\t\t\t\tmBrightness = 0.01f;\n\n\t\t\t// 显示\n\t\t\tmOperationBg.setImageResource(R.drawable.video_brightness_bg);\n\t\t\tmVolumeBrightnessLayout.setVisibility(View.VISIBLE);\n\t\t}\n\t\tWindowManager.LayoutParams lpa = getWindow().getAttributes();\n\t\tlpa.screenBrightness = mBrightness + percent;\n\t\tif (lpa.screenBrightness > 1.0f)\n\t\t\tlpa.screenBrightness = 1.0f;\n\t\telse if (lpa.screenBrightness < 0.01f)\n\t\t\tlpa.screenBrightness = 0.01f;\n\t\tgetWindow().setAttributes(lpa);\n\n\t\tViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();\n\t\tlp.width = (int) (findViewById(R.id.operation_full).getLayoutParams().width * lpa.screenBrightness);\n\t\tmOperationPercent.setLayoutParams(lp);\n\t}\n\n\t@Override\n\tpublic void onConfigurationChanged(Configuration newConfig) {\n\t\tif (mVideoView != null)\n\t\t\tmVideoView.setVideoLayout(mLayout, 0);\n\t\tsuper.onConfigurationChanged(newConfig);\n\t}\n\n\t@Override\n\tpublic void onCompletion(MediaPlayer player) {\n\t\tfinish();\n\t}\n\n\tprivate void stopPlayer() {\n\t\tif (mVideoView != null)\n\t\t\tmVideoView.pause();\n\t}\n\n\tprivate void startPlayer() {\n\t\tif (mVideoView != null)\n\t\t\tmVideoView.start();\n\t}\n\n\tprivate boolean isPlaying() {\n\t\treturn mVideoView != null && mVideoView.isPlaying();\n\t}\n\n\t/** 是否需要自动恢复播放，用于自动暂停，恢复播放 */\n\tprivate boolean needResume;\n\n\t@Override\n\tpublic boolean onInfo(MediaPlayer arg0, int arg1, int arg2) {\n\t\tswitch (arg1) {\n\t\tcase MediaPlayer.MEDIA_INFO_BUFFERING_START:\n\t\t\t//开始缓存，暂停播放\n\t\t\tif (isPlaying()) {\n\t\t\t\tstopPlayer();\n\t\t\t\tneedResume = true;\n\t\t\t}\n\t\t\tmLoadingView.setVisibility(View.VISIBLE);\n\t\t\tbreak;\n\t\tcase MediaPlayer.MEDIA_INFO_BUFFERING_END:\n\t\t\t//缓存完成，继续播放\n\t\t\tif (needResume)\n\t\t\t\tstartPlayer();\n\t\t\tmLoadingView.setVisibility(View.GONE);\n\t\t\tbreak;\n\t\tcase MediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED:\n\t\t\t//显示 下载速度\n\t\t\tLogger.e(\"download rate:\" + arg2);\n\t\t\t//mListener.onDownloadRateChanged(arg2);\n\t\t\tbreak;\n\t\t}\n\t\treturn true;\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/adapter/FileAdapter.java",
    "content": "package com.nmbb.oplayer.ui.adapter;\n\nimport java.util.ArrayList;\n\nimport com.nmbb.oplayer.R;\nimport com.nmbb.oplayer.po.PFile;\nimport com.nmbb.oplayer.util.FileUtils;\n\nimport android.content.Context;\nimport android.database.Cursor;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.CursorAdapter;\nimport android.widget.ImageView;\nimport android.widget.TextView;\n\npublic class FileAdapter extends CursorAdapter {\n\n\tprivate LayoutInflater mInflater;\n\tprivate ArrayList<Character> mKey = new ArrayList<Character>();\n\n\tpublic FileAdapter(Context context, Cursor c) {\n\t\tsuper(context, c, false);\n\t\tmInflater = LayoutInflater.from(context);\n\t}\n\n\t@Override\n\tpublic View newView(Context context, Cursor cursor, ViewGroup parent) {\n\t\treturn mInflater.inflate(R.layout.fragment_file_item, null);\n\t}\n\n\t@Override\n\tpublic void changeCursor(Cursor cursor) {\n\t\tinitKeys(cursor);\n\t  super.changeCursor(cursor);\n\t}\n\t\n\tprivate void initKeys(Cursor c) {\n\t\tif (c != null && !c.isClosed()) {\n\t\t\tmKey.clear();\n\t\t\twhile (c.moveToNext()) {\n\t\t\t\tString title_key = c.getString(2);\n\t\t\t\tmKey.add(title_key.charAt(0));\n\t\t\t}\n\t\t}\n\t}\n\n\t/** 根据拼音名称获取位置 */\n\tpublic int getPositionByName(char key) {\n\t\treturn mKey.indexOf(key);\n\t}\n\n\t@Override\n\tpublic PFile getItem(int position) {\n\t\tif (getCursor().moveToPosition(position))\n\t\t\treturn new PFile(getCursor());\n\t\telse\n\t\t\treturn null;\n\t}\n\n\t@Override\n\tpublic void bindView(View convertView, Context context, Cursor cursor) {\n\t\tfinal PFile f = new PFile(cursor);\n\t\t//显示名称\n\t\t((TextView) convertView.findViewById(R.id.title)).setText(f.title);\n\n\t\t//显示文件大小\n\t\tString file_size;\n\t\tif (f.temp_file_size > 0) {\n\t\t\tfile_size = FileUtils.showFileSize(f.temp_file_size) + \" / \" + FileUtils.showFileSize(f.file_size);\n\t\t} else {\n\t\t\tfile_size = FileUtils.showFileSize(f.file_size);\n\t\t}\n\t\t((TextView) convertView.findViewById(R.id.file_size)).setText(file_size);\n\n\t\t//显示缩略图\n\t\t((ImageView) convertView.findViewById(R.id.thumbnail)).setImageBitmap(f.getThumb(context));\n\t}\n\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/adapter/FileDownloadAdapter.java",
    "content": "package com.nmbb.oplayer.ui.adapter;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\n\nimport android.content.Context;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.ImageView;\nimport android.widget.TextView;\n\nimport com.nmbb.oplayer.R;\nimport com.nmbb.oplayer.po.PFile;\nimport com.nmbb.oplayer.ui.base.ArrayAdapter;\nimport com.nmbb.oplayer.util.FileUtils;\n\npublic class FileDownloadAdapter extends ArrayAdapter<PFile> {\n\tprivate HashMap<String, PFile> maps = new HashMap<String, PFile>();\n\n\tprivate LayoutInflater mInflater;\n\n\tpublic FileDownloadAdapter(Context ctx, ArrayList<PFile> l) {\n\t\tsuper(ctx, l);\n\t\tmInflater = LayoutInflater.from(ctx);\n\t\tmaps.clear();\n\t}\n\n\t@Override\n\tpublic View getView(int position, View convertView, ViewGroup parent) {\n\t\tfinal PFile f = getItem(position);\n\t\tif (convertView == null) {\n\t\t\tconvertView = mInflater.inflate(R.layout.fragment_file_item, null);\n\t\t}\n\t\t((TextView) convertView.findViewById(R.id.title)).setText(f.title);\n\n\t\t//显示文件大小\n\t\tString file_size;\n\t\tif (f.temp_file_size > 0) {\n\t\t\tfile_size = FileUtils.showFileSize(f.temp_file_size) + \" / \" + FileUtils.showFileSize(f.file_size);\n\t\t} else {\n\t\t\tfile_size = FileUtils.showFileSize(f.file_size);\n\t\t}\n\t\t((TextView) convertView.findViewById(R.id.file_size)).setText(file_size);\n\n\t\t//显示进度表\n\t\tfinal ImageView status = (ImageView) convertView.findViewById(R.id.status);\n\t\tif (f.status > -1) {\n\t\t\tint resStauts = getStatusImage(f.status);\n\t\t\tif (resStauts > 0) {\n\t\t\t\tif (status.getVisibility() != View.VISIBLE)\n\t\t\t\t\tstatus.setVisibility(View.VISIBLE);\n\t\t\t\tstatus.setImageResource(resStauts);\n\t\t\t}\n\t\t} else {\n\t\t\tif (status.getVisibility() != View.GONE)\n\t\t\t\tstatus.setVisibility(View.GONE);\n\t\t}\n\t\treturn convertView;\n\t}\n\n\tprivate int getStatusImage(int status) {\n\t\tint resStauts = -1;\n\t\tswitch (status) {\n\t\tcase 0:\n\t\t\tresStauts = R.drawable.down_btn_0;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tresStauts = R.drawable.down_btn_1;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tresStauts = R.drawable.down_btn_2;\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tresStauts = R.drawable.down_btn_3;\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tresStauts = R.drawable.down_btn_4;\n\t\t\tbreak;\n\t\tcase 5:\n\t\t\tresStauts = R.drawable.down_btn_5;\n\t\t\tbreak;\n\t\tcase 6:\n\t\t\tresStauts = R.drawable.down_btn_6;\n\t\t\tbreak;\n\t\tcase 7:\n\t\t\tresStauts = R.drawable.down_btn_7;\n\t\t\tbreak;\n\t\tcase 8:\n\t\t\tresStauts = R.drawable.down_btn_8;\n\t\t\tbreak;\n\t\tcase 9:\n\t\t\tresStauts = R.drawable.down_btn_9;\n\t\t\tbreak;\n\t\tcase 10:\n\t\t\tresStauts = R.drawable.down_btn_10;\n\t\t\tbreak;\n\t\t}\n\t\treturn resStauts;\n\t}\n\n\tpublic void add(PFile item, String url) {\n\t\tsuper.add(item);\n\t\tif (!maps.containsKey(url))\n\t\t\tmaps.put(url, item);\n\t}\n\n\tpublic void delete(int position) {\n\t\tsynchronized (mLock) {\n\t\t\tmObjects.remove(position);\n\t\t}\n\t\tnotifyDataSetChanged();\n\t}\n\n\tpublic PFile getItem(String url) {\n\t\treturn maps.get(url);\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/base/ArrayAdapter.java",
    "content": "package com.nmbb.oplayer.ui.base;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.Arrays;\r\nimport java.util.Collection;\r\nimport java.util.List;\r\n\r\nimport android.content.Context;\r\nimport android.view.LayoutInflater;\r\nimport android.widget.BaseAdapter;\r\n\r\npublic abstract class ArrayAdapter<T> extends BaseAdapter {\r\n\r\n\t// 数据\r\n\tprotected ArrayList<T> mObjects;\r\n\tprotected LayoutInflater mInflater;\r\n\tprotected final Object mLock = new Object();\r\n\r\n\tpublic ArrayAdapter(final Context ctx, final ArrayList<T> l) {\r\n\t\tmObjects = l == null ? new ArrayList<T>() : l;\r\n\t\tmInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);\r\n\t}\r\n\r\n\tpublic ArrayAdapter(final Context ctx, final T... l) {\r\n\t\tmObjects = new ArrayList<T>();\r\n\t\tmObjects.addAll(Arrays.asList(l));\r\n\t\tmInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);\r\n\t}\r\n\r\n\tpublic ArrayAdapter(final Context ctx, final List<T> l) {\r\n\t\tmObjects = new ArrayList<T>();\r\n\t\tif (l != null)\r\n\t\t\tmObjects.addAll(l);\r\n\t\tmInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);\r\n\t}\r\n\r\n\tpublic ArrayAdapter(final Context ctx, final Collection<T> l) {\r\n\t\tmObjects = new ArrayList<T>();\r\n\t\tif (l != null)\r\n\t\t\tmObjects.addAll(l);\r\n\t\tmInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);\r\n\t}\r\n\r\n\t@Override\r\n\tpublic int getCount() {\r\n\t\treturn mObjects.size();\r\n\t}\r\n\r\n\t@Override\r\n\tpublic T getItem(int position) {\r\n\t\treturn mObjects.get(position);\r\n\t}\r\n\r\n\t@Override\r\n\tpublic long getItemId(int position) {\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tpublic void add(T item) {\r\n\t\tthis.mObjects.add(item);\r\n\t}\r\n\r\n\tpublic void replace(ArrayList<T> newObjects) {\r\n\t\tif (newObjects == null)\r\n\t\t\tnewObjects = new ArrayList<T>();\r\n\t\tthis.mObjects = newObjects;\r\n\t}\r\n\r\n\t/**\r\n\t * Adds the specified items at the end of the array.\r\n\t * \r\n\t * @param items The items to add at the end of the array.\r\n\t */\r\n\tpublic void addAll(T... items) {\r\n\t\tArrayList<T> values = this.mObjects;\r\n\t\tfor (T item : items) {\r\n\t\t\tvalues.add(item);\r\n\t\t}\r\n\t\tthis.mObjects = values;\r\n\t}\r\n\r\n\t/**\r\n\t * \r\n\t * @param collection\r\n\t */\r\n\tpublic void addAll(Collection<? extends T> collection) {\r\n\t\tmObjects.addAll(collection);\r\n\t}\r\n\r\n\t/**\r\n\t * Remove all elements from the list.\r\n\t */\r\n\tpublic void clear() {\r\n\t\tmObjects.clear();\r\n\t}\r\n\r\n\t/**\r\n\t * 获取所有数据\r\n\t * \r\n\t * @return\r\n\t */\r\n\tpublic final ArrayList<T> getAll() {\r\n\t\treturn mObjects;\r\n\t}\r\n}\r\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/base/FilterArrayAdapter.java",
    "content": "package com.nmbb.oplayer.ui.base;\r\n\r\nimport java.util.ArrayList;\r\n\r\nimport android.content.Context;\r\nimport android.graphics.Color;\r\nimport android.text.SpannableStringBuilder;\r\nimport android.text.Spanned;\r\nimport android.text.TextUtils;\r\nimport android.text.style.ForegroundColorSpan;\r\nimport android.widget.Filter;\r\n\r\npublic abstract class FilterArrayAdapter<T> extends ArrayAdapter<T> {\r\n\r\n\tprivate String mFilterString;\r\n\tprivate Object mLock = new Object();\r\n\tprivate ListFilter mFilter;\r\n\tprivate ArrayList<T> mOriginalValues;\r\n\tprotected final ForegroundColorSpan redSpan = new ForegroundColorSpan(\r\n\t\t\tColor.RED);\r\n\r\n\r\n\tpublic FilterArrayAdapter(Context ctx, ArrayList<T> l) {\r\n\t\tsuper(ctx, l);\r\n\t}\r\n\r\n\tpublic Filter getFilter() {\r\n\t\tif (mFilter == null) {\r\n\t\t\tmFilter = new ListFilter();\r\n\t\t}\r\n\t\treturn mFilter;\r\n\t}\r\n\t\r\n\t/**\r\n\t * 获取搜索字符串\r\n\t * \r\n\t * @return\r\n\t */\r\n\tpublic String getFilterString() {\r\n\t\treturn mFilterString;\r\n\t}\r\n\t\r\n\t/**\r\n\t * 高亮文本\r\n\t * \r\n\t * @param text\r\n\t *            文本\r\n\t * @return\r\n\t */\r\n\tpublic CharSequence highlightText(String text) {\r\n\t\tCharSequence result;\r\n\t\tfinal String key = mFilterString;\r\n\t\tint index = TextUtils.isEmpty(key) ? -1 : text.toLowerCase().indexOf(key.toLowerCase());\r\n\t\tif (index > -1) {\r\n\t\t\tSpannableStringBuilder nameStyle = new SpannableStringBuilder(text);\r\n\t\t\tnameStyle.setSpan(redSpan, index, index + key.length(),\r\n\t\t\t\t\tSpanned.SPAN_EXCLUSIVE_EXCLUSIVE);\r\n\t\t\tresult = nameStyle;\r\n\t\t} else\r\n\t\t\tresult = text;\r\n\t\treturn result;\r\n\t}\r\n\t\r\n\t/**\r\n\t * 过滤\r\n\t * \r\n\t * @param values\r\n\t * @param prefixString\r\n\t * @return\r\n\t */\r\n\tpublic abstract ArrayList<T> filter(final ArrayList<T> values, CharSequence prefixString);\r\n\r\n\t/**\r\n\t * <p>\r\n\t * An array filter constrains the content of the array adapter with a prefix.\r\n\t * Each item that does not start with the supplied prefix is removed from the\r\n\t * list.\r\n\t * </p>\r\n\t */\r\n\tprivate class ListFilter extends Filter {\r\n\t\t@Override\r\n\t\tprotected FilterResults performFiltering(CharSequence prefix) {\r\n\t\t\tFilterResults results = new FilterResults();\r\n\r\n\t\t\tif (mOriginalValues == null) {\r\n\t\t\t\tsynchronized (mLock) {\r\n\t\t\t\t\tmOriginalValues = new ArrayList<T>(mObjects);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (prefix == null || prefix.length() == 0) {\r\n\t\t\t\tmFilterString = \"\";\r\n\t\t\t\tsynchronized (mLock) {\r\n\t\t\t\t\tArrayList<T> list = new ArrayList<T>(mOriginalValues);\r\n\t\t\t\t\tresults.values = list;\r\n\t\t\t\t\tresults.count = list.size();\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tmFilterString = prefix.toString();\r\n\t\t\t\tfinal ArrayList<T> newValues = FilterArrayAdapter.this.filter(mOriginalValues, prefix);\r\n\t\t\t\tresults.values = newValues;\r\n\t\t\t\tresults.count = newValues.size();\r\n\t\t\t}\r\n\r\n\t\t\treturn results;\r\n\t\t}\r\n\r\n\t\t@SuppressWarnings(\"unchecked\")\r\n\t\t@Override\r\n\t\tprotected void publishResults(CharSequence constraint, FilterResults results) {\r\n\t\t\tmObjects = (ArrayList<T>) results.values;\r\n\r\n\t\t\t//filterComplate();\r\n\r\n\t\t\tif (results.count > 0) {\r\n\t\t\t\tnotifyDataSetChanged();\r\n\t\t\t} else {\r\n\t\t\t\tnotifyDataSetInvalidated();\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/base/ThreadPool.java",
    "content": "package com.nmbb.oplayer.ui.base;\n\nimport java.util.concurrent.LinkedBlockingQueue;\nimport java.util.concurrent.ThreadFactory;\nimport java.util.concurrent.ThreadPoolExecutor;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport android.os.Build;\n\npublic class ThreadPool {\n\tprivate AtomicBoolean mStopped = new AtomicBoolean(Boolean.FALSE);\n\tprivate ThreadPoolExecutor mQueue;\n\n\tpublic ThreadPool() {\n\t\tif (Build.VERSION.SDK_INT > 8) {\n\t\t\tmQueue = new ThreadPoolExecutor(10, 10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), sThreadFactory);\n\t\t\tmQueue.allowCoreThreadTimeOut(true);\n\t\t} else {\n\t\t\tmQueue = new ThreadPoolExecutor(2, 10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), sThreadFactory);\n\t\t}\n\t}\n\n\tpublic void start(Runnable run) {\n\t\tmQueue.execute(run);\n\t}\n\n\tpublic void stop() {\n\t\tif (!mStopped.get()) {\n\t\t\tmQueue.shutdownNow();\n\t\t\tmStopped.set(Boolean.TRUE);\n\t\t}\n\t}\n\n\tprivate static final ThreadFactory sThreadFactory = new ThreadFactory() {\n\t\tprivate final AtomicInteger mCount = new AtomicInteger(1);\n\n\t\t@Override\n\t\tpublic Thread newThread(Runnable r) {\n\t\t\treturn new Thread(r, \"ThreadPool #\" + mCount.getAndIncrement());\n\t\t}\n\t};\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/helper/FileDownloadHelper.java",
    "content": "package com.nmbb.oplayer.ui.helper;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.HashMap;\nimport java.util.Timer;\nimport java.util.TimerTask;\n\nimport org.apache.http.HttpEntity;\nimport org.apache.http.HttpResponse;\nimport org.apache.http.client.HttpClient;\nimport org.apache.http.client.methods.HttpGet;\nimport org.apache.http.impl.client.DefaultHttpClient;\n\nimport android.os.Handler;\nimport android.util.Log;\n\nimport com.nmbb.oplayer.ui.base.ThreadPool;\n\npublic class FileDownloadHelper {\n\tprivate static final String TAG = \"FileDownloadHelper\";\n\t/** 线程池 */\n\tprivate ThreadPool mPool = new ThreadPool();\n\t/** 开始下载 */\n\tpublic static final int MESSAGE_START = 0;\n\t/** 更新进度 */\n\tpublic static final int MESSAGE_PROGRESS = 1;\n\t/** 下载结束 */\n\tpublic static final int MESSAGE_STOP = 2;\n\t/** 下载出错 */\n\tpublic static final int MESSAGE_ERROR = 3;\n\t/** 中途终止 */\n\tprivate volatile boolean mIsStop = false;\n\tprivate Handler mHandler;\n\tpublic volatile HashMap<String, String> mDownloadUrls = new HashMap<String, String>();\n\n\tpublic FileDownloadHelper(Handler handler) {\n\t\tif (handler == null)\n\t\t\tthrow new IllegalArgumentException(\"handler不能为空!\");\n\n\t\tthis.mHandler = handler;\n\t}\n\n\tpublic void stopALl() {\n\t\tmIsStop = true;\n\t\tmPool.stop();\n\t}\n\n\t/**\n\t * 下载一个新的文件\n\t * \n\t * @param url\n\t * @param savePath\n\t */\n\tpublic void newDownloadFile(final String url, final String savePath) {\n\t\tif (mDownloadUrls.containsKey(url))\n\t\t\treturn;\n\t\telse\n\t\t\tmDownloadUrls.put(url, savePath);\n\t\tmPool.start(new Runnable() {\n\n\t\t\t@Override\n\t\t\tpublic void run() {\n\t\t\t\tmHandler.sendMessage(mHandler.obtainMessage(MESSAGE_START, url));\n\t\t\t\tHttpClient client = new DefaultHttpClient();\n\t\t\t\tHttpGet get = new HttpGet(url);\n\t\t\t\tInputStream inputStream = null;\n\t\t\t\tFileOutputStream outputStream = null;\n\t\t\t\ttry {\n\t\t\t\t\tHttpResponse response = client.execute(get);\n\t\t\t\t\tHttpEntity entity = response.getEntity();\n\t\t\t\t\tfinal int size = (int) entity.getContentLength();\n\t\t\t\t\tinputStream = entity.getContent();\n\t\t\t\t\tif (size > 0 && inputStream != null) {\n\t\t\t\t\t\toutputStream = new FileOutputStream(savePath);\n\t\t\t\t\t\tint ch = -1;\n\t\t\t\t\t\tbyte[] buf = new byte[1024];\n\t\t\t\t\t\t//每秒更新一次进度\n\t\t\t\t\t\tnew Timer().schedule(new TimerTask() {\n\n\t\t\t\t\t\t\t@Override\n\t\t\t\t\t\t\tpublic void run() {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tFileInputStream fis = new FileInputStream(new File(savePath));\n\t\t\t\t\t\t\t\t\tint downloadedSize = fis.available();\n\t\t\t\t\t\t\t\t\tif (downloadedSize >= size)\n\t\t\t\t\t\t\t\t\t\tcancel();\n\t\t\t\t\t\t\t\t\tmHandler.sendMessage(mHandler.obtainMessage(MESSAGE_PROGRESS, downloadedSize, size, url));\n\t\t\t\t\t\t\t\t} catch (Exception e) {\n\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}, 50, 1000);\n\n\t\t\t\t\t\twhile ((ch = inputStream.read(buf)) != -1 && !mIsStop) {\n\t\t\t\t\t\t\toutputStream.write(buf, 0, ch);\n\t\t\t\t\t\t}\n\t\t\t\t\t\toutputStream.flush();\n\t\t\t\t\t}\n\t\t\t\t} catch (Exception e) {\n\t\t\t\t\tLog.e(TAG, e.getMessage(), e);\n\t\t\t\t\tmHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ERROR, url + \":\" + e.getMessage()));\n\t\t\t\t} finally {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (outputStream != null)\n\t\t\t\t\t\t\toutputStream.close();\n\t\t\t\t\t} catch (IOException ex) {\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (inputStream != null)\n\t\t\t\t\t\t\tinputStream.close();\n\t\t\t\t\t} catch (IOException ex) {\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tmDownloadUrls.remove(url);\n\t\t\t\tmHandler.sendMessage(mHandler.obtainMessage(MESSAGE_STOP, url));\n\t\t\t}\n\t\t});\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/helper/VideoHelper.java",
    "content": "package com.nmbb.oplayer.ui.helper;\r\n\r\nimport java.io.ByteArrayOutputStream;\r\nimport java.io.IOException;\r\nimport java.io.InputStream;\r\nimport java.net.HttpURLConnection;\r\nimport java.net.MalformedURLException;\r\nimport java.net.URL;\r\n\r\nimport com.nmbb.oplayer.util.StringUtils;\r\n\r\nimport android.os.Build;\r\nimport android.text.Html;\r\n\r\npublic class VideoHelper {\r\n\r\n\t/** 在线视频对象 */\r\n\tpublic static class OnlineVideo {\r\n\t\tpublic String url;\r\n\t\tpublic String title;\r\n\r\n\t\tpublic OnlineVideo() {\r\n\t\t}\r\n\r\n\t\tpublic OnlineVideo(String url) {\r\n\t\t\tthis.url = url;\r\n\t\t}\r\n\t}\r\n\r\n\t/** 获取优酷视频m3u8地址 */\r\n\tpublic static OnlineVideo getYoukuVideo(String url) {\r\n\t\tOnlineVideo result = null;\r\n\t\tString vid = \"\";\r\n\t\t//提取vid\r\n\t\tvid = substring(url, \"vid=\", \"&\");\r\n\r\n\t\tif (!StringUtils.isEmpty(vid)) {\r\n\t\t\tString title = \"\";\r\n\t\t\tString html = connect(url);\r\n\t\t\tif (!StringUtils.isEmpty(html)) {\r\n\t\t\t\t//获取title\r\n\t\t\t\ttitle = substring(html, \"<title>\", \"</title>\");\r\n\t\t\t\ttitle = substring(title, \"\", \"-优酷3G\", title);\r\n\t\t\t\ttitle = Html.fromHtml(title).toString();\r\n\t\t\t}\r\n\r\n\t\t\tresult = new OnlineVideo();\r\n\t\t\tresult.url = \"http://v.youku.com/player/getRealM3U8/vid/\" + vid + \"/type//video.m3u8\";\r\n\t\t\tresult.title = title;\r\n\t\t}\r\n\t\treturn result;\r\n\t}\r\n\r\n\tpublic static String substring(String search, String start, String end, String defaultValue) {\r\n\t\tint s_len = start.length();\r\n\t\tint s_pos = StringUtils.isEmpty(start) ? 0 : search.indexOf(start);\r\n\t\tif (s_pos > -1) {\r\n\t\t\tint end_pos = StringUtils.isEmpty(end) ? -1 : search.indexOf(end, s_pos + s_len);\r\n\t\t\tif (end_pos > -1)\r\n\t\t\t\treturn search.substring(s_pos + start.length(), end_pos);\r\n\t\t\telse\r\n\t\t\t\treturn search.substring(s_pos + start.length());\r\n\t\t}\r\n\t\treturn defaultValue;\r\n\t}\r\n\r\n\tpublic static String substring(String search, String start, String end) {\r\n\t\treturn substring(search, start, end, \"\");\r\n\t}\r\n\r\n\tprivate static String connect(String uri) {\r\n\t\treturn connect(uri, \"UTF8\");\r\n\t}\r\n\r\n\tprivate static String connect(String uri, String charsetName) {\r\n\t\tString result = \"\";\r\n\t\ttry {\r\n\t\t\tURL url = new URL(uri);\r\n\t\t\tHttpURLConnection conn = (HttpURLConnection) url.openConnection();\r\n\t\t\tconn.setConnectTimeout(5 * 1000);\r\n\t\t\tif (Integer.parseInt(Build.VERSION.SDK) < 8) {\r\n\t\t\t\tSystem.setProperty(\"http.keepAlive\", \"false\");\r\n\t\t\t}\r\n\t\t\tif (conn.getResponseCode() == 200) {\r\n\t\t\t\tInputStream is = conn.getInputStream();\r\n\t\t\t\tresult = readData(is, charsetName);\r\n\t\t\t}\r\n\t\t\tconn.disconnect();\r\n\t\t} catch (MalformedURLException e) {\r\n\t\t} catch (IOException e) {\r\n\t\t} catch (Exception e) {\r\n\t\t}\r\n\t\treturn result;\r\n\t}\r\n\r\n\tpublic static String readData(InputStream inSream, String charsetName) throws Exception {\r\n\t\tByteArrayOutputStream outStream = new ByteArrayOutputStream();\r\n\t\tbyte[] buffer = new byte[1024];\r\n\t\tint len = -1;\r\n\t\twhile ((len = inSream.read(buffer)) != -1) {\r\n\t\t\toutStream.write(buffer, 0, len);\r\n\t\t}\r\n\t\tbyte[] data = outStream.toByteArray();\r\n\t\toutStream.close();\r\n\t\tinSream.close();\r\n\t\treturn new String(data, charsetName);\r\n\t}\r\n}\r\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/helper/XmlReaderHelper.java",
    "content": "package com.nmbb.oplayer.ui.helper;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\n\nimport javax.xml.parsers.DocumentBuilder;\nimport javax.xml.parsers.DocumentBuilderFactory;\nimport javax.xml.parsers.ParserConfigurationException;\n\nimport org.w3c.dom.Document;\nimport org.w3c.dom.Element;\nimport org.w3c.dom.NamedNodeMap;\nimport org.w3c.dom.Node;\nimport org.w3c.dom.NodeList;\nimport org.xml.sax.SAXException;\n\nimport android.content.Context;\n\nimport com.nmbb.oplayer.po.OnlineVideo;\n\n/** 从XML读取电视台节目 */\npublic class XmlReaderHelper {\n\n\t/** 获取所有电视分类 */\n\tpublic static ArrayList<OnlineVideo> getAllCategory(final Context context) {\n\t\tArrayList<OnlineVideo> result = new ArrayList<OnlineVideo>();\n\t\tDocumentBuilderFactory docBuilderFactory = null;\n\t\tDocumentBuilder docBuilder = null;\n\t\tDocument doc = null;\n\t\ttry {\n\t\t\tdocBuilderFactory = DocumentBuilderFactory.newInstance();\n\t\t\tdocBuilder = docBuilderFactory.newDocumentBuilder();\n\t\t\t// xml file 放到 assets目录中的\n\t\t\tdoc = docBuilder.parse(context.getResources().getAssets()\n\t\t\t\t\t.open(\"online.xml\"));\n\t\t\t// root element\n\t\t\tElement root = doc.getDocumentElement();\n\t\t\tNodeList nodeList = root.getElementsByTagName(\"category\");\n\t\t\tfor (int i = 0; i < nodeList.getLength(); i++) {\n\t\t\t\tNode node = nodeList.item(i);// category\n\t\t\t\tOnlineVideo ov = new OnlineVideo();\n\t\t\t\tNamedNodeMap attr = node.getAttributes();\n\t\t\t\tov.title = attr.getNamedItem(\"name\").getNodeValue();\n\t\t\t\tov.id = attr.getNamedItem(\"id\").getNodeValue();\n\t\t\t\tov.category = 1;\n\t\t\t\tov.level = 2;\n\t\t\t\tov.is_category = true;\n\t\t\t\tresult.add(ov);\n\t\t\t\t// Read Node\n\t\t\t}\n\t\t} catch (IOException e) {\n\t\t} catch (SAXException e) {\n\t\t} catch (ParserConfigurationException e) {\n\t\t} finally {\n\t\t\tdoc = null;\n\t\t\tdocBuilder = null;\n\t\t\tdocBuilderFactory = null;\n\t\t}\n\t\treturn result;\n\t}\n\n\t/** 读取分类下所有电视地址 */\n\tpublic static ArrayList<OnlineVideo> getVideos(final Context context,\n\t\t\tString categoryId) {\n\t\tArrayList<OnlineVideo> result = new ArrayList<OnlineVideo>();\n\t\tDocumentBuilderFactory docBuilderFactory = null;\n\t\tDocumentBuilder docBuilder = null;\n\t\tDocument doc = null;\n\t\ttry {\n\t\t\tdocBuilderFactory = DocumentBuilderFactory.newInstance();\n\t\t\tdocBuilder = docBuilderFactory.newDocumentBuilder();\n\t\t\t// xml file 放到 assets目录中的\n\t\t\tdoc = docBuilder.parse(context.getResources().getAssets()\n\t\t\t\t\t.open(\"online.xml\"));\n\t\t\t// root element\n\t\t\tElement root = doc.getElementById(categoryId);\n\t\t\tif (root != null) {\n\t\t\t\tNodeList nodeList = root.getChildNodes();\n\t\t\t\tfor (int i = 0, j = nodeList.getLength(); i < j; i++) {\n\t\t\t\t\tNode baseNode = nodeList.item(i);\n\n\t\t\t\t\tif (!\"item\".equals(baseNode.getNodeName()))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tString id = baseNode.getFirstChild().getNodeValue();\n\t\t\t\t\tif (id == null)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tOnlineVideo ov = new OnlineVideo();\n\t\t\t\t\tov.id = id;\n\n\t\t\t\t\tElement el = doc.getElementById(ov.id);\n\t\t\t\t\tif (el != null) {\n\t\t\t\t\t\tov.title = el.getAttribute(\"title\");\n\t\t\t\t\t\tov.icon_url = el.getAttribute(\"image\");\n\t\t\t\t\t\tov.level = 3;\n\t\t\t\t\t\tov.category = 1;\n\t\t\t\t\t\tNodeList nodes = el.getChildNodes();\n\t\t\t\t\t\tfor (int m = 0, n = nodes.getLength(); m < n; m++) {\n\t\t\t\t\t\t\tNode node = nodes.item(m);\n\t\t\t\t\t\t\tif (!\"ref\".equals(node.getNodeName()))\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\tString href = node.getAttributes()\n\t\t\t\t\t\t\t\t\t.getNamedItem(\"href\").getNodeValue();\n\t\t\t\t\t\t\tif (ov.url == null) {\n\t\t\t\t\t\t\t\tov.url = href;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (ov.backup_url == null)\n\t\t\t\t\t\t\t\t\tov.backup_url = new ArrayList<String>();\n\t\t\t\t\t\t\t\tov.backup_url.add(href);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (ov.url != null)\n\t\t\t\t\t\t\tresult.add(ov);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (IOException e) {\n\t\t\te.printStackTrace();\n\t\t} catch (SAXException e) {\n\t\t\te.printStackTrace();\n\t\t} catch (ParserConfigurationException e) {\n\t\t\te.printStackTrace();\n\t\t} finally {\n\t\t\tdoc = null;\n\t\t\tdocBuilder = null;\n\t\t\tdocBuilderFactory = null;\n\t\t}\n\t\treturn result;\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/player/CommonGestures.java",
    "content": "/*\n * Copyright (C) 2012 YIXIA.COM\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.nmbb.oplayer.ui.player;\n\nimport android.annotation.SuppressLint;\nimport android.app.Activity;\nimport android.support.v4.view.GestureDetectorCompat;\nimport android.view.GestureDetector.SimpleOnGestureListener;\nimport android.view.MotionEvent;\nimport android.view.ScaleGestureDetector;\n\nimport com.nmbb.oplayer.util.DeviceUtils;\n\npublic class CommonGestures {\n\tpublic static final int SCALE_STATE_BEGIN = 0;\n\tpublic static final int SCALE_STATE_SCALEING = 1;\n\tpublic static final int SCALE_STATE_END = 2;\n\n\tprivate boolean mGestureEnabled;\n\n\tprivate GestureDetectorCompat mDoubleTapGestureDetector;\n\tprivate GestureDetectorCompat mTapGestureDetector;\n\tprivate ScaleGestureDetector mScaleDetector;\n\n\tprivate Activity mContext;\n\n\tpublic CommonGestures(Activity ctx) {\n\t\tmContext = ctx;\n\t\tmDoubleTapGestureDetector = new GestureDetectorCompat(mContext, new DoubleTapGestureListener());\n\t\tmTapGestureDetector = new GestureDetectorCompat(mContext, new TapGestureListener());\n\t\tmScaleDetector = new ScaleGestureDetector(mContext, new ScaleDetectorListener());\n\t}\n\n\tpublic boolean onTouchEvent(MotionEvent event) {\n\t\tif (mListener == null)\n\t\t\treturn false;\n\n\t\tif (mTapGestureDetector.onTouchEvent(event))\n\t\t\treturn true;\n\n\t\tif (event.getPointerCount() > 1) {\n\t\t\ttry {\n\t\t\t\tif (mScaleDetector != null && mScaleDetector.onTouchEvent(event))\n\t\t\t\t\treturn true;\n\t\t\t} catch (Exception e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}\n\n\t\tif (mDoubleTapGestureDetector.onTouchEvent(event))\n\t\t\treturn true;\n\n\t\tswitch (event.getAction() & MotionEvent.ACTION_MASK) {\n\t\tcase MotionEvent.ACTION_UP:\n\t\t\tmListener.onGestureEnd();\n\t\t\tbreak;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tprivate class TapGestureListener extends SimpleOnGestureListener {\n\t\t@Override\n\t\tpublic boolean onSingleTapConfirmed(MotionEvent event) {\n\t\t\tif (mListener != null)\n\t\t\t\tmListener.onSingleTap();\n\t\t\treturn true;\n\t\t}\n\n\t\t@Override\n\t\tpublic void onLongPress(MotionEvent e) {\n\t\t\tif (mListener != null && mGestureEnabled)\n\t\t\t\tmListener.onLongPress();\n\t\t}\n\t}\n\n\t@SuppressLint(\"NewApi\")\n\tprivate class ScaleDetectorListener implements ScaleGestureDetector.OnScaleGestureListener {\n\t\t@Override\n\t\tpublic boolean onScale(ScaleGestureDetector detector) {\n\t\t\tif (mListener != null && mGestureEnabled)\n\t\t\t\tmListener.onScale(detector.getScaleFactor(), SCALE_STATE_SCALEING);\n\t\t\treturn true;\n\t\t}\n\n\t\t@Override\n\t\tpublic void onScaleEnd(ScaleGestureDetector detector) {\n\t\t\tif (mListener != null && mGestureEnabled)\n\t\t\t\tmListener.onScale(0F, SCALE_STATE_END);\n\t\t}\n\n\t\t@Override\n\t\tpublic boolean onScaleBegin(ScaleGestureDetector detector) {\n\t\t\tif (mListener != null && mGestureEnabled)\n\t\t\t\tmListener.onScale(0F, SCALE_STATE_BEGIN);\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tprivate class DoubleTapGestureListener extends SimpleOnGestureListener {\n\t\tprivate boolean mDown = false;\n\n\t\t@Override\n\t\tpublic boolean onDown(MotionEvent event) {\n\t\t\tmDown = true;\n\t\t\treturn super.onDown(event);\n\t\t}\n\n\t\t@Override\n\t\tpublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {\n\t\t\tif (mListener != null && mGestureEnabled && e1 != null && e2 != null) {\n\t\t\t\tif (mDown) {\n\t\t\t\t\tmListener.onGestureBegin();\n\t\t\t\t\tmDown = false;\n\t\t\t\t}\n\t\t\t\tfloat mOldX = e1.getX(), mOldY = e1.getY();\n\t\t\t\tint windowWidth = DeviceUtils.getScreenWidth(mContext);\n\t\t\t\tint windowHeight = DeviceUtils.getScreenHeight(mContext);\n\t\t\t\tif (Math.abs(e2.getY(0) - mOldY) * 2 > Math.abs(e2.getX(0) - mOldX)) {\n\t\t\t\t\tif (mOldX > windowWidth * 4.0 / 5) {\n\t\t\t\t\t\tmListener.onRightSlide((mOldY - e2.getY(0)) / windowHeight);\n\t\t\t\t\t} else if (mOldX < windowWidth / 5.0) {\n\t\t\t\t\t\tmListener.onLeftSlide((mOldY - e2.getY(0)) / windowHeight);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn super.onScroll(e1, e2, distanceX, distanceY);\n\t\t}\n\n\t\t@Override\n\t\tpublic boolean onDoubleTap(MotionEvent event) {\n\t\t\tif (mListener != null && mGestureEnabled)\n\t\t\t\tmListener.onDoubleTap();\n\t\t\treturn super.onDoubleTap(event);\n\t\t}\n\t}\n\n\tpublic void setTouchListener(TouchListener l, boolean enable) {\n\t\tmListener = l;\n\t\tmGestureEnabled = enable;\n\t}\n\n\tprivate TouchListener mListener;\n\n\tpublic interface TouchListener {\n\t\tpublic void onGestureBegin();\n\n\t\tpublic void onGestureEnd();\n\n\t\tpublic void onLeftSlide(float percent);\n\n\t\tpublic void onRightSlide(float percent);\n\n\t\tpublic void onSingleTap();\n\n\t\tpublic void onDoubleTap();\n\n\t\tpublic void onScale(float scaleFactor, int state);\n\n\t\tpublic void onLongPress();\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/player/MediaController.java",
    "content": "/*\n * Copyright (C) 2012 YIXIA.COM\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.nmbb.oplayer.ui.player;\n\nimport java.lang.ref.WeakReference;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\n\nimport android.annotation.SuppressLint;\nimport android.annotation.TargetApi;\nimport android.app.Activity;\nimport android.content.Context;\nimport android.graphics.Rect;\nimport android.graphics.RectF;\nimport android.media.AudioManager;\nimport android.os.Handler;\nimport android.os.Message;\nimport android.view.Gravity;\nimport android.view.KeyEvent;\nimport android.view.LayoutInflater;\nimport android.view.MotionEvent;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.view.Window;\nimport android.view.WindowManager;\nimport android.view.animation.Animation;\nimport android.view.animation.Animation.AnimationListener;\nimport android.view.animation.AnimationUtils;\nimport android.widget.FrameLayout;\nimport android.widget.ImageButton;\nimport android.widget.ImageView;\nimport android.widget.PopupWindow;\nimport android.widget.SeekBar;\nimport android.widget.SeekBar.OnSeekBarChangeListener;\nimport android.widget.TextView;\n\nimport com.nmbb.oplayer.R;\nimport com.nmbb.oplayer.exception.Logger;\nimport com.nmbb.oplayer.ui.player.CommonGestures.TouchListener;\nimport com.nmbb.oplayer.util.DeviceUtils;\nimport com.nmbb.oplayer.util.FractionalTouchDelegate;\nimport com.nmbb.oplayer.util.StringUtils;\n\npublic class MediaController extends FrameLayout {\n\tprivate MediaPlayerControl mPlayer;\n\tprivate Activity mContext;\n\tprivate PopupWindow mWindow;\n\tprivate View mAnchor;\n\tprivate View mRoot;\n\tprivate ImageButton mLock;\n\tprivate ImageButton mScreenToggle;\n\tprivate ImageButton mSnapshot;\n\tprivate SeekBar mProgress;\n\tprivate TextView mEndTime, mCurrentTime;\n\tprivate long mDuration;\n\tprivate boolean mShowing;\n\tprivate boolean mScreenLocked = false;\n\tprivate boolean mDragging;\n\tprivate boolean mInstantSeeking = true;\n\tprivate static final int DEFAULT_TIME_OUT = 3000;\n\tprivate static final int DEFAULT_LONG_TIME_SHOW = 120000;\n\tprivate static final int DEFAULT_SEEKBAR_VALUE = 1000;\n\tprivate static final int TIME_TICK_INTERVAL = 1000;\n\tprivate ImageButton mPauseButton;\n\n\tprivate View mMediaController;\n\tprivate View mControlsLayout;\n\tprivate View mSystemInfoLayout;\n\tprivate View mControlsButtons;\n\tprivate View mMenu;\n\tprivate TextView mDateTime;\n\tprivate TextView mDownloadRate;\n\tprivate TextView mFileName;\n\tprivate TextView mBatteryLevel;\n\n\tprivate TextView mOperationInfo;\n\tprivate View mOperationVolLum;\n\tprivate ImageView mVolLumNum;\n\tprivate ImageView mVolLumBg;\n\n\tprivate AudioManager mAM;\n\tprivate int mMaxVolume;\n\tprivate float mBrightness = 0.01f;\n\tprivate int mVolume = 0;\n\tprivate Handler mHandler;\n\n\tprivate Animation mAnimSlideInTop;\n\tprivate Animation mAnimSlideInBottom;\n\tprivate Animation mAnimSlideOutTop;\n\tprivate Animation mAnimSlideOutBottom;\n\n\tprivate CommonGestures mGestures;\n\tprivate int mVideoMode;\n\n\tpublic MediaController(Context context) {\n\t\tsuper(context);\n\t\tmContext = (Activity) context;\n\t\tinitFloatingWindow();\n\t\tinitResources();\n\t}\n\n\tpublic MediaController(Context context, boolean locked) {\n\t\tthis(context);\n\t\tmScreenLocked = locked;\n\t\tlock(mScreenLocked);\n\t}\n\n\tprivate void initFloatingWindow() {\n\t\tmWindow = new PopupWindow(mContext);\n\t\tmWindow.setFocusable(true);\n\t\tmWindow.setBackgroundDrawable(null);\n\t\tmWindow.setOutsideTouchable(true);\n\t}\n\n\t@TargetApi(11)\n\tpublic void setWindowLayoutType() {\n\t\tif (DeviceUtils.hasICS()) {\n\t\t\ttry {\n\t\t\t\tmAnchor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);\n\t\t\t\tMethod setWindowLayoutType = PopupWindow.class.getMethod(\"setWindowLayoutType\", new Class[] { int.class });\n\t\t\t\tsetWindowLayoutType.invoke(mWindow, WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG);\n\t\t\t} catch (Exception e) {\n\t\t\t\tLogger.e(e);\n\t\t\t}\n\t\t}\n\t}\n\n\t@SuppressLint(\"NewApi\")\n\tprivate void initResources() {\n\t\tmHandler = new MHandler(this);\n\t\tmAM = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);\n\t\tmMaxVolume = mAM.getStreamMaxVolume(AudioManager.STREAM_MUSIC);\n\t\tmGestures = new CommonGestures(mContext);\n\t\tmGestures.setTouchListener(mTouchListener, true);\n\n\t\tmAnimSlideOutBottom = AnimationUtils.loadAnimation(mContext, R.anim.slide_out_bottom);\n\t\tmAnimSlideOutTop = AnimationUtils.loadAnimation(mContext, R.anim.slide_out_top);\n\t\tmAnimSlideInBottom = AnimationUtils.loadAnimation(mContext, R.anim.slide_in_bottom);\n\t\tmAnimSlideInTop = AnimationUtils.loadAnimation(mContext, R.anim.slide_in_top);\n\t\tmAnimSlideOutBottom.setAnimationListener(new AnimationListener() {\n\t\t\t@Override\n\t\t\tpublic void onAnimationStart(Animation animation) {\n\t\t\t}\n\n\t\t\t@Override\n\t\t\tpublic void onAnimationEnd(Animation animation) {\n\t\t\t\tmMediaController.setVisibility(View.GONE);\n\t\t\t\tshowButtons(false);\n\t\t\t\tmHandler.removeMessages(MSG_HIDE_SYSTEM_UI);\n\t\t\t\tmHandler.sendEmptyMessageDelayed(MSG_HIDE_SYSTEM_UI, DEFAULT_TIME_OUT);\n\t\t\t}\n\n\t\t\t@Override\n\t\t\tpublic void onAnimationRepeat(Animation animation) {\n\t\t\t}\n\t\t});\n\n\t\tremoveAllViews();\n\n\t\tmRoot = inflateLayout();\n\t\tmWindow.setContentView(mRoot);\n\t\tmWindow.setWidth(android.view.ViewGroup.LayoutParams.MATCH_PARENT);\n\t\tmWindow.setHeight(android.view.ViewGroup.LayoutParams.MATCH_PARENT);\n\n\t\tfindViewItems(mRoot);\n\t\tshowSystemUi(false);\n\t\tif (DeviceUtils.hasHoneycomb()) {\n\t\t\tmRoot.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {\n\t\t\t\t@Override\n        public void onSystemUiVisibilityChange(int visibility) {\n\t\t\t\t\tif ((visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) {\n\t\t\t\t\t\tmHandler.sendEmptyMessageDelayed(MSG_HIDE_SYSTEM_UI, DEFAULT_TIME_OUT);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate View inflateLayout() {\n\t\treturn ((LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.mediacontroller, this);\n\t}\n\n\tprivate void findViewItems(View v) {\n\t\tmMediaController = v.findViewById(R.id.mediacontroller);\n\n\t\tmSystemInfoLayout = v.findViewById(R.id.info_panel);\n\n\t\tmEndTime = (TextView) v.findViewById(R.id.mediacontroller_time_total);\n\t\tmCurrentTime = (TextView) v.findViewById(R.id.mediacontroller_time_current);\n\n\t\tmMenu = v.findViewById(R.id.video_menu);\n\t\tmMenu.setOnClickListener(mMenuListener);\n\t\tFractionalTouchDelegate.setupDelegate(mSystemInfoLayout, mMenu, new RectF(1.0f, 1f, 1.2f, 1.2f));\n\n\t\tmFileName = (TextView) v.findViewById(R.id.mediacontroller_file_name);\n\t\tmDateTime = (TextView) v.findViewById(R.id.date_time);\n\t\tmDownloadRate = (TextView) v.findViewById(R.id.download_rate);\n\t\tmBatteryLevel = (TextView) v.findViewById(R.id.battery_level);\n\n\t\tmControlsLayout = v.findViewById(R.id.mediacontroller_controls);\n\t\tmControlsButtons = v.findViewById(R.id.mediacontroller_controls_buttons);\n\n\t\tmOperationInfo = (TextView) v.findViewById(R.id.operation_info);\n\t\tmOperationVolLum = v.findViewById(R.id.operation_volume_brightness);\n\t\tmVolLumBg = (ImageView) v.findViewById(R.id.operation_bg);\n\t\tmVolLumNum = (ImageView) v.findViewById(R.id.operation_percent);\n\n\t\tmLock = (ImageButton) v.findViewById(R.id.mediacontroller_lock);\n\t\tmLock.setOnClickListener(mLockClickListener);\n\t\tFractionalTouchDelegate.setupDelegate(mSystemInfoLayout, mLock, new RectF(1.0f, 1f, 1.2f, 1.2f));\n\n\t\tmScreenToggle = (ImageButton) v.findViewById(R.id.mediacontroller_screen_size);\n\t\tmScreenToggle.setOnClickListener(mScreenToggleListener);\n\n\t\tmSnapshot = (ImageButton) v.findViewById(R.id.mediacontroller_snapshot);\n\t\tmSnapshot.setOnClickListener(mSnapshotListener);\n\n\t\tmPauseButton = (ImageButton) v.findViewById(R.id.mediacontroller_play_pause);\n\t\tmPauseButton.setOnClickListener(mPauseListener);\n\n\t\tmProgress = (SeekBar) v.findViewById(R.id.mediacontroller_seekbar);\n\t\tmProgress.setOnSeekBarChangeListener(mSeekListener);\n\t\tmProgress.setMax(DEFAULT_SEEKBAR_VALUE);\n\t}\n\n\tpublic void setAnchorView(View view) {\n\t\tmAnchor = view;\n\t\tint[] location = new int[2];\n\t\tmAnchor.getLocationOnScreen(location);\n\t\tRect anchorRect = new Rect(location[0], location[1], location[0] + mAnchor.getWidth(), location[1] + mAnchor.getHeight());\n\t\tsetWindowLayoutType();\n\t\tmWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, anchorRect.left, anchorRect.bottom);\n\t}\n\n\tpublic void release() {\n\t\tif (mWindow != null) {\n\t\t\tmWindow.dismiss();\n\t\t\tmWindow = null;\n\t\t}\n\t}\n\n\tprivate View.OnClickListener mMenuListener = new View.OnClickListener() {\n\t\t@Override\n\t\tpublic void onClick(View v) {\n\t\t\tmPlayer.showMenu();\n\t\t}\n\t};\n\n\tprivate void setOperationInfo(String info, long time) {\n\t\tmOperationInfo.setText(info);\n\t\tmOperationInfo.setVisibility(View.VISIBLE);\n\t\tmHandler.removeMessages(MSG_HIDE_OPERATION_INFO);\n\t\tmHandler.sendEmptyMessageDelayed(MSG_HIDE_OPERATION_INFO, time);\n\t}\n\n\tprivate void setBrightnessScale(float scale) {\n\t\tsetGraphicOperationProgress(R.drawable.video_brightness_bg, scale);\n\t}\n\n\tprivate void setVolumeScale(float scale) {\n\t\tsetGraphicOperationProgress(R.drawable.video_volumn_bg, scale);\n\t}\n\n\tprivate void setGraphicOperationProgress(int bgID, float scale) {\n\t\tmVolLumBg.setImageResource(bgID);\n\t\tmOperationInfo.setVisibility(View.GONE);\n\t\tmOperationVolLum.setVisibility(View.VISIBLE);\n\t\tViewGroup.LayoutParams lp = mVolLumNum.getLayoutParams();\n\t\tlp.width = (int) (findViewById(R.id.operation_full).getLayoutParams().width * scale);\n\t\tmVolLumNum.setLayoutParams(lp);\n\t}\n\n\tpublic void setFileName(String name) {\n\t\tmFileName.setText(name);\n\t}\n\n\tpublic void setDownloadRate(String rate) {\n\t\tmDownloadRate.setVisibility(View.VISIBLE);\n\t\tmDownloadRate.setText(rate);\n\t}\n\n\tpublic void setBatteryLevel(String level) {\n\t\tmBatteryLevel.setVisibility(View.VISIBLE);\n\t\tmBatteryLevel.setText(level);\n\t}\n\n\tpublic void setMediaPlayer(MediaPlayerControl player) {\n\t\tmPlayer = player;\n\t\tupdatePausePlay();\n\t}\n\n\tpublic void show() {\n\t\tshow(DEFAULT_TIME_OUT);\n\t}\n\n\tpublic void show(int timeout) {\n\t\tif (timeout != 0) {\n\t\t\tmHandler.removeMessages(MSG_FADE_OUT);\n\t\t\tmHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_FADE_OUT), timeout);\n\t\t}\n\t\tif (!mShowing) {\n\t\t\tshowButtons(true);\n\t\t\tmHandler.removeMessages(MSG_HIDE_SYSTEM_UI);\n\t\t\tshowSystemUi(true);\n\n\t\t\tmPauseButton.requestFocus();\n\n\t\t\tmControlsLayout.startAnimation(mAnimSlideInTop);\n\t\t\tmSystemInfoLayout.startAnimation(mAnimSlideInBottom);\n\t\t\tmMediaController.setVisibility(View.VISIBLE);\n\n\t\t\tupdatePausePlay();\n\t\t\tmHandler.sendEmptyMessage(MSG_TIME_TICK);\n\t\t\tmHandler.sendEmptyMessage(MSG_SHOW_PROGRESS);\n\n\t\t\tmShowing = true;\n\t\t}\n\t}\n\n\tpublic void hide() {\n\t\tif (mShowing) {\n\t\t\ttry {\n\t\t\t\tmHandler.removeMessages(MSG_TIME_TICK);\n\t\t\t\tmHandler.removeMessages(MSG_SHOW_PROGRESS);\n\t\t\t\tmControlsLayout.startAnimation(mAnimSlideOutTop);\n\t\t\t\tmSystemInfoLayout.startAnimation(mAnimSlideOutBottom);\n\t\t\t} catch (IllegalArgumentException ex) {\n\t\t\t\tLogger.d(\"MediaController already removed\");\n\t\t\t}\n\t\t\tmShowing = false;\n\t\t}\n\t}\n\n\tprivate void toggleVideoMode(boolean larger, boolean recycle) {\n\t\tif (larger) {\n\t\t\tif (mVideoMode < VideoView.VIDEO_LAYOUT_ZOOM)\n\t\t\t\tmVideoMode++;\n\t\t\telse if (recycle)\n\t\t\t\tmVideoMode = VideoView.VIDEO_LAYOUT_ORIGIN;\n\t\t} else {\n\t\t\tif (mVideoMode > VideoView.VIDEO_LAYOUT_ORIGIN)\n\t\t\t\tmVideoMode--;\n\t\t\telse if (recycle)\n\t\t\t\tmVideoMode = VideoView.VIDEO_LAYOUT_ZOOM;\n\t\t}\n\n\t\tswitch (mVideoMode) {\n\t\tcase VideoView.VIDEO_LAYOUT_ORIGIN:\n\t\t\tsetOperationInfo(mContext.getString(R.string.video_original), 500);\n\t\t\tmScreenToggle.setImageResource(R.drawable.mediacontroller_sreen_size_100);\n\t\t\tbreak;\n\t\tcase VideoView.VIDEO_LAYOUT_SCALE:\n\t\t\tsetOperationInfo(mContext.getString(R.string.video_fit_screen), 500);\n\t\t\tmScreenToggle.setImageResource(R.drawable.mediacontroller_screen_fit);\n\t\t\tbreak;\n\t\tcase VideoView.VIDEO_LAYOUT_STRETCH:\n\t\t\tsetOperationInfo(mContext.getString(R.string.video_stretch), 500);\n\t\t\tmScreenToggle.setImageResource(R.drawable.mediacontroller_screen_size);\n\t\t\tbreak;\n\t\tcase VideoView.VIDEO_LAYOUT_ZOOM:\n\t\t\tsetOperationInfo(mContext.getString(R.string.video_crop), 500);\n\t\t\tmScreenToggle.setImageResource(R.drawable.mediacontroller_sreen_size_crop);\n\t\t\tbreak;\n\t\t}\n\n\t\tmPlayer.toggleVideoMode(mVideoMode);\n\t}\n\n\tprivate void lock(boolean toLock) {\n\t\tif (toLock) {\n\t\t\tmLock.setImageResource(R.drawable.mediacontroller_lock);\n\t\t\tmMenu.setVisibility(View.GONE);\n\t\t\tmControlsButtons.setVisibility(View.GONE);\n\t\t\tmProgress.setEnabled(false);\n\t\t\tif (mScreenLocked != toLock)\n\t\t\t\tsetOperationInfo(mContext.getString(R.string.video_screen_locked), 1000);\n\t\t} else {\n\t\t\tmLock.setImageResource(R.drawable.mediacontroller_unlock);\n\t\t\t// If you wanna to show, set mMenu visible\n\t\t\tmMenu.setVisibility(View.GONE);\n\t\t\tmControlsButtons.setVisibility(View.VISIBLE);\n\t\t\tmProgress.setEnabled(true);\n\t\t\tif (mScreenLocked != toLock)\n\t\t\t\tsetOperationInfo(mContext.getString(R.string.video_screen_unlocked), 1000);\n\t\t}\n\t\tmScreenLocked = toLock;\n\t\tmGestures.setTouchListener(mTouchListener, !mScreenLocked);\n\t}\n\n\tpublic boolean isLocked() {\n\t\treturn mScreenLocked;\n\t}\n\n\tprivate static final int MSG_FADE_OUT = 1;\n\tprivate static final int MSG_SHOW_PROGRESS = 2;\n\tprivate static final int MSG_HIDE_SYSTEM_UI = 3;\n\tprivate static final int MSG_TIME_TICK = 4;\n\tprivate static final int MSG_HIDE_OPERATION_INFO = 5;\n\tprivate static final int MSG_HIDE_OPERATION_VOLLUM = 6;\n\n\tprivate static class MHandler extends Handler {\n\t\tprivate WeakReference<MediaController> mc;\n\n\t\tpublic MHandler(MediaController mc) {\n\t\t\tthis.mc = new WeakReference<MediaController>(mc);\n\t\t}\n\n\t\t@Override\n\t\tpublic void handleMessage(Message msg) {\n\t\t\tMediaController c = mc.get();\n\t\t\tif (c == null)\n\t\t\t\treturn;\n\n\t\t\tswitch (msg.what) {\n\t\t\tcase MSG_FADE_OUT:\n\t\t\t\tc.hide();\n\t\t\t\tbreak;\n\t\t\tcase MSG_SHOW_PROGRESS:\n\t\t\t\tlong pos = c.setProgress();\n\t\t\t\tif (!c.mDragging && c.mShowing) {\n\t\t\t\t\tmsg = obtainMessage(MSG_SHOW_PROGRESS);\n\t\t\t\t\tsendMessageDelayed(msg, 1000 - (pos % 1000));\n\t\t\t\t\tc.updatePausePlay();\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase MSG_HIDE_SYSTEM_UI:\n\t\t\t\tif (!c.mShowing)\n\t\t\t\t\tc.showSystemUi(false);\n\t\t\t\tbreak;\n\t\t\tcase MSG_TIME_TICK:\n\t\t\t\tc.mDateTime.setText(StringUtils.currentTimeString());\n\t\t\t\tsendEmptyMessageDelayed(MSG_TIME_TICK, TIME_TICK_INTERVAL);\n\t\t\t\tbreak;\n\t\t\tcase MSG_HIDE_OPERATION_INFO:\n\t\t\t\tc.mOperationInfo.setVisibility(View.GONE);\n\t\t\t\tbreak;\n\t\t\tcase MSG_HIDE_OPERATION_VOLLUM:\n\t\t\t\tc.mOperationVolLum.setVisibility(View.GONE);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t};\n\n\tprivate long setProgress() {\n\t\tif (mPlayer == null || mDragging)\n\t\t\treturn 0;\n\n\t\tlong position = mPlayer.getCurrentPosition();\n\t\tlong duration = mPlayer.getDuration();\n\t\tif (duration > 0) {\n\t\t\tlong pos = 1000L * position / duration;\n\t\t\tmProgress.setProgress((int) pos);\n\t\t}\n\t\tint percent = mPlayer.getBufferPercentage();\n\t\tmProgress.setSecondaryProgress(percent * 10);\n\n\t\tmDuration = duration;\n\n\t\tmEndTime.setText(StringUtils.generateTime(mDuration));\n\t\tmCurrentTime.setText(StringUtils.generateTime(position));\n\n\t\treturn position;\n\t}\n\n\t@Override\n\tpublic boolean onTouchEvent(MotionEvent event) {\n\t\tmHandler.removeMessages(MSG_HIDE_SYSTEM_UI);\n\t\tmHandler.sendEmptyMessageDelayed(MSG_HIDE_SYSTEM_UI, DEFAULT_TIME_OUT);\n\t\treturn mGestures.onTouchEvent(event) || super.onTouchEvent(event);\n\t}\n\n\tprivate TouchListener mTouchListener = new TouchListener() {\n\t\t@Override\n\t\tpublic void onGestureBegin() {\n\t\t\tmBrightness = mContext.getWindow().getAttributes().screenBrightness;\n\t\t\tmVolume = mAM.getStreamVolume(AudioManager.STREAM_MUSIC);\n\t\t\tif (mBrightness <= 0.00f)\n\t\t\t\tmBrightness = 0.50f;\n\t\t\tif (mBrightness < 0.01f)\n\t\t\t\tmBrightness = 0.01f;\n\t\t\tif (mVolume < 0)\n\t\t\t\tmVolume = 0;\n\t\t}\n\n\t\t@Override\n\t\tpublic void onGestureEnd() {\n\t\t\tmOperationVolLum.setVisibility(View.GONE);\n\t\t}\n\n\t\t@Override\n\t\tpublic void onLeftSlide(float percent) {\n\t\t\tsetBrightness(mBrightness + percent);\n\t\t\tsetBrightnessScale(mContext.getWindow().getAttributes().screenBrightness);\n\t\t}\n\n\t\t@Override\n\t\tpublic void onRightSlide(float percent) {\n\t\t\tint v = (int) (percent * mMaxVolume) + mVolume;\n\t\t\tsetVolume(v);\n\t\t}\n\n\t\t@Override\n\t\tpublic void onSingleTap() {\n\t\t\tif (mShowing)\n\t\t\t\thide();\n\t\t\telse\n\t\t\t\tshow();\n\t\t\tif (mPlayer.getBufferPercentage() >= 100)\n\t\t\t\tmPlayer.removeLoadingView();\n\t\t}\n\n\t\t@Override\n\t\tpublic void onDoubleTap() {\n\t\t\ttoggleVideoMode(true, true);\n\t\t}\n\n\t\t@Override\n\t\tpublic void onLongPress() {\n\t\t\tdoPauseResume();\n\t\t}\n\n\t\t@Override\n\t\tpublic void onScale(float scaleFactor, int state) {\n\t\t\tswitch (state) {\n\t\t\tcase CommonGestures.SCALE_STATE_BEGIN:\n\t\t\t\tmVideoMode = VideoView.VIDEO_LAYOUT_SCALE_ZOOM;\n\t\t\t\tmScreenToggle.setImageResource(R.drawable.mediacontroller_sreen_size_100);\n\t\t\t\tmPlayer.toggleVideoMode(mVideoMode);\n\t\t\t\tbreak;\n\t\t\tcase CommonGestures.SCALE_STATE_SCALEING:\n\t\t\t\tfloat currentRatio = mPlayer.scale(scaleFactor);\n\t\t\t\tsetOperationInfo((int) (currentRatio * 100) + \"%\", 500);\n\t\t\t\tbreak;\n\t\t\tcase CommonGestures.SCALE_STATE_END:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t};\n\n\tprivate void setVolume(int v) {\n\t\tif (v > mMaxVolume)\n\t\t\tv = mMaxVolume;\n\t\telse if (v < 0)\n\t\t\tv = 0;\n\t\tmAM.setStreamVolume(AudioManager.STREAM_MUSIC, v, 0);\n\t\tsetVolumeScale((float) v / mMaxVolume);\n\t}\n\n\tprivate void setBrightness(float f) {\n\t\tWindowManager.LayoutParams lp = mContext.getWindow().getAttributes();\n\t\tlp.screenBrightness = f;\n\t\tif (lp.screenBrightness > 1.0f)\n\t\t\tlp.screenBrightness = 1.0f;\n\t\telse if (lp.screenBrightness < 0.01f)\n\t\t\tlp.screenBrightness = 0.01f;\n\t\tmContext.getWindow().setAttributes(lp);\n\t}\n\n\t@Override\n\tpublic boolean onTrackballEvent(MotionEvent ev) {\n\t\tshow(DEFAULT_TIME_OUT);\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean dispatchKeyEvent(KeyEvent event) {\n\t\tint keyCode = event.getKeyCode();\n\n\t\tswitch (keyCode) {\n\t\tcase KeyEvent.KEYCODE_VOLUME_MUTE:\n\t\t\treturn super.dispatchKeyEvent(event);\n\t\tcase KeyEvent.KEYCODE_VOLUME_UP:\n\t\tcase KeyEvent.KEYCODE_VOLUME_DOWN:\n\t\t\tmVolume = mAM.getStreamVolume(AudioManager.STREAM_MUSIC);\n\t\t\tint step = keyCode == KeyEvent.KEYCODE_VOLUME_UP ? 1 : -1;\n\t\t\tsetVolume(mVolume + step);\n\t\t\tmHandler.removeMessages(MSG_HIDE_OPERATION_VOLLUM);\n\t\t\tmHandler.sendEmptyMessageDelayed(MSG_HIDE_OPERATION_VOLLUM, 500);\n\t\t\treturn true;\n\t\t}\n\n\t\tif (isLocked()) {\n\t\t\tshow();\n\t\t\treturn true;\n\t\t}\n\n\t\tif (event.getRepeatCount() == 0 && (keyCode == KeyEvent.KEYCODE_HEADSETHOOK || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE || keyCode == KeyEvent.KEYCODE_SPACE)) {\n\t\t\tdoPauseResume();\n\t\t\tshow(DEFAULT_TIME_OUT);\n\t\t\treturn true;\n\t\t} else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP) {\n\t\t\tif (mPlayer.isPlaying()) {\n\t\t\t\tmPlayer.pause();\n\t\t\t\tupdatePausePlay();\n\t\t\t}\n\t\t\treturn true;\n\t\t} else if (keyCode == KeyEvent.KEYCODE_BACK) {\n\t\t\trelease();\n\t\t\tmPlayer.stop();\n\t\t\treturn true;\n\t\t} else {\n\t\t\tshow(DEFAULT_TIME_OUT);\n\t\t}\n\t\treturn super.dispatchKeyEvent(event);\n\t}\n\n\t@TargetApi(11)\n\tprivate void showSystemUi(boolean visible) {\n\t\tif (DeviceUtils.hasHoneycomb()) {\n\t\t\tint flag = visible ? 0 : View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LOW_PROFILE;\n\t\t\tmRoot.setSystemUiVisibility(flag);\n\t\t}\n\t}\n\n\tprivate void showButtons(boolean showButtons) {\n\t\tWindow window = mContext.getWindow();\n\t\tWindowManager.LayoutParams layoutParams = window.getAttributes();\n\t\tfloat val = showButtons ? -1 : 0;\n\t\ttry {\n\t\t\tField buttonBrightness = layoutParams.getClass().getField(\"buttonBrightness\");\n\t\t\tbuttonBrightness.set(layoutParams, val);\n\t\t} catch (Exception e) {\n\t\t\tLogger.e(\"dimButtons\", e);\n\t\t}\n\t\twindow.setAttributes(layoutParams);\n\t}\n\n\tprivate void updatePausePlay() {\n\t\tif (mPlayer.isPlaying())\n\t\t\tmPauseButton.setImageResource(R.drawable.mediacontroller_pause);\n\t\telse\n\t\t\tmPauseButton.setImageResource(R.drawable.mediacontroller_play);\n\t}\n\n\tprivate void doPauseResume() {\n\t\tif (mPlayer.isPlaying())\n\t\t\tmPlayer.pause();\n\t\telse\n\t\t\tmPlayer.start();\n\t\tupdatePausePlay();\n\t}\n\n\tprivate View.OnClickListener mPauseListener = new View.OnClickListener() {\n\t\t@Override\n\t\tpublic void onClick(View v) {\n\t\t\tif (mPlayer.isPlaying())\n\t\t\t\tshow(DEFAULT_LONG_TIME_SHOW);\n\t\t\telse\n\t\t\t\tshow();\n\t\t\tdoPauseResume();\n\t\t}\n\t};\n\n\tprivate View.OnClickListener mLockClickListener = new View.OnClickListener() {\n\t\t@Override\n\t\tpublic void onClick(View v) {\n\t\t\thide();\n\t\t\tlock(!mScreenLocked);\n\t\t\tshow();\n\t\t}\n\t};\n\n\tprivate View.OnClickListener mScreenToggleListener = new View.OnClickListener() {\n\t\t@Override\n\t\tpublic void onClick(View v) {\n\t\t\tshow(DEFAULT_TIME_OUT);\n\t\t\ttoggleVideoMode(true, true);\n\t\t}\n\t};\n\n\tprivate View.OnClickListener mSnapshotListener = new View.OnClickListener() {\n\t\t@Override\n\t\tpublic void onClick(View v) {\n\t\t\tshow(DEFAULT_TIME_OUT);\n\t\t\tmSnapshot.setEnabled(false);\n\t\t\tmPlayer.snapshot();\n\t\t\tmSnapshot.setEnabled(true);\n\t\t}\n\t};\n\n\tprivate OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {\n\t\tprivate boolean wasStopped = false;\n\n\t\t@Override\n\t\tpublic void onStartTrackingTouch(SeekBar bar) {\n\t\t\tmDragging = true;\n\t\t\tshow(3600000);\n\t\t\tmHandler.removeMessages(MSG_SHOW_PROGRESS);\n\t\t\twasStopped = !mPlayer.isPlaying();\n\t\t\tif (mInstantSeeking) {\n\t\t\t\tmAM.setStreamMute(AudioManager.STREAM_MUSIC, true);\n\t\t\t\tif (wasStopped) {\n\t\t\t\t\tmPlayer.start();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t@Override\n\t\tpublic void onProgressChanged(SeekBar bar, int progress, boolean fromuser) {\n\t\t\tif (!fromuser)\n\t\t\t\treturn;\n\n\t\t\tlong newposition = (mDuration * progress) / 1000;\n\t\t\tString time = StringUtils.generateTime(newposition);\n\t\t\tif (mInstantSeeking)\n\t\t\t\tmPlayer.seekTo(newposition);\n\t\t\tsetOperationInfo(time, 1500);\n\t\t\tmCurrentTime.setText(time);\n\t\t}\n\n\t\t@Override\n\t\tpublic void onStopTrackingTouch(SeekBar bar) {\n\t\t\tif (!mInstantSeeking) {\n\t\t\t\tmPlayer.seekTo((mDuration * bar.getProgress()) / 1000);\n\t\t\t} else if (wasStopped) {\n\t\t\t\tmPlayer.pause();\n\t\t\t}\n\t\t\tmOperationInfo.setVisibility(View.GONE);\n\t\t\tshow(DEFAULT_TIME_OUT);\n\t\t\tmHandler.removeMessages(MSG_SHOW_PROGRESS);\n\t\t\tmAM.setStreamMute(AudioManager.STREAM_MUSIC, false);\n\t\t\tmDragging = false;\n\t\t\tmHandler.sendEmptyMessageDelayed(MSG_SHOW_PROGRESS, 1000);\n\t\t}\n\t};\n\n\tpublic interface MediaPlayerControl {\n\t\tvoid start();\n\n\t\tvoid pause();\n\n\t\tvoid stop();\n\n\t\tvoid seekTo(long pos);\n\n\t\tboolean isPlaying();\n\n\t\tlong getDuration();\n\n\t\tlong getCurrentPosition();\n\n\t\tint getBufferPercentage();\n\n\t\tvoid previous();\n\n\t\tvoid next();\n\n\t\tlong goForward();\n\n\t\tlong goBack();\n\n\t\tvoid toggleVideoMode(int mode);\n\n\t\tvoid showMenu();\n\n\t\tvoid removeLoadingView();\n\n\t\tfloat scale(float scale);\n\n\t\tvoid snapshot();\n\t}\n\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/player/PlayerService.java",
    "content": "/*\n * Copyright (C) 2012 YIXIA.COM\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.nmbb.oplayer.ui.player;\n\nimport io.vov.vitamio.MediaPlayer;\nimport io.vov.vitamio.MediaPlayer.OnBufferingUpdateListener;\nimport io.vov.vitamio.MediaPlayer.OnCompletionListener;\nimport io.vov.vitamio.MediaPlayer.OnErrorListener;\nimport io.vov.vitamio.MediaPlayer.OnHWRenderFailedListener;\nimport io.vov.vitamio.MediaPlayer.OnInfoListener;\nimport io.vov.vitamio.MediaPlayer.OnPreparedListener;\nimport io.vov.vitamio.MediaPlayer.OnSeekCompleteListener;\nimport io.vov.vitamio.MediaPlayer.OnTimedTextListener;\nimport io.vov.vitamio.MediaPlayer.OnVideoSizeChangedListener;\nimport io.vov.vitamio.Vitamio;\nimport io.vov.vitamio.utils.Log;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\n\nimport android.app.Service;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.graphics.Bitmap;\nimport android.net.Uri;\nimport android.os.Binder;\nimport android.os.IBinder;\nimport android.telephony.PhoneStateListener;\nimport android.telephony.TelephonyManager;\nimport android.view.SurfaceHolder;\n\nimport com.nmbb.oplayer.exception.Logger;\nimport com.nmbb.oplayer.util.FileUtils;\n\npublic class PlayerService extends Service implements\n\t\tOnBufferingUpdateListener, OnCompletionListener, OnPreparedListener,\n\t\tOnVideoSizeChangedListener, OnErrorListener, OnInfoListener,\n\t\tOnSeekCompleteListener, OnTimedTextListener {\n\tprivate MediaPlayer mPlayer;\n\tprivate VPlayerListener mListener;\n\tprivate Uri mUri;\n\tprivate Uri mOldUri;\n\tprivate float mSeekTo = -1f;\n\tprivate boolean mFromNotification;\n\tprivate String[] mSubPaths;\n\tprivate boolean mInitialized;\n\tprivate final IBinder mBinder = new LocalBinder();\n\tprivate TelephonyManager mTelephonyManager;\n\tprivate int mCurrentState;\n\tprivate SurfaceHolder mSurfaceHolder;\n\tpublic static final int VPLYAER_NOTIFICATION_ID = 1;\n\n\tpublic static final int STATE_PREPARED = -1;\n\tpublic static final int STATE_PLAYING = 0;\n\tpublic static final int STATE_NEED_RESUME = 1;\n\tpublic static final int STATE_STOPPED = 2;\n\tpublic static final int STATE_RINGING = 3;\n\n\tprivate int mLastAudioTrack = -1;\n\tprivate String mLastSubTrack;\n\tprivate int mLastSubTrackId = -1;\n\tprivate long mMediaId = -1l;\n\n\tpublic class LocalBinder extends Binder {\n\t\tpublic PlayerService getService() {\n\t\t\treturn PlayerService.this;\n\t\t}\n\t}\n\n\t@Override\n\tpublic void onCreate() {\n\t\tsuper.onCreate();\n\t\tmInitialized = false;\n\t\tmTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);\n\t\tmTelephonyManager.listen(mPhoneListener,\n\t\t\t\tPhoneStateListener.LISTEN_CALL_STATE);\n\n\t}\n\n\t@Override\n\tpublic int onStartCommand(Intent intent, int flags, int startId) {\n\t\tif (Vitamio.isInitialized(this)) {\n\t\t\tvplayerInit(intent.getBooleanExtra(\"isHWCodec\", false));\n\t\t} else {\n\t\t\tstopSelf();\n\t\t}\n\t\tLog.d(\"CREATE OK\");\n\t\treturn super.onStartCommand(intent, flags, startId);\n\t}\n\n\tprivate void vplayerInit(boolean isHWCodec) {\n\t\tmPlayer = new MediaPlayer(PlayerService.this.getApplicationContext(),\n\t\t\t\tisHWCodec);\n\t\tmPlayer.setOnHWRenderFailedListener(new OnHWRenderFailedListener() {\n\t\t\t@Override\n\t\t\tpublic void onFailed() {\n\t\t\t\tif (mListener != null)\n\t\t\t\t\tmListener.onHWRenderFailed();\n\t\t\t}\n\t\t});\n\t\tmPlayer.setOnBufferingUpdateListener(PlayerService.this);\n\t\tmPlayer.setOnCompletionListener(PlayerService.this);\n\t\tmPlayer.setOnPreparedListener(PlayerService.this);\n\t\tmPlayer.setOnVideoSizeChangedListener(PlayerService.this);\n\t\tmPlayer.setOnErrorListener(PlayerService.this);\n\t\tmPlayer.setOnInfoListener(PlayerService.this);\n\t}\n\n\tpublic void releaseContext() {\n\t\tif (mPlayer != null)\n\t\t\tmPlayer.release();\n\t\tmPlayer = null;\n\t}\n\n\t@Override\n\tpublic IBinder onBind(Intent intent) {\n\t\tLog.d(\"BIND OK : \" + intent.getPackage());\n\t\treturn mBinder;\n\t}\n\n\t@Override\n\tpublic void onDestroy() {\n\t\tsuper.onDestroy();\n\t\trelease(true);\n\t\treleaseContext();\n\t}\n\n\tpublic boolean isInitialized() {\n\t\treturn mInitialized;\n\t}\n\n\tprivate String mTitle;\n\n\tpublic boolean initialize(Uri filePath, String displayName,\n\t\t\tboolean saveUri, float startPos, VPlayerListener listener,\n\t\t\tint parentId, boolean isHWCodec) {\n\t\tif (mPlayer == null)\n\t\t\tvplayerInit(isHWCodec);\n\t\tmTitle = displayName;\n\t\tmListener = listener;\n\t\tmOldUri = mUri;\n\t\tmUri = filePath;\n\t\tmSeekTo = startPos;\n\t\tmMediaId = -1;\n\t\tmLastAudioTrack = -1;\n\t\tmLastSubTrackId = -1;\n\t\tmLastSubTrack = \"\";\n\t\tsetMediaTrack();\n\t\tLog.i(\"%s ==> %s, %s, %s, %s\", mOldUri, mUri, mInitialized, mPrepared,\n\t\t\t\tmVideoSizeKnown);\n\t\tmFromNotification = mInitialized && mUri != null\n\t\t\t\t&& mUri.equals(mOldUri);\n\t\tmListener.onOpenStart();\n\t\tif (!mFromNotification)\n\t\t\topenVideo();\n\t\telse\n\t\t\topenSuccess();\n\t\treturn mInitialized;\n\t}\n\n\tprivate void setMediaTrack() {\n\t}\n\n\tprivate void openVideo() {\n\t\tif (mUri == null || mPlayer == null)\n\t\t\treturn;\n\n\t\tmPlayer.reset();\n\t\tmInitialized = false;\n\t\tmPrepared = false;\n\t\tmVideoSizeKnown = false;\n\n\t\ttry {\n\t\t\tmPlayer.setScreenOnWhilePlaying(true);\n\t\t\tmPlayer.setDataSource(PlayerService.this, mUri);\n\t\t\t// if (mLastAudioTrack != -1)\n\t\t\t// mPlayer.setInitialAudioTrack(mLastAudioTrack);\n\t\t\t// if (mLastSubTrackId != -1)\n\t\t\t// mPlayer.setInitialSubTrack(mLastSubTrackId);\n\t\t\tif (mSurfaceHolder != null && mSurfaceHolder.getSurface() != null\n\t\t\t\t\t&& mSurfaceHolder.getSurface().isValid())\n\t\t\t\tmPlayer.setDisplay(mSurfaceHolder);\n\t\t\tmPlayer.prepareAsync();\n\t\t} catch (IllegalArgumentException e) {\n\t\t\tLogger.e(\"openVideo\", e);\n\t\t} catch (IllegalStateException e) {\n\t\t\tLogger.e(\"openVideo\", e);\n\t\t} catch (IOException e) {\n\t\t\tLogger.e(\"openVideo\", e);\n\t\t}\n\t}\n\n\tpublic Uri getUri() {\n\t\treturn mUri;\n\t}\n\n\tpublic long getMediaId() {\n\t\treturn mMediaId;\n\t}\n\n\tpublic int getLastAudioTrack() {\n\t\treturn mLastAudioTrack;\n\t}\n\n\tpublic String getLastSubTrack() {\n\t\treturn mLastSubTrack;\n\t}\n\n\tpublic int getLastSubTrackId() {\n\t\treturn mLastSubTrackId;\n\t}\n\n\tpublic void setVPlayerListener(VPlayerListener listener) {\n\t\tmListener = listener;\n\t}\n\n\tpublic void setState(int state) {\n\t\tmCurrentState = state;\n\t}\n\n\tpublic boolean needResume() {\n\t\treturn mInitialized\n\t\t\t\t&& (mCurrentState == STATE_NEED_RESUME || mCurrentState == STATE_PREPARED);\n\t}\n\n\tpublic boolean ringingState() {\n\t\treturn mInitialized && mCurrentState == STATE_RINGING;\n\t}\n\n\tpublic void release() {\n\t\trelease(true);\n\t}\n\n\tprivate void release(boolean all) {\n\t\tif (mPlayer != null) {\n\t\t\tif (mListener != null)\n\t\t\t\tmListener.onCloseStart();\n\t\t\tmPlayer.reset();\n\t\t\tmInitialized = false;\n\t\t\tmPrepared = false;\n\t\t\tmVideoSizeKnown = false;\n\t\t\tif (mListener != null)\n\t\t\t\tmListener.onCloseComplete();\n\t\t}\n\t\tif (all) {\n\t\t\tmListener = null;\n\t\t\tmUri = null;\n\t\t}\n\t}\n\n\tpublic void stop() {\n\t\tif (mInitialized) {\n\t\t\tmPlayer.pause();\n\t\t}\n\t}\n\n\tpublic void start() {\n\t\tif (mInitialized) {\n\t\t\tmPlayer.start();\n\t\t\tsetState(STATE_PLAYING);\n\t\t}\n\t}\n\n\tpublic void setDisplay(SurfaceHolder surface) {\n\t\tmSurfaceHolder = surface;\n\t\tif (mPlayer != null)\n\t\t\tmPlayer.setDisplay(surface);\n\t}\n\n\tpublic void releaseSurface() {\n\t\tif (mInitialized)\n\t\t\tmPlayer.releaseDisplay();\n\t}\n\n\tpublic boolean isPlaying() {\n\t\treturn (mInitialized && mPlayer.isPlaying());\n\t}\n\n\tpublic int getVideoWidth() {\n\t\tif (mInitialized)\n\t\t\treturn mPlayer.getVideoWidth();\n\t\treturn 0;\n\t}\n\n\tpublic int getVideoHeight() {\n\t\tif (mInitialized)\n\t\t\treturn mPlayer.getVideoHeight();\n\t\treturn 0;\n\t}\n\n\tpublic float getVideoAspectRatio() {\n\t\tif (mInitialized)\n\t\t\treturn mPlayer.getVideoAspectRatio();\n\t\treturn 0f;\n\t}\n\n\tpublic long getDuration() {\n\t\tif (mInitialized)\n\t\t\treturn mPlayer.getDuration();\n\t\treturn 0;\n\t}\n\n\tpublic long getCurrentPosition() {\n\t\tif (mInitialized)\n\t\t\treturn mPlayer.getCurrentPosition();\n\t\treturn 0;\n\t}\n\n\tpublic Bitmap getCurrentFrame() {\n\t\tif (mInitialized)\n\t\t\treturn mPlayer.getCurrentFrame();\n\t\treturn null;\n\t}\n\n\tpublic float getBufferProgress() {\n\t\tif (mInitialized)\n\t\t\treturn mPlayer.getBufferProgress();\n\t\treturn 0f;\n\t}\n\n\tpublic void seekTo(float percent) {\n\t\tif (mInitialized)\n\t\t\tmPlayer.seekTo((int) (percent * getDuration()));\n\t}\n\n\tpublic String getMetaEncoding() {\n\t\tif (mInitialized)\n\t\t\treturn mPlayer.getMetaEncoding();\n\t\treturn null;\n\t}\n\n\tpublic void setAudioTrack(int num) {\n\t\tif (mInitialized)\n\t\t\tmPlayer.selectTrack(num);\n\t\t// mPlayer.setAudioTrack(num);\n\t}\n\n\tpublic int getAudioTrack() {\n\t\tif (mInitialized)\n\t\t\treturn mPlayer.getAudioTrack();\n\t\treturn 0;\n\t}\n\n\t// public HashMap<String, Integer> getAudioTrackMap() {\n\t// if (!mInitialized)\n\t// return null;\n\t// String enc = VP.DEFAULT_META_ENCODING;\n\t// return mPlayer.getAudioTrackMap(enc.equals(VP.DEFAULT_META_ENCODING) ?\n\t// getMetaEncoding() : enc);\n\t// }\n\t//\n\t// public HashMap<String, Object> getSubTrackMap() {\n\t// if (!mInitialized)\n\t// return null;\n\t// String enc = VP.DEFAULT_SUB_ENCODING;\n\t// HashMap<String, Object> trackMap = new HashMap<String, Object>();\n\t// HashMap<String, Integer> m =\n\t// mPlayer.getSubTrackMap(enc.equals(VP.DEFAULT_SUB_ENCODING) ?\n\t// getMetaEncoding() : enc);\n\t// if (m != null)\n\t// for (String k : m.keySet())\n\t// trackMap.put(k, m.get(k));\n\t//\n\t// if (mSubPaths != null)\n\t// for (String s : mSubPaths)\n\t// trackMap.put(new File(s).getName(), s);\n\t//\n\t// return trackMap;\n\t// }\n\t//\n\t// public int getSubTrack() {\n\t// if (mInitialized)\n\t// return mPlayer.getSubTrack();\n\t// return 0;\n\t// }\n\t//\n\t// public void setSubTrack(int id) {\n\t// if (mInitialized)\n\t// mPlayer.setSubTrack(id);\n\t// }\n\t//\n\t// public String getSubPath() {\n\t// if (mInitialized)\n\t// return mPlayer.getSubPath();\n\t// return null;\n\t// }\n\n\tpublic void setSubShown(boolean shown) {\n\t\tif (mInitialized)\n\t\t\tmPlayer.setTimedTextShown(shown);// setSubtitleShown ->\n\t\t\t\t\t\t\t\t\t\t\t\t// setTimedTextShown 4.0\n\t}\n\n\tprotected boolean isBuffering() {\n\t\treturn (mInitialized && mPlayer.isBuffering());\n\t}\n\n\tprotected void setBuffer(int bufSize) {\n\t\tif (mInitialized)\n\t\t\tmPlayer.setBufferSize(bufSize);\n\t}\n\n\tprotected void setVolume(float left, float right) {\n\t\tif (mInitialized) {\n\t\t\tif (left <= 0f)\n\t\t\t\tleft = 0f;\n\t\t\telse if (left >= 1f)\n\t\t\t\tleft = 1f;\n\t\t\tif (right <= 0f)\n\t\t\t\tright = 0f;\n\t\t\telse if (right >= 1f)\n\t\t\t\tright = 1f;\n\t\t\tmPlayer.setVolume(left, right);\n\t\t}\n\t}\n\n\tprotected void setVideoQuality(int quality) {\n\t\tif (mInitialized)\n\t\t\tmPlayer.setVideoQuality(quality);\n\t}\n\n\tprotected void setDeinterlace(boolean deinterlace) {\n\t\tif (mInitialized)\n\t\t\tmPlayer.setDeinterlace(deinterlace);\n\t}\n\n\t// public int getSubLocation() {\n\t// if (mInitialized)\n\t// return mPlayer.getSubLocation();\n\t// return -1;\n\t// }\n\t//\n\tprotected void setSubEncoding(String encoding) {\n\t\tif (mInitialized) {\n\t\t\tString enc = encoding.equals(VP.DEFAULT_SUB_ENCODING) ? null\n\t\t\t\t\t: encoding;\n\t\t\tmPlayer.setTimedTextEncoding(enc);// setSubEncoding ->\n\t\t\t\t\t\t\t\t\t\t\t\t// setTimedTextEncoding\n\t\t}\n\t}\n\n\tpublic void setSubPath(String subPath) {\n\t\tif (mInitialized)\n\t\t\tmPlayer.addTimedTextSource(subPath);\n\t\t// mPlayer.setSubPath(subPath);\n\t}\n\n\tpublic static interface VPlayerListener {\n\t\tpublic void onHWRenderFailed();\n\n\t\tpublic void onVideoSizeChanged(int width, int height);\n\n\t\tpublic void onSubChanged(String text);\n\n\t\tpublic void onSubChanged(byte[] pixels, int width, int height);\n\n\t\tpublic void onOpenStart();\n\n\t\tpublic void onOpenSuccess();\n\n\t\tpublic void onOpenFailed();\n\n\t\tpublic void onBufferStart();\n\n\t\tpublic void onBufferComplete();\n\n\t\tpublic void onDownloadRateChanged(int kbPerSec);\n\n\t\tpublic void onPlaybackComplete();\n\n\t\tpublic void onCloseStart();\n\n\t\tpublic void onCloseComplete();\n\t}\n\n\tprivate PhoneStateListener mPhoneListener = new PhoneStateListener() {\n\t\t@Override\n\t\tpublic void onCallStateChanged(int state, String incomingNumber) {\n\t\t\tswitch (state) {\n\t\t\tcase TelephonyManager.CALL_STATE_IDLE:\n\t\t\t\tbreak;\n\t\t\tcase TelephonyManager.CALL_STATE_OFFHOOK:\n\t\t\tcase TelephonyManager.CALL_STATE_RINGING:\n\t\t\t\tif (isPlaying()) {\n\t\t\t\t\tstop();\n\t\t\t\t\tsetState(STATE_RINGING);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t};\n\n\tprivate boolean mVideoSizeKnown = false;\n\tprivate boolean mPrepared = false;\n\n\t@Override\n\tpublic void onVideoSizeChanged(MediaPlayer arg0, int arg1, int arg2) {\n\t\tmVideoSizeKnown = true;\n\t\tif (mListener != null)\n\t\t\tmListener.onVideoSizeChanged(arg1, arg2);\n\t}\n\n\t@Override\n\tpublic void onPrepared(MediaPlayer arg0) {\n\t\tmPrepared = true;\n\t\topenSuccess();\n\t}\n\n\tprivate void openSuccess() {\n\t\tmInitialized = true;\n\t\tif (!mFromNotification && mSeekTo > 0 && mSeekTo < 1)\n\t\t\tseekTo(mSeekTo);\n\t\tmSeekTo = -1;\n\t\tmListener.onOpenSuccess();\n\t\tif (!mFromNotification) {\n\t\t\tsetSubEncoding(VP.DEFAULT_SUB_ENCODING);\n\t\t\tif (mUri != null)\n\t\t\t\tmSubPaths = getSubFiles(mUri.getPath());\n\t\t\tif (mSubPaths != null)\n\t\t\t\tsetSubPath(FileUtils.getCanonical(new File(mSubPaths[0])));\n\t\t\tsetSubShown(VP.DEFAULT_SUB_SHOWN);\n\t\t}\n\t}\n\n\t@Override\n\tpublic void onCompletion(MediaPlayer arg0) {\n\t\tif (mListener != null) {\n\t\t\tmListener.onPlaybackComplete();\n\t\t} else {\n\t\t\trelease(true);\n\t\t}\n\t}\n\n\t@Override\n\tpublic void onBufferingUpdate(MediaPlayer arg0, int arg1) {\n\t}\n\n\t@Override\n\tpublic void onSeekComplete(MediaPlayer arg0) {\n\t}\n\n\t@Override\n\tpublic boolean onInfo(MediaPlayer arg0, int arg1, int arg2) {\n\t\tswitch (arg1) {\n\t\tcase MediaPlayer.MEDIA_INFO_BUFFERING_START:\n\t\t\tif (mListener != null)\n\t\t\t\tmListener.onBufferStart();\n\t\t\telse\n\t\t\t\tmPlayer.pause();\n\t\t\tbreak;\n\t\tcase MediaPlayer.MEDIA_INFO_BUFFERING_END:\n\t\t\tif (mListener != null)\n\t\t\t\tmListener.onBufferComplete();\n\t\t\telse\n\t\t\t\tmPlayer.start();\n\t\t\tbreak;\n\t\tcase MediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED:\n\t\t\tif (mListener != null)\n\t\t\t\tmListener.onDownloadRateChanged(arg2);\n\t\t\tbreak;\n\t\t}\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic boolean onError(MediaPlayer arg0, int arg1, int arg2) {\n\t\tmListener.onOpenFailed();\n\t\treturn true;\n\t}\n\n\tprivate String[] getSubFiles(String videoPath) {\n\t\tArrayList<String> files = new ArrayList<String>();\n\t\tfor (String ext : MediaPlayer.SUB_TYPES) {\n\t\t\tFile s = new File(videoPath.substring(0,\n\t\t\t\t\tvideoPath.lastIndexOf('.') > 0 ? videoPath.lastIndexOf('.')\n\t\t\t\t\t\t\t: videoPath.length())\n\t\t\t\t\t+ ext);\n\t\t\tif (s.exists() && s.isFile() && s.canRead())\n\t\t\t\tfiles.add(s.getAbsolutePath());\n\t\t}\n\n\t\tif (files.isEmpty())\n\t\t\treturn null;\n\t\telse\n\t\t\treturn files.toArray(new String[files.size()]);\n\t}\n\n\t@Override\n\tpublic void onTimedText(String text) {\n\t\tif (mListener != null)\n\t\t\tmListener.onSubChanged(text);\n\t}\n\n\t@Override\n\tpublic void onTimedTextUpdate(byte[] pixels, int width, int height) {\n\t\tif (mListener != null)\n\t\t\tmListener.onSubChanged(pixels, width, height);\n\t}\n\n\t// @Override\n\t// public void onSubtitleUpdate(String arg0) {\n\t// if (mListener != null)\n\t// mListener.onSubChanged(arg0);\n\t// }\n\t//\n\t// @Override\n\t// public void onSubtitleUpdate(byte[] arg0, int arg1, int arg2) {\n\t// if (mListener != null)\n\t// mListener.onSubChanged(arg0, arg1, arg2);\n\t// }\n\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/player/VP.java",
    "content": "package com.nmbb.oplayer.ui.player;\n\nimport io.vov.vitamio.MediaPlayer;\nimport android.graphics.Typeface;\n\npublic class VP {\n\t\n\tpublic static final String SNAP_SHOT_PATH = \"/Player\";\n\tpublic static final String SESSION_LAST_POSITION_SUFIX = \".last\";\n\t\n\t// key\n\tpublic static final String SUB_SHADOW_COLOR = \"vplayer_sub_shadow_color\";\n\tpublic static final String SUB_POSITION = \"vplayer_sub_position\";\n\tpublic static final String SUB_SIZE = \"vplayer_sub_size\";\n\tpublic static final String SUB_SHADOW_RADIUS = \"vplayer_sub_shadow_radius\";\n\tpublic static final String SUB_ENABLED = \"vplayer_sub_enabled\";\n\tpublic static final String SUB_SHADOW_ENABLED = \"vplayer_sub_shadow_enabled\";\n\tpublic static final String SUB_TEXT_KEY = \"sub_text\";\n\tpublic static final String SUB_PIXELS_KEY = \"sub_pixels\";\n\tpublic static final String SUB_WIDTH_KEY = \"sub_width\";\n\tpublic static final String SUB_HEIGHT_KEY = \"sub_height\";\n\t\n\t// default value 1024\n\tpublic static final int DEFAULT_BUF_SIZE = 512 * 1024;\n\tpublic static final int DEFAULT_VIDEO_QUALITY = MediaPlayer.VIDEOQUALITY_MEDIUM;\n\tpublic static final boolean DEFAULT_DEINTERLACE = false;\n\tpublic static final float DEFAULT_ASPECT_RATIO = 0f;\n\tpublic static final float DEFAULT_STEREO_VOLUME = 1.0f;\n\tpublic static final String DEFAULT_META_ENCODING = \"auto\";\n\tpublic static final String DEFAULT_SUB_ENCODING = \"auto\";\n\tpublic static final int DEFAULT_SUB_STYLE = Typeface.BOLD;\n\tpublic static final int DEFAULT_SUB_COLOR = 0xffffffff;\n\tpublic static final int DEFAULT_SUB_SHADOWCOLOR = 0xff000000;\n\tpublic static final float DEFAULT_SUB_SHADOWRADIUS = 2.0f;\n\tpublic static final float DEFAULT_SUB_SIZE = 18.0f;\n\tpublic static final float DEFAULT_SUB_POS = 10.0f;\n\tpublic static final int DEFAULT_TYPEFACE_INT = 0;\n\tpublic static final boolean DEFAULT_SUB_SHOWN = true;\n\tpublic static final boolean DEFAULT_SUB_SHADOW = true;\n\tpublic static final Typeface DEFAULT_TYPEFACE = Typeface.DEFAULT;\n\t\n\t\n\tpublic static Typeface getTypeface(int type) {\n\t\tswitch (type) {\n\t\tcase 0:\n\t\t\treturn Typeface.DEFAULT;\n\t\tcase 1:\n\t\t\treturn Typeface.SANS_SERIF;\n\t\tcase 2:\n\t\t\treturn Typeface.SERIF;\n\t\tcase 3:\n\t\t\treturn Typeface.MONOSPACE;\n\t\tdefault:\n\t\t\treturn DEFAULT_TYPEFACE;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/player/VideoActivity.java",
    "content": "/*\n * Copyright (C) 2012 YIXIA.COM\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.nmbb.oplayer.ui.player;\n\nimport io.vov.vitamio.utils.FileUtils;\nimport io.vov.vitamio.utils.Log;\nimport io.vov.vitamio.widget.OutlineTextView;\n\nimport java.io.File;\nimport java.nio.ByteBuffer;\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport android.annotation.SuppressLint;\nimport android.app.Activity;\nimport android.app.KeyguardManager;\nimport android.content.BroadcastReceiver;\nimport android.content.ComponentName;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.content.IntentFilter;\nimport android.content.ServiceConnection;\nimport android.content.res.Configuration;\nimport android.graphics.Bitmap;\nimport android.media.AudioManager;\nimport android.net.Uri;\nimport android.os.BatteryManager;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.os.Environment;\nimport android.os.Handler;\nimport android.os.IBinder;\nimport android.os.Message;\nimport android.text.TextUtils;\nimport android.view.SurfaceHolder;\nimport android.view.View;\nimport android.view.ViewGroup.MarginLayoutParams;\nimport android.view.WindowManager;\nimport android.widget.ImageView;\nimport android.widget.TextView;\n\nimport com.nmbb.oplayer.R;\nimport com.nmbb.oplayer.preference.PreferenceUtils;\nimport com.nmbb.oplayer.util.ApplicationUtils;\nimport com.nmbb.oplayer.util.DeviceUtils;\nimport com.nmbb.oplayer.util.ImageUtils;\nimport com.nmbb.oplayer.util.IntentHelper;\nimport com.nmbb.oplayer.util.MediaUtils;\nimport com.nmbb.oplayer.util.StringUtils;\nimport com.nmbb.oplayer.util.ToastUtils;\n\n@SuppressLint(\"HandlerLeak\")\npublic class VideoActivity extends Activity implements\n\t\tMediaController.MediaPlayerControl, VideoView.SurfaceCallback {\n\n\tpublic static final int RESULT_FAILED = -7;\n\n\tprivate static final IntentFilter USER_PRESENT_FILTER = new IntentFilter(\n\t\t\tIntent.ACTION_USER_PRESENT);\n\tprivate static final IntentFilter SCREEN_FILTER = new IntentFilter(\n\t\t\tIntent.ACTION_SCREEN_ON);\n\tprivate static final IntentFilter HEADSET_FILTER = new IntentFilter(\n\t\t\tIntent.ACTION_HEADSET_PLUG);\n\tprivate static final IntentFilter BATTERY_FILTER = new IntentFilter(\n\t\t\tIntent.ACTION_BATTERY_CHANGED);\n\n\tprivate boolean mCreated = false;\n\tprivate boolean mNeedLock;\n\tprivate String mDisplayName;\n\tprivate String mBatteryLevel;\n\tprivate boolean mFromStart;\n\tprivate int mLoopCount;\n\tprivate boolean mSaveUri;\n\tprivate int mParentId;\n\tprivate float mStartPos;\n\tprivate boolean mEnd = false;\n\tprivate String mSubPath;\n\tprivate boolean mSubShown;\n\tprivate View mViewRoot;\n\tprivate VideoView mVideoView;\n\tprivate View mVideoLoadingLayout;\n\tprivate TextView mVideoLoadingText;\n\tprivate View mSubtitleContainer;\n\tprivate OutlineTextView mSubtitleText;\n\tprivate ImageView mSubtitleImage;\n\tprivate Uri mUri;\n\tprivate ScreenReceiver mScreenReceiver;\n\tprivate HeadsetPlugReceiver mHeadsetPlugReceiver;\n\tprivate UserPresentReceiver mUserPresentReceiver;\n\tprivate BatteryReceiver mBatteryReceiver;\n\tprivate boolean mReceiverRegistered = false;\n\tprivate boolean mHeadsetPlaying = false;\n\tprivate boolean mCloseComplete = false;\n\tprivate boolean mIsHWCodec = false;\n\n\tprivate MediaController mMediaController;\n\tprivate PlayerService vPlayer;\n\tprivate ServiceConnection vPlayerServiceConnection;\n\t// private Animation mLoadingAnimation;\n\t// private View mLoadingProgressView;\n\n\tstatic {\n\t\tSCREEN_FILTER.addAction(Intent.ACTION_SCREEN_OFF);\n\t}\n\n\t@Override\n\tpublic void onCreate(Bundle savedInstanceState) {\n\t\tsuper.onCreate(savedInstanceState);\n\t\tgetWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,\n\t\t\t\tWindowManager.LayoutParams.FLAG_FULLSCREEN);\n\t\tif (!io.vov.vitamio.LibsChecker.checkVitamioLibs(this))\n\t\t\treturn;\n\n\t\tvPlayerServiceConnection = new ServiceConnection() {\n\t\t\t@Override\n\t\t\tpublic void onServiceConnected(ComponentName name, IBinder service) {\n\t\t\t\tvPlayer = ((PlayerService.LocalBinder) service).getService();\n\t\t\t\tmServiceConnected = true;\n\t\t\t\tif (mSurfaceCreated)\n\t\t\t\t\tvPlayerHandler.sendEmptyMessage(OPEN_FILE);\n\t\t\t}\n\n\t\t\t@Override\n\t\t\tpublic void onServiceDisconnected(ComponentName name) {\n\t\t\t\tvPlayer = null;\n\t\t\t\tmServiceConnected = false;\n\t\t\t}\n\t\t};\n\n\t\tsetVolumeControlStream(AudioManager.STREAM_MUSIC);\n\t\tparseIntent(getIntent());\n\t\tloadView(R.layout.activity_video);\n\t\tmanageReceivers();\n\n\t\tmCreated = true;\n\t}\n\n\tprivate void attachMediaController() {\n\t\tif (mMediaController != null) {\n\t\t\tmNeedLock = mMediaController.isLocked();\n\t\t\tmMediaController.release();\n\t\t}\n\t\tmMediaController = new MediaController(this, mNeedLock);\n\t\tmMediaController.setMediaPlayer(this);\n\t\tmMediaController.setAnchorView(mVideoView.getRootView());\n\t\tsetFileName();\n\t\tsetBatteryLevel();\n\t}\n\n\t@Override\n\tpublic void onStart() {\n\t\tsuper.onStart();\n\t\tif (!mCreated)\n\t\t\treturn;\n\t\tIntent serviceIntent = new Intent(this, PlayerService.class);\n\t\tserviceIntent.putExtra(\"isHWCodec\", mIsHWCodec);\n\t\tbindService(serviceIntent, vPlayerServiceConnection,\n\t\t\t\tContext.BIND_AUTO_CREATE);\n\t}\n\n\t@Override\n\tpublic void onResume() {\n\t\tsuper.onResume();\n\t\tif (!mCreated)\n\t\t\treturn;\n\t\tif (isInitialized()) {\n\t\t\tKeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);\n\t\t\tif (!keyguardManager.inKeyguardRestrictedInputMode()) {\n\t\t\t\tstartPlayer();\n\t\t\t}\n\t\t} else {\n\t\t\tif (mCloseComplete) {\n\t\t\t\treOpen();\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic void onPause() {\n\t\tsuper.onPause();\n\t\tif (!mCreated)\n\t\t\treturn;\n\t\tif (isInitialized()) {\n\t\t\tsavePosition();\n\t\t\tif (vPlayer != null && vPlayer.isPlaying()) {\n\t\t\t\tstopPlayer();\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic void onStop() {\n\t\tsuper.onStop();\n\t\tif (!mCreated)\n\t\t\treturn;\n\t\tif (isInitialized()) {\n\t\t\tvPlayer.releaseSurface();\n\t\t}\n\t\tif (mServiceConnected) {\n\t\t\tunbindService(vPlayerServiceConnection);\n\t\t\tmServiceConnected = false;\n\t\t}\n\n\t}\n\n\t@Override\n\tpublic void onDestroy() {\n\t\tsuper.onDestroy();\n\t\tif (!mCreated)\n\t\t\treturn;\n\t\tmanageReceivers();\n\t\tif (isInitialized() && !vPlayer.isPlaying())\n\t\t\trelease();\n\t\tif (mMediaController != null)\n\t\t\tmMediaController.release();\n\t}\n\n\t@Override\n\tpublic void onConfigurationChanged(Configuration newConfig) {\n\t\tif (isInitialized()) {\n\t\t\tsetVideoLayout();\n\t\t\tattachMediaController();\n\t\t}\n\n\t\tsuper.onConfigurationChanged(newConfig);\n\t}\n\n\t@Override\n\tpublic void onBackPressed() {\n\t\tsuper.onBackPressed();\n\t}\n\n\t@Override\n\tprotected void onSaveInstanceState(Bundle outState) {\n\t\t// http://code.google.com/p/android/issues/detail?id=19917\n\t\toutState.putString(\"WORKAROUND_FOR_BUG_19917_KEY\",\n\t\t\t\t\"WORKAROUND_FOR_BUG_19917_VALUE\");\n\t\tsuper.onSaveInstanceState(outState);\n\t}\n\n\t@Override\n\tpublic void showMenu() {\n\n\t}\n\n\tprivate void loadView(int id) {\n\t\tsetContentView(id);\n\t\tgetWindow().setBackgroundDrawable(null);\n\t\tmViewRoot = findViewById(R.id.video_root);\n\t\tmVideoView = (VideoView) findViewById(R.id.video);\n\t\tmVideoView.initialize(this, this, mIsHWCodec);\n\t\tmSubtitleContainer = findViewById(R.id.subtitle_container);\n\t\tmSubtitleText = (OutlineTextView) findViewById(R.id.subtitle_text);\n\t\tmSubtitleImage = (ImageView) findViewById(R.id.subtitle_image);\n\t\tmVideoLoadingText = (TextView) findViewById(R.id.video_loading_text);\n\t\tmVideoLoadingLayout = findViewById(R.id.video_loading);\n\t\t// mLoadingProgressView =\n\t\t// mVideoLoadingLayout.findViewById(R.id.video_loading_progress);\n\n\t\t// mLoadingAnimation = AnimationUtils.loadAnimation(VideoActivity.this,\n\t\t// R.anim.loading_rotate);\n\t\tgetWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n\t}\n\n\tprivate void parseIntent(Intent i) {\n\t\tUri dat = IntentHelper.getIntentUri(i);\n\t\tif (dat == null)\n\t\t\tresultFinish(RESULT_FAILED);\n\n\t\tString datString = dat.toString();\n\t\tif (!datString.equals(dat.toString()))\n\t\t\tdat = Uri.parse(datString);\n\n\t\tmUri = dat;\n\n\t\tmNeedLock = i.getBooleanExtra(\"lockScreen\", false);\n\t\tmDisplayName = i.getStringExtra(\"displayName\");\n\t\tmFromStart = i.getBooleanExtra(\"fromStart\", false);\n\t\tmSaveUri = i.getBooleanExtra(\"saveUri\", true);\n\t\tmStartPos = i.getFloatExtra(\"startPosition\", -1.0f);\n\t\tmLoopCount = i.getIntExtra(\"loopCount\", 1);\n\t\tmParentId = i.getIntExtra(\"parentId\", 0);\n\t\tmSubPath = i.getStringExtra(\"subPath\");\n\t\tmSubShown = i.getBooleanExtra(\"subShown\", true);\n\t\tmIsHWCodec = i.getBooleanExtra(\"hwCodec\", false);\n\t\tLog.i(\"L: %b, N: %s, S: %b, P: %f, LP: %d\", mNeedLock, mDisplayName,\n\t\t\t\tmFromStart, mStartPos, mLoopCount);\n\t}\n\n\tprivate void manageReceivers() {\n\t\tif (!mReceiverRegistered) {\n\t\t\tmScreenReceiver = new ScreenReceiver();\n\t\t\tregisterReceiver(mScreenReceiver, SCREEN_FILTER);\n\t\t\tmUserPresentReceiver = new UserPresentReceiver();\n\t\t\tregisterReceiver(mUserPresentReceiver, USER_PRESENT_FILTER);\n\t\t\tmBatteryReceiver = new BatteryReceiver();\n\t\t\tregisterReceiver(mBatteryReceiver, BATTERY_FILTER);\n\t\t\tmHeadsetPlugReceiver = new HeadsetPlugReceiver();\n\t\t\tregisterReceiver(mHeadsetPlugReceiver, HEADSET_FILTER);\n\t\t\tmReceiverRegistered = true;\n\t\t} else {\n\t\t\ttry {\n\t\t\t\tif (mScreenReceiver != null)\n\t\t\t\t\tunregisterReceiver(mScreenReceiver);\n\t\t\t\tif (mUserPresentReceiver != null)\n\t\t\t\t\tunregisterReceiver(mUserPresentReceiver);\n\t\t\t\tif (mHeadsetPlugReceiver != null)\n\t\t\t\t\tunregisterReceiver(mHeadsetPlugReceiver);\n\t\t\t\tif (mBatteryReceiver != null)\n\t\t\t\t\tunregisterReceiver(mBatteryReceiver);\n\t\t\t} catch (IllegalArgumentException e) {\n\t\t\t}\n\t\t\tmReceiverRegistered = false;\n\t\t}\n\t}\n\n\tprivate void setFileName() {\n\t\tif (mUri != null) {\n\t\t\tString name = null;\n\t\t\tif (mUri.getScheme() == null || mUri.getScheme().equals(\"file\"))\n\t\t\t\tname = FileUtils.getName(mUri.toString());\n\t\t\telse\n\t\t\t\tname = mUri.getLastPathSegment();\n\t\t\tif (name == null)\n\t\t\t\tname = \"null\";\n\t\t\tif (mDisplayName == null)\n\t\t\t\tmDisplayName = name;\n\t\t\tmMediaController.setFileName(mDisplayName);\n\t\t}\n\t}\n\n\tprivate void applyResult(int resultCode) {\n\t\tvPlayerHandler.removeMessages(BUFFER_PROGRESS);\n\t\tIntent i = new Intent();\n\t\ti.putExtra(\"filePath\", mUri.toString());\n\t\tif (isInitialized()) {\n\t\t\ti.putExtra(\"position\", (double) vPlayer.getCurrentPosition()\n\t\t\t\t\t/ vPlayer.getDuration());\n\t\t\ti.putExtra(\"duration\", vPlayer.getDuration());\n\t\t\tsavePosition();\n\t\t}\n\t\tswitch (resultCode) {\n\t\tcase RESULT_FAILED:\n\t\t\tToastUtils.showLongToast(R.string.video_cannot_play);\n\t\t\tbreak;\n\t\tcase RESULT_CANCELED:\n\t\tcase RESULT_OK:\n\t\t\tbreak;\n\t\t}\n\t\tsetResult(resultCode, i);\n\t}\n\n\tprivate void resultFinish(int resultCode) {\n\t\tapplyResult(resultCode);\n\t\tif (DeviceUtils.hasICS() && resultCode != RESULT_FAILED) {\n\t\t\tandroid.os.Process.killProcess(android.os.Process.myPid());\n\t\t} else {\n\t\t\tfinish();\n\t\t}\n\t}\n\n\tprivate void release() {\n\t\tif (vPlayer != null) {\n\t\t\tif (DeviceUtils.hasICS()) {\n\t\t\t\tandroid.os.Process.killProcess(android.os.Process.myPid());\n\t\t\t} else {\n\t\t\t\tvPlayer.release();\n\t\t\t\tvPlayer.releaseContext();\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate void reOpen(Uri path, String name, boolean fromStart) {\n\t\tif (isInitialized()) {\n\t\t\tsavePosition();\n\t\t\tvPlayer.release();\n\t\t\tvPlayer.releaseContext();\n\t\t}\n\t\tIntent i = getIntent();\n\t\tif (mMediaController != null)\n\t\t\ti.putExtra(\"lockScreen\", mMediaController.isLocked());\n\t\ti.putExtra(\"startPosition\", PreferenceUtils.getFloat(mUri\n\t\t\t\t+ VP.SESSION_LAST_POSITION_SUFIX, 7.7f));\n\t\ti.putExtra(\"fromStart\", fromStart);\n\t\ti.putExtra(\"displayName\", name);\n\t\ti.setData(path);\n\t\tparseIntent(i);\n\t\tmUri = path;\n\t\tif (mViewRoot != null)\n\t\t\tmViewRoot.invalidate();\n\t\tif (mOpened != null)\n\t\t\tmOpened.set(false);\n\t}\n\n\tpublic void reOpen() {\n\t\treOpen(mUri, mDisplayName, false);\n\t}\n\n\tprotected void startPlayer() {\n\t\tif (isInitialized() && mScreenReceiver.screenOn\n\t\t\t\t&& !vPlayer.isBuffering()) {\n\t\t\tLog.i(\"VideoActivity#startPlayer\");\n\t\t\tif (!vPlayer.isPlaying()) {\n\t\t\t\tvPlayer.start();\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected void stopPlayer() {\n\t\tif (isInitialized()) {\n\t\t\tvPlayer.stop();\n\t\t}\n\t}\n\n\tprivate void setBatteryLevel() {\n\t\tif (mMediaController != null)\n\t\t\tmMediaController.setBatteryLevel(mBatteryLevel);\n\t}\n\n\tprivate class BatteryReceiver extends BroadcastReceiver {\n\t\t@Override\n\t\tpublic void onReceive(Context context, Intent intent) {\n\t\t\tint level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);\n\t\t\tint scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);\n\t\t\tint percent = scale > 0 ? level * 100 / scale : 0;\n\t\t\tif (percent > 100)\n\t\t\t\tpercent = 100;\n\t\t\tmBatteryLevel = String.valueOf(percent) + \"%\";\n\t\t\tsetBatteryLevel();\n\t\t}\n\t}\n\n\tprivate class UserPresentReceiver extends BroadcastReceiver {\n\t\t@Override\n\t\tpublic void onReceive(Context context, Intent intent) {\n\t\t\tif (isRootActivity()) {\n\t\t\t\tstartPlayer();\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate boolean isRootActivity() {\n\t\treturn ApplicationUtils.isTopActivity(getApplicationContext(),\n\t\t\t\tgetClass().getName());\n\t\t// ActivityManager activity = (ActivityManager)\n\t\t// getSystemService(Context.ACTIVITY_SERVICE);\n\t\t// return\n\t\t// activity.getRunningTasks(1).get(0).topActivity.flattenToString().endsWith(\"io.vov.vitamio.activity.VideoActivity\");\n\t}\n\n\tpublic class HeadsetPlugReceiver extends BroadcastReceiver {\n\t\t@Override\n\t\tpublic void onReceive(Context context, Intent intent) {\n\t\t\tif (intent != null && intent.hasExtra(\"state\")) {\n\t\t\t\tint state = intent.getIntExtra(\"state\", -1);\n\t\t\t\tif (state == 0) {\n\t\t\t\t\tmHeadsetPlaying = isPlaying();\n\t\t\t\t\tstopPlayer();\n\t\t\t\t} else if (state == 1) {\n\t\t\t\t\tif (mHeadsetPlaying)\n\t\t\t\t\t\tstartPlayer();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\tprivate class ScreenReceiver extends BroadcastReceiver {\n\t\tprivate boolean screenOn = true;\n\n\t\t@Override\n\t\tpublic void onReceive(Context context, Intent intent) {\n\t\t\tif (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {\n\t\t\t\tscreenOn = false;\n\t\t\t\tstopPlayer();\n\t\t\t} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {\n\t\t\t\tscreenOn = true;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate void loadVPlayerPrefs() {\n\t\tif (!isInitialized())\n\t\t\treturn;\n\t\tvPlayer.setBuffer(VP.DEFAULT_BUF_SIZE);\n\t\tvPlayer.setVideoQuality(VP.DEFAULT_VIDEO_QUALITY);\n\t\tvPlayer.setDeinterlace(VP.DEFAULT_DEINTERLACE);\n\t\tvPlayer.setVolume(VP.DEFAULT_STEREO_VOLUME, VP.DEFAULT_STEREO_VOLUME);\n\t\tvPlayer.setSubEncoding(VP.DEFAULT_SUB_ENCODING);\n\t\tMarginLayoutParams lp = (MarginLayoutParams) mSubtitleContainer\n\t\t\t\t.getLayoutParams();\n\t\tlp.bottomMargin = (int) VP.DEFAULT_SUB_POS;\n\t\tmSubtitleContainer.setLayoutParams(lp);\n\t\tvPlayer.setSubShown(mSubShown);\n\t\tsetTextViewStyle(mSubtitleText);\n\t\tif (!TextUtils.isEmpty(mSubPath))\n\t\t\tvPlayer.setSubPath(mSubPath);\n\t\tif (mVideoView != null && isInitialized())\n\t\t\tsetVideoLayout();\n\t}\n\n\tprivate void setTextViewStyle(OutlineTextView v) {\n\t\tv.setTextColor(VP.DEFAULT_SUB_COLOR);\n\t\tv.setTypeface(VP.getTypeface(VP.DEFAULT_TYPEFACE_INT),\n\t\t\t\tVP.DEFAULT_SUB_STYLE);\n\t\tv.setShadowLayer(VP.DEFAULT_SUB_SHADOWRADIUS, 0, 0,\n\t\t\t\tVP.DEFAULT_SUB_SHADOWCOLOR);\n\t}\n\n\tprivate boolean isInitialized() {\n\t\treturn (mCreated && vPlayer != null && vPlayer.isInitialized());\n\t}\n\n\tprivate Handler mSubHandler = new Handler() {\n\t\tBundle data;\n\t\tString text;\n\t\tbyte[] pixels;\n\t\tint width = 0, height = 0;\n\t\tBitmap bm = null;\n\t\tint oldType = SUBTITLE_TEXT;\n\n\t\t@Override\n\t\tpublic void handleMessage(Message msg) {\n\t\t\tdata = msg.getData();\n\t\t\tswitch (msg.what) {\n\t\t\tcase SUBTITLE_TEXT:\n\t\t\t\tif (oldType != SUBTITLE_TEXT) {\n\t\t\t\t\tmSubtitleImage.setVisibility(View.GONE);\n\t\t\t\t\tmSubtitleText.setVisibility(View.VISIBLE);\n\t\t\t\t\toldType = SUBTITLE_TEXT;\n\t\t\t\t}\n\t\t\t\ttext = data.getString(VP.SUB_TEXT_KEY);\n\t\t\t\tmSubtitleText.setText(text == null ? \"\" : text.trim());\n\t\t\t\tbreak;\n\t\t\tcase SUBTITLE_BITMAP:\n\t\t\t\tif (oldType != SUBTITLE_BITMAP) {\n\t\t\t\t\tmSubtitleText.setVisibility(View.GONE);\n\t\t\t\t\tmSubtitleImage.setVisibility(View.VISIBLE);\n\t\t\t\t\toldType = SUBTITLE_BITMAP;\n\t\t\t\t}\n\t\t\t\tpixels = data.getByteArray(VP.SUB_PIXELS_KEY);\n\t\t\t\tif (bm == null || width != data.getInt(VP.SUB_WIDTH_KEY)\n\t\t\t\t\t\t|| height != data.getInt(VP.SUB_HEIGHT_KEY)) {\n\t\t\t\t\twidth = data.getInt(VP.SUB_WIDTH_KEY);\n\t\t\t\t\theight = data.getInt(VP.SUB_HEIGHT_KEY);\n\t\t\t\t\tbm = Bitmap.createBitmap(width, height,\n\t\t\t\t\t\t\tBitmap.Config.ARGB_8888);\n\t\t\t\t}\n\t\t\t\tif (pixels != null)\n\t\t\t\t\tbm.copyPixelsFromBuffer(ByteBuffer.wrap(pixels));\n\t\t\t\tmSubtitleImage.setImageBitmap(bm);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t};\n\n\tprivate AtomicBoolean mOpened = new AtomicBoolean(Boolean.FALSE);\n\tprivate boolean mSurfaceCreated = false;\n\tprivate boolean mServiceConnected = false;\n\tprivate Object mOpenLock = new Object();\n\tprivate static final int OPEN_FILE = 0;\n\tprivate static final int OPEN_START = 1;\n\tprivate static final int OPEN_SUCCESS = 2;\n\tprivate static final int OPEN_FAILED = 3;\n\tprivate static final int HW_FAILED = 4;\n\tprivate static final int LOAD_PREFS = 5;\n\tprivate static final int BUFFER_START = 11;\n\tprivate static final int BUFFER_PROGRESS = 12;\n\tprivate static final int BUFFER_COMPLETE = 13;\n\tprivate static final int CLOSE_START = 21;\n\tprivate static final int CLOSE_COMPLETE = 22;\n\tprivate static final int SUBTITLE_TEXT = 0;\n\tprivate static final int SUBTITLE_BITMAP = 1;\n\tprivate Handler vPlayerHandler = new Handler() {\n\t\t@Override\n\t\tpublic void handleMessage(Message msg) {\n\t\t\tswitch (msg.what) {\n\t\t\tcase OPEN_FILE:\n\t\t\t\tsynchronized (mOpenLock) {\n\t\t\t\t\tif (!mOpened.get() && vPlayer != null) {\n\t\t\t\t\t\tmOpened.set(true);\n\t\t\t\t\t\tvPlayer.setVPlayerListener(vPlayerListener);\n\t\t\t\t\t\tif (vPlayer.isInitialized())\n\t\t\t\t\t\t\tmUri = vPlayer.getUri();\n\n\t\t\t\t\t\tif (mVideoView != null)\n\t\t\t\t\t\t\tvPlayer.setDisplay(mVideoView.getHolder());\n\t\t\t\t\t\tif (mUri != null)\n\t\t\t\t\t\t\tvPlayer.initialize(mUri, mDisplayName, mSaveUri,\n\t\t\t\t\t\t\t\t\tgetStartPosition(), vPlayerListener,\n\t\t\t\t\t\t\t\t\tmParentId, mIsHWCodec);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase OPEN_START:\n\t\t\t\tmVideoLoadingText.setText(R.string.video_layout_loading);\n\t\t\t\tsetVideoLoadingLayoutVisibility(View.VISIBLE);\n\t\t\t\tbreak;\n\t\t\tcase OPEN_SUCCESS:\n\t\t\t\tloadVPlayerPrefs();\n\t\t\t\tsetVideoLoadingLayoutVisibility(View.GONE);\n\t\t\t\tsetVideoLayout();\n\t\t\t\tvPlayer.start();\n\t\t\t\tattachMediaController();\n\t\t\t\tbreak;\n\t\t\tcase OPEN_FAILED:\n\t\t\t\tresultFinish(RESULT_FAILED);\n\t\t\t\tbreak;\n\t\t\tcase BUFFER_START:\n\t\t\t\tsetVideoLoadingLayoutVisibility(View.VISIBLE);\n\t\t\t\tvPlayerHandler.sendEmptyMessageDelayed(BUFFER_PROGRESS, 1000);\n\t\t\t\tbreak;\n\t\t\tcase BUFFER_PROGRESS:\n\t\t\t\tif (vPlayer.getBufferProgress() >= 100) {\n\t\t\t\t\tsetVideoLoadingLayoutVisibility(View.GONE);\n\t\t\t\t} else {\n\t\t\t\t\tmVideoLoadingText.setText(getString(\n\t\t\t\t\t\t\tR.string.video_layout_buffering_progress,\n\t\t\t\t\t\t\tvPlayer.getBufferProgress()));\n\t\t\t\t\tvPlayerHandler.sendEmptyMessageDelayed(BUFFER_PROGRESS,\n\t\t\t\t\t\t\t1000);\n\t\t\t\t\tstopPlayer();\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase BUFFER_COMPLETE:\n\t\t\t\tsetVideoLoadingLayoutVisibility(View.GONE);\n\t\t\t\tvPlayerHandler.removeMessages(BUFFER_PROGRESS);\n\t\t\t\tbreak;\n\t\t\tcase CLOSE_START:\n\t\t\t\tmVideoLoadingText.setText(R.string.closing_file);\n\t\t\t\tsetVideoLoadingLayoutVisibility(View.VISIBLE);\n\t\t\t\tbreak;\n\t\t\tcase CLOSE_COMPLETE:\n\t\t\t\tmCloseComplete = true;\n\t\t\t\tbreak;\n\t\t\tcase HW_FAILED:\n\t\t\t\tif (mVideoView != null) {\n\t\t\t\t\tmVideoView.setVisibility(View.GONE);\n\t\t\t\t\tmVideoView.setVisibility(View.VISIBLE);\n\t\t\t\t\tmVideoView.initialize(VideoActivity.this,\n\t\t\t\t\t\t\tVideoActivity.this, false);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase LOAD_PREFS:\n\t\t\t\tloadVPlayerPrefs();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t};\n\n\tprivate void setVideoLoadingLayoutVisibility(int visibility) {\n\t\tif (mVideoLoadingLayout != null) {\n\t\t\t// if (visibility == View.VISIBLE)\n\t\t\t// mLoadingProgressView.startAnimation(mLoadingAnimation);\n\t\t\tmVideoLoadingLayout.setVisibility(visibility);\n\t\t}\n\t}\n\n\tprivate PlayerService.VPlayerListener vPlayerListener = new PlayerService.VPlayerListener() {\n\t\t@Override\n\t\tpublic void onHWRenderFailed() {\n\t\t\tif (Build.VERSION.SDK_INT < 11 && mIsHWCodec) {\n\t\t\t\tvPlayerHandler.sendEmptyMessage(HW_FAILED);\n\t\t\t\tvPlayerHandler.sendEmptyMessageDelayed(HW_FAILED, 200);\n\t\t\t}\n\t\t}\n\n\t\t@Override\n\t\tpublic void onSubChanged(String sub) {\n\t\t\tMessage msg = new Message();\n\t\t\tBundle b = new Bundle();\n\t\t\tb.putString(VP.SUB_TEXT_KEY, sub);\n\t\t\tmsg.setData(b);\n\t\t\tmsg.what = SUBTITLE_TEXT;\n\t\t\tmSubHandler.sendMessage(msg);\n\t\t}\n\n\t\t@Override\n\t\tpublic void onSubChanged(byte[] pixels, int width, int height) {\n\t\t\tMessage msg = new Message();\n\t\t\tBundle b = new Bundle();\n\t\t\tb.putByteArray(VP.SUB_PIXELS_KEY, pixels);\n\t\t\tb.putInt(VP.SUB_WIDTH_KEY, width);\n\t\t\tb.putInt(VP.SUB_HEIGHT_KEY, height);\n\t\t\tmsg.setData(b);\n\t\t\tmsg.what = SUBTITLE_BITMAP;\n\t\t\tmSubHandler.sendMessage(msg);\n\t\t}\n\n\t\t@Override\n\t\tpublic void onOpenStart() {\n\t\t\tvPlayerHandler.sendEmptyMessage(OPEN_START);\n\t\t}\n\n\t\t@Override\n\t\tpublic void onOpenSuccess() {\n\t\t\tvPlayerHandler.sendEmptyMessage(OPEN_SUCCESS);\n\t\t}\n\n\t\t@Override\n\t\tpublic void onOpenFailed() {\n\t\t\tvPlayerHandler.sendEmptyMessage(OPEN_FAILED);\n\t\t}\n\n\t\t@Override\n\t\tpublic void onBufferStart() {\n\t\t\tvPlayerHandler.sendEmptyMessage(BUFFER_START);\n\t\t\tstopPlayer();\n\t\t}\n\n\t\t@Override\n\t\tpublic void onBufferComplete() {\n\t\t\tLog.i(\"VideoActivity#onBufferComplete \" + vPlayer.needResume());\n\t\t\tvPlayerHandler.sendEmptyMessage(BUFFER_COMPLETE);\n\t\t\tif (vPlayer != null && !vPlayer.needResume())\n\t\t\t\tstartPlayer();\n\t\t}\n\n\t\t@Override\n\t\tpublic void onPlaybackComplete() {\n\t\t\tmEnd = true;\n\t\t\tif (mLoopCount == 0 || mLoopCount-- > 1) {\n\t\t\t\tvPlayer.start();\n\t\t\t\tvPlayer.seekTo(0);\n\t\t\t} else {\n\t\t\t\tresultFinish(RESULT_OK);\n\t\t\t}\n\t\t}\n\n\t\t@Override\n\t\tpublic void onCloseStart() {\n\t\t\tvPlayerHandler.sendEmptyMessage(CLOSE_START);\n\t\t}\n\n\t\t@Override\n\t\tpublic void onCloseComplete() {\n\t\t\tvPlayerHandler.sendEmptyMessage(CLOSE_COMPLETE);\n\t\t}\n\n\t\t@Override\n\t\tpublic void onVideoSizeChanged(int width, int height) {\n\t\t\tif (mVideoView != null) {\n\t\t\t\tsetVideoLayout();\n\t\t\t}\n\t\t}\n\n\t\t@Override\n\t\tpublic void onDownloadRateChanged(int kbPerSec) {\n\t\t\tif (!MediaUtils.isNative(mUri.toString())\n\t\t\t\t\t&& mMediaController != null) {\n\t\t\t\tmMediaController.setDownloadRate(String.format(\"%dKB/s\",\n\t\t\t\t\t\tkbPerSec));\n\t\t\t}\n\t\t}\n\n\t};\n\n\tprivate int mVideoMode = VideoView.VIDEO_LAYOUT_SCALE;\n\n\tprivate void setVideoLayout() {\n\t\tmVideoView.setVideoLayout(mVideoMode, VP.DEFAULT_ASPECT_RATIO,\n\t\t\t\tvPlayer.getVideoWidth(), vPlayer.getVideoHeight(),\n\t\t\t\tvPlayer.getVideoAspectRatio());\n\t}\n\n\tprivate void savePosition() {\n\t\tif (vPlayer != null && mUri != null) {\n\t\t\tPreferenceUtils.put(\n\t\t\t\t\tmUri.toString(),\n\t\t\t\t\tStringUtils.generateTime((int) (0.5 + vPlayer\n\t\t\t\t\t\t\t.getCurrentPosition()))\n\t\t\t\t\t\t\t+ \" / \"\n\t\t\t\t\t\t\t+ StringUtils.generateTime(vPlayer.getDuration()));\n\t\t\tif (mEnd)\n\t\t\t\tPreferenceUtils\n\t\t\t\t\t\t.put(mUri + VP.SESSION_LAST_POSITION_SUFIX, 1.0f);\n\t\t\telse\n\t\t\t\tPreferenceUtils\n\t\t\t\t\t\t.put(mUri + VP.SESSION_LAST_POSITION_SUFIX,\n\t\t\t\t\t\t\t\t(float) (vPlayer.getCurrentPosition() / (double) vPlayer\n\t\t\t\t\t\t\t\t\t\t.getDuration()));\n\t\t}\n\t}\n\n\tprivate float getStartPosition() {\n\t\tif (mFromStart)\n\t\t\treturn 1.1f;\n\t\tif (mStartPos <= 0.0f || mStartPos >= 1.0f)\n\t\t\treturn PreferenceUtils.getFloat(mUri\n\t\t\t\t\t+ VP.SESSION_LAST_POSITION_SUFIX, 7.7f);\n\t\treturn mStartPos;\n\t}\n\n\t@Override\n\tpublic int getBufferPercentage() {\n\t\tif (isInitialized())\n\t\t\treturn (int) (vPlayer.getBufferProgress() * 100);\n\t\treturn 0;\n\t}\n\n\t@Override\n\tpublic long getCurrentPosition() {\n\t\tif (isInitialized())\n\t\t\treturn vPlayer.getCurrentPosition();\n\t\treturn (long) (getStartPosition() * vPlayer.getDuration());\n\t}\n\n\t@Override\n\tpublic long getDuration() {\n\t\tif (isInitialized())\n\t\t\treturn vPlayer.getDuration();\n\t\treturn 0;\n\t}\n\n\t@Override\n\tpublic boolean isPlaying() {\n\t\tif (isInitialized())\n\t\t\treturn vPlayer.isPlaying();\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic void pause() {\n\t\tif (isInitialized())\n\t\t\tvPlayer.stop();\n\t}\n\n\t@Override\n\tpublic void seekTo(long arg0) {\n\t\tif (isInitialized())\n\t\t\tvPlayer.seekTo((float) ((double) arg0 / vPlayer.getDuration()));\n\t}\n\n\t@Override\n\tpublic void start() {\n\t\tif (isInitialized())\n\t\t\tvPlayer.start();\n\t}\n\n\t@Override\n\tpublic void previous() {\n\t}\n\n\t@Override\n\tpublic void next() {\n\t}\n\n\tprivate static final int VIDEO_MAXIMUM_HEIGHT = 2048;\n\tprivate static final int VIDEO_MAXIMUM_WIDTH = 2048;\n\n\t@Override\n\tpublic float scale(float scaleFactor) {\n\t\tfloat userRatio = VP.DEFAULT_ASPECT_RATIO;\n\t\tint videoWidth = vPlayer.getVideoWidth();\n\t\tint videoHeight = vPlayer.getVideoHeight();\n\t\tfloat videoRatio = vPlayer.getVideoAspectRatio();\n\t\tfloat currentRatio = mVideoView.mVideoHeight / (float) videoHeight;\n\n\t\tcurrentRatio += (scaleFactor - 1);\n\t\tif (videoWidth * currentRatio >= VIDEO_MAXIMUM_WIDTH)\n\t\t\tcurrentRatio = VIDEO_MAXIMUM_WIDTH / (float) videoWidth;\n\n\t\tif (videoHeight * currentRatio >= VIDEO_MAXIMUM_HEIGHT)\n\t\t\tcurrentRatio = VIDEO_MAXIMUM_HEIGHT / (float) videoHeight;\n\n\t\tif (currentRatio < 0.5f)\n\t\t\tcurrentRatio = 0.5f;\n\n\t\tmVideoView.mVideoHeight = (int) (videoHeight * currentRatio);\n\t\tmVideoView.setVideoLayout(mVideoMode, userRatio, videoWidth,\n\t\t\t\tvideoHeight, videoRatio);\n\t\treturn currentRatio;\n\t}\n\n\t@SuppressLint(\"SimpleDateFormat\")\n\t@Override\n\tpublic void snapshot() {\n\t\tif (!com.nmbb.oplayer.util.FileUtils.sdAvailable()) {\n\t\t\tToastUtils.showToast(R.string.file_explorer_sdcard_not_available);\n\t\t} else {\n\t\t\tUri imgUri = null;\n\t\t\tBitmap bitmap = vPlayer.getCurrentFrame();\n\t\t\tif (bitmap != null) {\n\t\t\t\tFile screenshotsDirectory = new File(\n\t\t\t\t\t\tEnvironment\n\t\t\t\t\t\t\t\t.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)\n\t\t\t\t\t\t\t\t+ VP.SNAP_SHOT_PATH);\n\t\t\t\tif (!screenshotsDirectory.exists()) {\n\t\t\t\t\tscreenshotsDirectory.mkdirs();\n\t\t\t\t}\n\n\t\t\t\tFile savePath = new File(\n\t\t\t\t\t\tscreenshotsDirectory.getPath()\n\t\t\t\t\t\t\t\t+ \"/\"\n\t\t\t\t\t\t\t\t+ new SimpleDateFormat(\"yyyyMMddHHmmss\")\n\t\t\t\t\t\t\t\t\t\t.format(new Date()) + \".jpg\");\n\t\t\t\tif (ImageUtils.saveBitmap(savePath.getPath(), bitmap)) {\n\t\t\t\t\timgUri = Uri.fromFile(savePath);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (imgUri != null) {\n\t\t\t\tsendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,\n\t\t\t\t\t\timgUri));\n\t\t\t\tToastUtils.showLongToast(getString(\n\t\t\t\t\t\tR.string.video_screenshot_save_in, imgUri.getPath()));\n\t\t\t} else {\n\t\t\t\tToastUtils.showToast(R.string.video_screenshot_failed);\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic void toggleVideoMode(int mode) {\n\t\tmVideoMode = mode;\n\t\tsetVideoLayout();\n\t}\n\n\t@Override\n\tpublic void stop() {\n\t\tonBackPressed();\n\t}\n\n\t@Override\n\tpublic long goForward() {\n\t\treturn 0;\n\t}\n\n\t@Override\n\tpublic long goBack() {\n\t\treturn 0;\n\t}\n\n\t@Override\n\tpublic void removeLoadingView() {\n\t\tmVideoLoadingLayout.setVisibility(View.GONE);\n\t}\n\n\t@Override\n\tpublic void onSurfaceCreated(SurfaceHolder holder) {\n\t\tLog.i(\"onSurfaceCreated\");\n\t\tmSurfaceCreated = true;\n\t\tif (mServiceConnected)\n\t\t\tvPlayerHandler.sendEmptyMessage(OPEN_FILE);\n\t\tif (vPlayer != null)\n\t\t\tvPlayer.setDisplay(holder);\n\t}\n\n\t@Override\n\tpublic void onSurfaceChanged(SurfaceHolder holder, int format, int width,\n\t\t\tint height) {\n\t\tif (vPlayer != null) {\n\t\t\tsetVideoLayout();\n\t\t}\n\t}\n\n\t@Override\n\tpublic void onSurfaceDestroyed(SurfaceHolder holder) {\n\t\tLog.i(\"onSurfaceDestroyed\");\n\t\tif (vPlayer != null && vPlayer.isInitialized()) {\n\t\t\tif (vPlayer.isPlaying()) {\n\t\t\t\tvPlayer.stop();\n\t\t\t\tvPlayer.setState(PlayerService.STATE_NEED_RESUME);\n\t\t\t}\n\t\t\tvPlayer.releaseSurface();\n\t\t\tif (vPlayer.needResume())\n\t\t\t\tvPlayer.start();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/player/VideoView.java",
    "content": "/*\n * Copyright (C) 2012 YIXIA.COM\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.nmbb.oplayer.ui.player;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.graphics.PixelFormat;\nimport android.util.AttributeSet;\nimport android.view.SurfaceHolder;\nimport android.view.SurfaceView;\nimport android.view.ViewGroup.LayoutParams;\n\nimport com.nmbb.oplayer.util.DeviceUtils;\n\npublic class VideoView extends SurfaceView {\n\tprivate Activity mActivity;\n\tprivate SurfaceHolder mSurfaceHolder;\n\tprivate int mSurfaceWidth, mSurfaceHeight;\n\tprivate int mVideoMode = VIDEO_LAYOUT_SCALE;\n\tpublic static final int VIDEO_LAYOUT_ORIGIN = 0;\n\tpublic static final int VIDEO_LAYOUT_SCALE = 1;\n\tpublic static final int VIDEO_LAYOUT_STRETCH = 2;\n\tpublic static final int VIDEO_LAYOUT_ZOOM = 3;\n\tpublic static final int VIDEO_LAYOUT_SCALE_ZOOM = 4;\n\tpublic int mVideoHeight;\n\n\tpublic VideoView(Context context, AttributeSet attrs) {\n\t\tsuper(context, attrs);\n\t\tgetHolder().addCallback(mCallback);\n\t\tgetHolder().setFormat(PixelFormat.RGBA_8888); \n\t}\n\n\t@SuppressWarnings(\"deprecation\")\n\tpublic void initialize(Activity activity, SurfaceCallback l, boolean push) {\n\t\tmActivity = activity;\n\t\tmListener = l;\n\t\tif (mSurfaceHolder == null)\n\t\t\tmSurfaceHolder = getHolder();\n\n\t\t// These methods is set to hw decoder or sw decoder, <= 2.3\n\t\tif (push)\n\t\t\tgetHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);\n\t\telse\n\t\t\tgetHolder().setType(SurfaceHolder.SURFACE_TYPE_NORMAL);\n\t}\n\n\tprivate void setSurfaceLayout(float userRatio, int videoWidth, int videoHeight, float videoAspectRatio) {\n\t\tLayoutParams lp = getLayoutParams();\n\t\tint windowWidth = DeviceUtils.getScreenWidth(mActivity);\n\t\tint windowHeight = DeviceUtils.getScreenHeight(mActivity);\n\t\tfloat windowRatio = windowWidth / (float) windowHeight;\n\t\tfloat videoRatio = userRatio <= 0.01f ? videoAspectRatio : userRatio;\n\t\tmSurfaceHeight = videoHeight;\n\t\tmSurfaceWidth = videoWidth;\n\t\tif (VIDEO_LAYOUT_ORIGIN == mVideoMode && mSurfaceWidth < windowWidth && mSurfaceHeight < windowHeight) {\n\t\t\tlp.width = (int) (mSurfaceHeight * videoRatio);\n\t\t\tlp.height = mSurfaceHeight;\n\t\t} else if (mVideoMode == VIDEO_LAYOUT_ZOOM) {\n\t\t\tlp.width = windowRatio > videoRatio ? windowWidth : (int) (videoRatio * windowHeight);\n\t\t\tlp.height = windowRatio < videoRatio ? windowHeight : (int) (windowWidth / videoRatio);\n\t\t} else if (mVideoMode == VIDEO_LAYOUT_SCALE_ZOOM && mVideoHeight > 0) {\n\t\t\tlp.width = (int) (mVideoHeight * videoRatio);\n\t\t\tlp.height = mVideoHeight;\n\t\t} else {\n\t\t\tboolean full = mVideoMode == VIDEO_LAYOUT_STRETCH;\n\t\t\tlp.width = (full || windowRatio < videoRatio) ? windowWidth : (int) (videoRatio * windowHeight);\n\t\t\tlp.height = (full || windowRatio > videoRatio) ? windowHeight : (int) (windowWidth / videoRatio);\n\t\t}\n\t\tmVideoHeight = lp.height;\n\t\tsetLayoutParams(lp);\n\t\tgetHolder().setFixedSize(mSurfaceWidth, mSurfaceHeight);\n\t\t//Log.d(\"VIDEO: %dx%dx%f, Surface: %dx%d, LP: %dx%d, Window: %dx%dx%f\", videoWidth, videoHeight, videoAspectRatio, mSurfaceWidth, mSurfaceHeight, lp.width, lp.height, windowWidth, windowHeight, windowRatio);\n\t}\n\n\tpublic void setVideoLayout(int layout, float userRatio, int videoWidth, int videoHeight, float videoRatio) {\n\t\tmVideoMode = layout;\n\t\tsetSurfaceLayout(userRatio, videoWidth, videoHeight, videoRatio);\n\t}\n\n\tprivate SurfaceHolder.Callback mCallback = new SurfaceHolder.Callback() {\n\t\t@Override\n\t\tpublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {\n\t\t\tholder.setKeepScreenOn(true);\n\t\t\tif (mListener != null)\n\t\t\t\tmListener.onSurfaceChanged(holder, format, width, height);\n\t\t}\n\n\t\t@Override\n\t\tpublic void surfaceCreated(SurfaceHolder holder) {\n\t\t\tmSurfaceHolder = holder;\n\t\t\tif (mListener != null)\n\t\t\t\tmListener.onSurfaceCreated(holder);\n\t\t}\n\n\t\t@Override\n\t\tpublic void surfaceDestroyed(SurfaceHolder holder) {\n\t\t\tif (mListener != null)\n\t\t\t\tmListener.onSurfaceDestroyed(holder);\n\t\t}\n\t};\n\n\tprivate SurfaceCallback mListener;\n\n\tpublic interface SurfaceCallback {\n\t\tpublic void onSurfaceCreated(SurfaceHolder holder);\n\n\t\tpublic void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height);\n\n\t\tpublic void onSurfaceDestroyed(SurfaceHolder holder);\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/vitamio/InitActivity.java",
    "content": "package com.nmbb.oplayer.ui.vitamio;\n\nimport io.vov.vitamio.Vitamio;\nimport android.app.Activity;\nimport android.app.ProgressDialog;\nimport android.content.Intent;\nimport android.os.AsyncTask;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.Message;\nimport android.view.WindowManager;\n\nimport com.nmbb.oplayer.R;\n\npublic class InitActivity extends Activity {\n\tpublic static final String FROM_ME = \"fromVitamioInitActivity\";\n\tpublic static final String EXTRA_MSG = \"EXTRA_MSG\";\n\tpublic static final String EXTRA_FILE = \"EXTRA_FILE\";\n\tprivate ProgressDialog mPD;\n\n\t@Override\n\tprotected void onCreate(Bundle savedInstanceState) {\n\t\tsuper.onCreate(savedInstanceState);\n\t\tgetWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n\n\t\tnew AsyncTask<Object, Object, Object>() {\n\t\t\t@Override\n\t\t\tprotected void onPreExecute() {\n\t\t\t\tmPD = new ProgressDialog(InitActivity.this);\n\t\t\t\tmPD.setCancelable(false);\n\t\t\t\tmPD.setMessage(getText(R.string.init_decoders));\n\t\t\t\tmPD.show();\n\t\t\t}\n\n\t\t\t@Override\n\t\t\tprotected Object doInBackground(Object... params) {\n\n\t\t\t\tVitamio.initialize(getApplicationContext());\n//\t\t\t\tif (Vitamio.isInitialized(getApplicationContext()))\n//\t\t\t\t\treturn null;\n//\n//\t\t\t\t//反射解压\n//\t\t\t\ttry {\n//\t\t\t\t\tClass c = Class.forName(\"io.vov.vitamio.Vitamio\");\n//\t\t\t\t\tMethod extractLibs = c.getDeclaredMethod(\"extractLibs\", new Class[] { android.content.Context.class, int.class });\n//\t\t\t\t\textractLibs.setAccessible(true);\n//\t\t\t\t\textractLibs.invoke(c, new Object[] { getApplicationContext(), R.raw.libarm });\n//\t\t\t\t\t\n////\t\t\t\t\tField vitamioLibraryPath = c.getDeclaredField(\"vitamioLibraryPath\");\n////\n////\t\t\t\t\t AndroidContextUtils.getDataDir(ctx) + \"libs/\"\n//\t\t\t\t\t\n//\t\t\t\t} catch (NoSuchMethodException e) {\n//\t\t\t\t\tLog.e(\"extractLibs\", e);\n//\t\t\t\t\te.printStackTrace();\n//\t\t\t\t} catch (IllegalArgumentException e) {\n//\t\t\t\t\te.printStackTrace();\n//\t\t\t\t} catch (IllegalAccessException e) {\n//\t\t\t\t\te.printStackTrace();\n//\t\t\t\t} catch (InvocationTargetException e) {\n//\t\t\t\t\te.printStackTrace();\n//\t\t\t\t} catch (ClassNotFoundException e) {\n//\t\t\t\t\te.printStackTrace();\n//\t\t\t\t}\n\n\t\t\t\tuiHandler.sendEmptyMessage(0);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}.execute();\n\t}\n\n\tprivate Handler uiHandler = new Handler() {\n\t\t@Override\n\t\tpublic void handleMessage(Message msg) {\n\t\t\tmPD.dismiss();\n\t\t\tIntent src = getIntent();\n\t\t\tIntent i = new Intent();\n\t\t\ti.setClassName(src.getStringExtra(\"package\"), src.getStringExtra(\"className\"));\n\t\t\ti.setData(src.getData());\n\t\t\ti.putExtras(src);\n\t\t\ti.putExtra(FROM_ME, true);\n\t\t\tstartActivity(i);\n\n\t\t\tfinish();\n\t\t}\n\t};\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/ui/vitamio/LibsChecker.java",
    "content": "package com.nmbb.oplayer.ui.vitamio;\n\nimport io.vov.vitamio.Vitamio;\nimport android.app.Activity;\nimport android.content.Intent;\n\npublic final class LibsChecker {\n\tpublic static final String FROM_ME = \"fromVitamioInitActivity\";\n\n\t//\n\t//\tpublic static final boolean checkVitamioLibs(Activity ctx, int msgID, int rawID) {\n\t//\t\tnew Vitamio().\n\t//\t\tif (!Vitamio.isInitialized(ctx) && !ctx.getIntent().getBooleanExtra(FROM_ME, false)) {\n\t//\t\t\tIntent i = new Intent();\n\t//\t\t\ti.setClassName(Vitamio.getCompatiblePackage(), \"com.nmbb.oplayer.ui.vitamio.InitActivity\");\n\t//\t\t\ti.putExtras(ctx.getIntent());\n\t//\t\t\ti.setData(ctx.getIntent().getData());\n\t//\t\t\ti.putExtra(\"package\", ctx.getApplicationInfo().packageName);\n\t//\t\t\ti.putExtra(\"className\", ctx.getClass().getName());\n\t//\t\t\ti.putExtra(\"EXTRA_MSG\", msgID);\n\t//\t\t\ti.putExtra(\"EXTRA_FILE\", rawID);\n\t//\t\t\tctx.startActivity(i);\n\t//\t\t\tctx.finish();\n\t//\t\t\treturn false;\n\t//\t\t}\n\t//\t\treturn true;\n\t//\t}\n\n\tpublic static final boolean checkVitamioLibs(Activity ctx, int msgID) {\n\t\tif ((!Vitamio.isInitialized(ctx)) && (!ctx.getIntent().getBooleanExtra(\"fromVitamioInitActivity\", false))) {\n\t\t\tIntent i = new Intent();\n\t\t\ti.setClassName(ctx.getPackageName(), \"com.nmbb.oplayer.ui.vitamio.InitActivity\");//io.vov.vitamio.activity.InitActivity\n\t\t\ti.putExtras(ctx.getIntent());\n\t\t\ti.setData(ctx.getIntent().getData());\n\t\t\ti.putExtra(\"package\", ctx.getPackageName());\n\t\t\ti.putExtra(\"className\", ctx.getClass().getName());\n\t\t\ti.putExtra(\"EXTRA_MSG\", msgID);\n\t\t\tctx.startActivity(i);\n\t\t\tctx.finish();\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/util/ApplicationUtils.java",
    "content": "package com.nmbb.oplayer.util;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.util.List;\n\nimport android.app.Activity;\nimport android.app.ActivityManager;\nimport android.content.Context;\nimport android.content.pm.ApplicationInfo;\nimport android.content.pm.PackageManager;\nimport android.content.pm.PackageManager.NameNotFoundException;\nimport android.os.Environment;\nimport android.widget.Toast;\n\npublic class ApplicationUtils {\n\t/**\n\t * 备份App 首先无需提升权限就就可以复制APK，查看权限你就会知道，在data/app下的APK权限如下：-rw-r--r-- system\n\t * system 5122972 2012-12-13 10:38 com.taobao.taobao-1.apk 我们是有读取权限的。\n\t * \n\t * @param packageName\n\t * @param mActivity\n\t * @throws IOException\n\t */\n\tpublic static void backupApp(String packageName, Activity mActivity)\n\t\t\tthrows IOException {\n\t\t// 存放位置\n\t\tString newFile = Environment.getExternalStorageDirectory()\n\t\t\t\t.getAbsolutePath() + File.separator;\n\t\tString oldFile = null;\n\t\ttry {\n\t\t\t// 原始位置\n\t\t\toldFile = mActivity.getPackageManager().getApplicationInfo(\n\t\t\t\t\tpackageName, 0).sourceDir;\n\t\t} catch (NameNotFoundException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\tSystem.out.println(newFile);\n\t\tSystem.out.println(oldFile);\n\n\t\tFile in = new File(oldFile);\n\t\tFile out = new File(newFile + packageName + \".apk\");\n\t\tif (!out.exists()) {\n\t\t\tout.createNewFile();\n\t\t\tToast.makeText(mActivity, \"文件备份成功！\" + \"存放于\" + newFile + \"目录下\", 1)\n\t\t\t\t\t.show();\n\t\t} else {\n\t\t\tToast.makeText(mActivity, \"文件已经存在！\" + \"查看\" + newFile + \"目录下\", 1)\n\t\t\t\t\t.show();\n\t\t}\n\n\t\tFileInputStream fis = new FileInputStream(in);\n\t\tFileOutputStream fos = new FileOutputStream(out);\n\n\t\tint count;\n\t\t// 文件太大的话，我觉得需要修改\n\t\tbyte[] buffer = new byte[256 * 1024];\n\t\twhile ((count = fis.read(buffer)) > 0) {\n\t\t\tfos.write(buffer, 0, count);\n\t\t}\n\n\t\tfis.close();\n\t\tfos.flush();\n\t\tfos.close();\n\t}\n\n\t/**\n\t * 获取当前Apk版本号 android:versionCode\n\t * \n\t * @param context\n\t * @return\n\t */\n\tpublic static int getVerCode(Context context) {\n\t\tint verCode = -1;\n\t\ttry {\n\t\t\tverCode = context.getPackageManager().getPackageInfo(\n\t\t\t\t\tcontext.getPackageName(), 0).versionCode;\n\t\t} catch (NameNotFoundException e) {\n\t\t}\n\t\treturn verCode;\n\t}\n\n\tpublic static String getVerName(Context context) {\n\t\ttry {\n\t\t\treturn context.getPackageManager().getPackageInfo(\n\t\t\t\t\tcontext.getPackageName(), 0).versionName;\n\t\t} catch (NameNotFoundException e) {\n\t\t}\n\t\treturn \"\";\n\t}\n\n\t/**\n\t * 返回当前的应用是否处于前台显示状态 不需要android.permission.GET_TASKS权限\n\t * http://zengrong.net/post/1680.htm\n\t * \n\t * @param packageName\n\t * @return\n\t */\n\tpublic static boolean isTopActivity(Context context, String packageName) {\n\t\t// _context是一个保存的上下文\n\t\tActivityManager am = (ActivityManager) context.getApplicationContext()\n\t\t\t\t.getSystemService(Context.ACTIVITY_SERVICE);\n\t\tList<ActivityManager.RunningAppProcessInfo> list = am\n\t\t\t\t.getRunningAppProcesses();\n\t\tif (list.size() == 0)\n\t\t\treturn false;\n\t\tfor (ActivityManager.RunningAppProcessInfo process : list) {\n\t\t\t// Log.d(getTAG(), Integer.toString(__process.importance));\n\t\t\t// Log.d(getTAG(), __process.processName);\n\t\t\tif (process.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND\n\t\t\t\t\t&& process.processName.equals(packageName)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 检测APP是否存在\n\t * @param context\n\t * @param packageName\n\t * @return\n\t */\n\tpublic static boolean checkAppExist(Context context, String packageName) {\n\t\ttry {\n\t\t\tApplicationInfo info = context.getPackageManager()\n\t\t\t\t\t.getApplicationInfo(packageName, 0);\n\t\t\treturn info != null && info.packageName.equals(packageName);\n\t\t} catch (PackageManager.NameNotFoundException e) {\n\n\t\t} catch (Exception e) {\n\t\t}\n\t\treturn false;\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/util/ArrayUtils.java",
    "content": "/*\n * Copyright (C) 2012 YIXIA.COM\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.nmbb.oplayer.util;\n\nimport java.lang.reflect.Array;\n\npublic class ArrayUtils {\n\tpublic static <T> T[] concat(T[] A, T[] B) {\n\t\tfinal Class<?> typeofA = A.getClass().getComponentType();\n\t\t@SuppressWarnings(\"unchecked\")\n\t\tT[] C = (T[]) Array.newInstance(typeofA, A.length + B.length);\n\t\tSystem.arraycopy(A, 0, C, 0, A.length);\n\t\tSystem.arraycopy(B, 0, C, A.length, B.length);\n\n\t\treturn C;\n\t}\n\t\n\tpublic static <T> int indexOf(T[] array, T s) {\n\t\tfor (int i = 0; i < array.length; i++) {\n\t\t\tif (array[i].equals(s)) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/util/ConvertUtils.java",
    "content": "package com.nmbb.oplayer.util;\n\nimport android.content.Context;\n\n/**\n * 数据转换类\n * \n * @author 农民伯伯\n * @see http://www.cnblogs.com/over140\n * \n */\npublic final class ConvertUtils {\n\n\tprivate static final float UNIT = 1000.0F;\n\n\t/**\n\t * 毫秒转秒\n\t * \n\t * @param time 毫秒\n\t * @return\n\t */\n\tpublic static float ms2s(long time) {\n\t\treturn time / UNIT;\n\t}\n\n\t/**\n\t * 微秒转秒\n\t * \n\t * @param time 微秒\n\t * @return\n\t */\n\tpublic static float us2s(long time) {\n\t\treturn time / UNIT / UNIT;\n\t}\n\n\t/**\n\t * 纳秒转秒\n\t * \n\t * @param time 纳秒\n\t * @return\n\t */\n\tpublic static float ns2s(long time) {\n\t\treturn time / UNIT / UNIT / UNIT;\n\t}\n\n\t/**\n\t * 转换字符串为boolean\n\t * \n\t * @param str\n\t * @return\n\t */\n\tpublic static boolean toBoolean(String str) {\n\t\treturn toBoolean(str, false);\n\t}\n\n\t/**\n\t * 转换字符串为boolean\n\t * \n\t * @param str\n\t * @param def\n\t * @return\n\t */\n\tpublic static boolean toBoolean(String str, boolean def) {\n\t\tif (StringUtils.isEmpty(str))\n\t\t\treturn def;\n\t\tif (\"false\".equalsIgnoreCase(str) || \"0\".equals(str))\n\t\t\treturn false;\n\t\telse if (\"true\".equalsIgnoreCase(str) || \"1\".equals(str))\n\t\t\treturn true;\n\t\telse\n\t\t\treturn def;\n\t}\n\n\t/**\n\t * 转换字符串为float\n\t * \n\t * @param str\n\t * @return\n\t */\n\tpublic static float toFloat(String str) {\n\t\treturn toFloat(str, 0F);\n\t}\n\n\t/**\n\t * 转换字符串为float\n\t * \n\t * @param str\n\t * @param def\n\t * @return\n\t */\n\tpublic static float toFloat(String str, float def) {\n\t\tif (StringUtils.isEmpty(str))\n\t\t\treturn def;\n\t\ttry {\n\t\t\treturn Float.parseFloat(str);\n\t\t} catch (NumberFormatException e) {\n\t\t\treturn def;\n\t\t}\n\t}\n\n\t/**\n\t * 转换字符串为long\n\t * \n\t * @param str\n\t * @return\n\t */\n\tpublic static long toLong(String str) {\n\t\treturn toLong(str, 0L);\n\t}\n\n\t/**\n\t * 转换字符串为long\n\t * \n\t * @param str\n\t * @param def\n\t * @return\n\t */\n\tpublic static long toLong(String str, long def) {\n\t\tif (StringUtils.isEmpty(str))\n\t\t\treturn def;\n\t\ttry {\n\t\t\treturn Long.parseLong(str);\n\t\t} catch (NumberFormatException e) {\n\t\t\treturn def;\n\t\t}\n\t}\n\n\t/**\n\t * 转换字符串为short\n\t * \n\t * @param str\n\t * @return\n\t */\n\tpublic static short toShort(String str) {\n\t\treturn toShort(str, (short) 0);\n\t}\n\n\t/**\n\t * 转换字符串为short\n\t * \n\t * @param str\n\t * @param def\n\t * @return\n\t */\n\tpublic static short toShort(String str, short def) {\n\t\tif (StringUtils.isEmpty(str))\n\t\t\treturn def;\n\t\ttry {\n\t\t\treturn Short.parseShort(str);\n\t\t} catch (NumberFormatException e) {\n\t\t\treturn def;\n\t\t}\n\t}\n\n\t/**\n\t * 转换字符串为int\n\t * \n\t * @param str\n\t * @return\n\t */\n\tpublic static int toInt(String str) {\n\t\treturn toInt(str, 0);\n\t}\n\n\t/**\n\t * 转换字符串为int\n\t * \n\t * @param str\n\t * @param def\n\t * @return\n\t */\n\tpublic static int toInt(String str, int def) {\n\t\tif (StringUtils.isEmpty(str))\n\t\t\treturn def;\n\t\ttry {\n\t\t\treturn Integer.parseInt(str);\n\t\t} catch (NumberFormatException e) {\n\t\t\treturn def;\n\t\t}\n\t}\n\n\tpublic static String toString(Object o) {\n\t\treturn toString(o, \"\");\n\t}\n\n\tpublic static String toString(Object o, String def) {\n\t\tif (o == null)\n\t\t\treturn def;\n\n\t\treturn o.toString();\n\t}\n\n\tpublic static int dipToPX(final Context ctx, int dip) {\n\t\tfloat scale = ctx.getResources().getDisplayMetrics().density;\n\t\treturn (int) (dip / 1.5D * scale + 0.5D);\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/util/DeviceUtils.java",
    "content": "package com.nmbb.oplayer.util;\n\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.FileReader;\nimport java.io.IOException;\nimport java.util.List;\n\nimport android.app.Activity;\nimport android.content.ComponentName;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.content.pm.PackageInfo;\nimport android.content.pm.PackageManager;\nimport android.content.pm.PackageManager.NameNotFoundException;\nimport android.content.pm.ResolveInfo;\nimport android.content.res.Configuration;\nimport android.os.Build;\nimport android.os.Environment;\nimport android.os.StatFs;\nimport android.util.DisplayMetrics;\nimport android.view.Display;\nimport android.view.View;\nimport android.view.WindowManager;\nimport android.view.inputmethod.InputMethodManager;\n\nimport com.nmbb.oplayer.exception.Logger;\n\n/**\n * 系统版本信息类\n * \n * @author tangjun\n * \n */\npublic class DeviceUtils {\n\n\t/** >=2.2 */\n\tpublic static boolean hasFroyo() {\n\t\treturn Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO;\n\t}\n\n\t/** >=2.3 */\n\tpublic static boolean hasGingerbread() {\n\t\treturn Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD;\n\t}\n\n\t/** >=3.0 LEVEL:11 */\n\tpublic static boolean hasHoneycomb() {\n\t\treturn Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;\n\t}\n\n\t/** >=3.1 */\n\tpublic static boolean hasHoneycombMR1() {\n\t\treturn Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1;\n\t}\n\n\t/** >=4.0 14 */\n\tpublic static boolean hasICS() {\n\t\treturn Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;\n\t}\n\n\tpublic static int getSDKVersionInt() {\n\t\treturn Build.VERSION.SDK_INT;\n\t}\n\n\t@SuppressWarnings(\"deprecation\")\n\tpublic static String getSDKVersion() {\n\t\treturn Build.VERSION.SDK;\n\t}\n\n\t/**\n\t * 判断是否是平板电脑\n\t * \n\t * @param context\n\t * @return\n\t */\n\tpublic static boolean isTablet(Context context) {\n\t\treturn (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE;\n\t}\n\n\tpublic static boolean isHoneycombTablet(Context context) {\n\t\treturn hasHoneycomb() && isTablet(context);\n\t}\n\n\t/**\n\t * 获得设备型号\n\t * \n\t * @return\n\t */\n\tpublic static String getDeviceModel() {\n\t\treturn StringUtils.trim(Build.MODEL);\n\t}\n\n\t/** 检测是否魅族手机 */\n\tpublic static boolean isMeizu() {\n\t\treturn getDeviceModel().toLowerCase().indexOf(\"meizu\") != -1;\n\t}\n\n\t/** 检测是否HTC手机 */\n\tpublic static boolean isHTC() {\n\t\treturn getDeviceModel().toLowerCase().indexOf(\"htc\") != -1;\n\t}\n\t\n\tpublic static boolean isXiaomi() {\n\t\treturn getDeviceModel().toLowerCase().indexOf(\"xiaomi\") != -1;\n\t}\n\n\t/**\n\t * 获得设备制造商\n\t * \n\t * @return\n\t */\n\tpublic static String getManufacturer() {\n\t\treturn StringUtils.trim(Build.MANUFACTURER);\n\t}\n\n\t@SuppressWarnings(\"deprecation\")\n\tpublic static int getScreenHeight(Context context) {\n\t\tDisplay display = ((WindowManager) context\n\t\t\t\t.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();\n\t\treturn display.getHeight();\n\t}\n\n\t/** 获取屏幕宽度 */\n\t@SuppressWarnings(\"deprecation\")\n\tpublic static int getScreenWidth(Context context) {\n\t\tDisplay display = ((WindowManager) context\n\t\t\t\t.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();\n\t\treturn display.getWidth();\n\t}\n\n\t/**\n\t * 获得设备屏幕密度\n\t */\n\tpublic static float getScreenDensity(Context context) {\n\t\tDisplayMetrics metrics = context.getApplicationContext().getResources()\n\t\t\t\t.getDisplayMetrics();\n\t\treturn metrics.density;\n\t}\n\n\tpublic static int[] getScreenSize(int w, int h, Context context) {\n\t\tint phoneW = getScreenWidth(context);\n\t\tint phoneH = getScreenHeight(context);\n\n\t\tif (w * phoneH > phoneW * h) {\n\t\t\tphoneH = phoneW * h / w;\n\t\t} else if (w * phoneH < phoneW * h) {\n\t\t\tphoneW = phoneH * w / h;\n\t\t}\n\n\t\treturn new int[] { phoneW, phoneH };\n\t}\n\n\tpublic static int[] getScreenSize(int w, int h, int phoneW, int phoneH) {\n\t\tif (w * phoneH > phoneW * h) {\n\t\t\tphoneH = phoneW * h / w;\n\t\t} else if (w * phoneH < phoneW * h) {\n\t\t\tphoneW = phoneH * w / h;\n\t\t}\n\t\treturn new int[] { phoneW, phoneH };\n\t}\n\n\t/** 设置屏幕亮度 */\n\tpublic static void setBrightness(final Activity context, float f) {\n\t\tWindowManager.LayoutParams lp = context.getWindow().getAttributes();\n\t\tlp.screenBrightness = f;\n\t\tif (lp.screenBrightness > 1.0f)\n\t\t\tlp.screenBrightness = 1.0f;\n\t\telse if (lp.screenBrightness < 0.01f)\n\t\t\tlp.screenBrightness = 0.01f;\n\t\tcontext.getWindow().setAttributes(lp);\n\t}\n\n\t// private static final long NO_STORAGE_ERROR = -1L;\n\tprivate static final long CANNOT_STAT_ERROR = -2L;\n\n\t/** 检测磁盘状态 */\n\t// public static int getStorageStatus(boolean mayHaveSd) {\n\t// long remaining = mayHaveSd ? getAvailableStorage() : NO_STORAGE_ERROR;\n\t// if (remaining == NO_STORAGE_ERROR) {\n\t// return CommonStatus.STORAGE_STATUS_NONE;\n\t// }\n\t// return remaining < CommonConstants.LOW_STORAGE_THRESHOLD ?\n\t// CommonStatus.STORAGE_STATUS_LOW : CommonStatus.STORAGE_STATUS_OK;\n\t// }\n\n\tpublic static long getAvailableStorage() {\n\t\ttry {\n\t\t\tString storageDirectory = Environment.getExternalStorageDirectory()\n\t\t\t\t\t.toString();\n\t\t\tStatFs stat = new StatFs(storageDirectory);\n\t\t\treturn (long) stat.getAvailableBlocks()\n\t\t\t\t\t* (long) stat.getBlockSize();\n\t\t} catch (RuntimeException ex) {\n\t\t\t// if we can't stat the filesystem then we don't know how many\n\t\t\t// free bytes exist. It might be zero but just leave it\n\t\t\t// blank since we really don't know.\n\t\t\treturn CANNOT_STAT_ERROR;\n\t\t}\n\t}\n\n\t/** 隐藏软键盘 */\n\tpublic static void hideSoftInput(Context ctx, View v) {\n\t\tInputMethodManager imm = (InputMethodManager) ctx\n\t\t\t\t.getSystemService(Context.INPUT_METHOD_SERVICE);\n\t\t// 这个方法可以实现输入法在窗口上切换显示，如果输入法在窗口上已经显示，则隐藏，如果隐藏，则显示输入法到窗口上\n\t\timm.hideSoftInputFromWindow(v.getApplicationWindowToken(),\n\t\t\t\tInputMethodManager.HIDE_NOT_ALWAYS);\n\t}\n\n\t/** 显示软键盘 */\n\tpublic static void showSoftInput(Context ctx) {\n\t\tInputMethodManager imm = (InputMethodManager) ctx\n\t\t\t\t.getSystemService(Context.INPUT_METHOD_SERVICE);\n\t\timm.toggleSoftInput(0, InputMethodManager.SHOW_FORCED);// (v,\n\t\t// InputMethodManager.SHOW_FORCED);\n\t}\n\n\t/**\n\t * 软键盘是否已经打开\n\t * \n\t * @return\n\t */\n\tprotected boolean isHardKeyboardOpen(Context ctx) {\n\t\treturn ctx.getResources().getConfiguration().hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO;\n\t}\n\n\tpublic static String getCpuInfo() {\n\t\tString cpuInfo = \"\";\n\t\ttry {\n\t\t\tif (new File(\"/proc/cpuinfo\").exists()) {\n\t\t\t\tFileReader fr = new FileReader(\"/proc/cpuinfo\");\n\t\t\t\tBufferedReader localBufferedReader = new BufferedReader(fr,\n\t\t\t\t\t\t8192);\n\t\t\t\tcpuInfo = localBufferedReader.readLine();\n\t\t\t\tlocalBufferedReader.close();\n\n\t\t\t\tif (cpuInfo != null) {\n\t\t\t\t\tcpuInfo = cpuInfo.split(\":\")[1].trim().split(\" \")[0];\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (IOException e) {\n\t\t} catch (Exception e) {\n\t\t}\n\t\treturn cpuInfo;\n\t}\n\n\tpublic static void startApkActivity(final Context ctx, String packageName) {\n\t\tPackageManager pm = ctx.getPackageManager();\n\t\tPackageInfo pi;\n\t\ttry {\n\t\t\tpi = pm.getPackageInfo(packageName, 0);\n\t\t\tIntent intent = new Intent(Intent.ACTION_MAIN, null);\n\t\t\tintent.addCategory(Intent.CATEGORY_LAUNCHER);\n\t\t\tintent.setPackage(pi.packageName);\n\n\t\t\tList<ResolveInfo> apps = pm.queryIntentActivities(intent, 0);\n\n\t\t\tResolveInfo ri = apps.iterator().next();\n\t\t\tif (ri != null) {\n\t\t\t\tString className = ri.activityInfo.name;\n\t\t\t\tintent.setComponent(new ComponentName(packageName, className));\n\t\t\t\tctx.startActivity(intent);\n\t\t\t}\n\t\t} catch (NameNotFoundException e) {\n\t\t\tLogger.e(e);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/util/FileUtils.java",
    "content": "package com.nmbb.oplayer.util;\r\n\r\nimport java.io.File;\r\nimport java.io.IOException;\r\nimport java.util.Arrays;\r\nimport java.util.HashMap;\r\nimport java.util.HashSet;\r\nimport java.util.Map;\r\n\r\nimport android.os.Environment;\r\nimport android.os.StatFs;\r\nimport android.util.Log;\r\n\r\npublic class FileUtils {\r\n\t// http://www.fileinfo.com/filetypes/video , \"dat\" , \"bin\" , \"rms\"\r\n\tpublic static final String[] VIDEO_EXTENSIONS = { \"264\", \"3g2\", \"3gp\",\r\n\t\t\t\"3gp2\", \"3gpp\", \"3gpp2\", \"3mm\", \"3p2\", \"60d\", \"aep\", \"ajp\", \"amv\",\r\n\t\t\t\"amx\", \"arf\", \"asf\", \"asx\", \"avb\", \"avd\", \"avi\", \"avs\", \"avs\",\r\n\t\t\t\"axm\", \"bdm\", \"bdmv\", \"bik\", \"bix\", \"bmk\", \"box\", \"bs4\", \"bsf\",\r\n\t\t\t\"byu\", \"camre\", \"clpi\", \"cpi\", \"cvc\", \"d2v\", \"d3v\", \"dav\", \"dce\",\r\n\t\t\t\"dck\", \"ddat\", \"dif\", \"dir\", \"divx\", \"dlx\", \"dmb\", \"dmsm\", \"dmss\",\r\n\t\t\t\"dnc\", \"dpg\", \"dream\", \"dsy\", \"dv\", \"dv-avi\", \"dv4\", \"dvdmedia\",\r\n\t\t\t\"dvr-ms\", \"dvx\", \"dxr\", \"dzm\", \"dzp\", \"dzt\", \"evo\", \"eye\", \"f4p\",\r\n\t\t\t\"f4v\", \"fbr\", \"fbr\", \"fbz\", \"fcp\", \"flc\", \"flh\", \"fli\", \"flv\",\r\n\t\t\t\"flx\", \"gl\", \"grasp\", \"gts\", \"gvi\", \"gvp\", \"hdmov\", \"hkm\", \"ifo\",\r\n\t\t\t\"imovi\", \"imovi\", \"iva\", \"ivf\", \"ivr\", \"ivs\", \"izz\", \"izzy\", \"jts\",\r\n\t\t\t\"lsf\", \"lsx\", \"m15\", \"m1pg\", \"m1v\", \"m21\", \"m21\", \"m2a\", \"m2p\",\r\n\t\t\t\"m2t\", \"m2ts\", \"m2v\", \"m4e\", \"m4u\", \"m4v\", \"m75\", \"meta\", \"mgv\",\r\n\t\t\t\"mj2\", \"mjp\", \"mjpg\", \"mkv\", \"mmv\", \"mnv\", \"mod\", \"modd\", \"moff\",\r\n\t\t\t\"moi\", \"moov\", \"mov\", \"movie\", \"mp21\", \"mp21\", \"mp2v\", \"mp4\",\r\n\t\t\t\"mp4v\", \"mpe\", \"mpeg\", \"mpeg4\", \"mpf\", \"mpg\", \"mpg2\", \"mpgin\",\r\n\t\t\t\"mpl\", \"mpls\", \"mpv\", \"mpv2\", \"mqv\", \"msdvd\", \"msh\", \"mswmm\",\r\n\t\t\t\"mts\", \"mtv\", \"mvb\", \"mvc\", \"mvd\", \"mve\", \"mvp\", \"mxf\", \"mys\",\r\n\t\t\t\"ncor\", \"nsv\", \"nvc\", \"ogm\", \"ogv\", \"ogx\", \"osp\", \"par\", \"pds\",\r\n\t\t\t\"pgi\", \"piv\", \"playlist\", \"pmf\", \"prel\", \"pro\", \"prproj\", \"psh\",\r\n\t\t\t\"pva\", \"pvr\", \"pxv\", \"qt\", \"qtch\", \"qtl\", \"qtm\", \"qtz\",\r\n\t\t\t\"rcproject\", \"rdb\", \"rec\", \"rm\", \"rmd\", \"rmp\", \"rmvb\", \"roq\", \"rp\",\r\n\t\t\t\"rts\", \"rts\", \"rum\", \"rv\", \"sbk\", \"sbt\", \"scm\", \"scm\", \"scn\",\r\n\t\t\t\"sec\", \"seq\", \"sfvidcap\", \"smil\", \"smk\", \"sml\", \"smv\", \"spl\",\r\n\t\t\t\"ssm\", \"str\", \"stx\", \"svi\", \"swf\", \"swi\", \"swt\", \"tda3mt\", \"tivo\",\r\n\t\t\t\"tix\", \"tod\", \"tp\", \"tp0\", \"tpd\", \"tpr\", \"trp\", \"ts\", \"tvs\", \"vc1\",\r\n\t\t\t\"vcr\", \"vcv\", \"vdo\", \"vdr\", \"veg\", \"vem\", \"vf\", \"vfw\", \"vfz\",\r\n\t\t\t\"vgz\", \"vid\", \"viewlet\", \"viv\", \"vivo\", \"vlab\", \"vob\", \"vp3\",\r\n\t\t\t\"vp6\", \"vp7\", \"vpj\", \"vro\", \"vsp\", \"w32\", \"wcp\", \"webm\", \"wm\",\r\n\t\t\t\"wmd\", \"wmmp\", \"wmv\", \"wmx\", \"wp3\", \"wpl\", \"wtv\", \"wvx\", \"xfl\",\r\n\t\t\t\"xvid\", \"yuv\", \"zm1\", \"zm2\", \"zm3\", \"zmv\" };\r\n\t// http://www.fileinfo.com/filetypes/audio , \"spx\" , \"mid\" , \"sf\"\r\n\tpublic static final String[] AUDIO_EXTENSIONS = { \"4mp\", \"669\", \"6cm\",\r\n\t\t\t\"8cm\", \"8med\", \"8svx\", \"a2m\", \"aa\", \"aa3\", \"aac\", \"aax\", \"abc\",\r\n\t\t\t\"abm\", \"ac3\", \"acd\", \"acd-bak\", \"acd-zip\", \"acm\", \"act\", \"adg\",\r\n\t\t\t\"afc\", \"agm\", \"ahx\", \"aif\", \"aifc\", \"aiff\", \"ais\", \"akp\", \"al\",\r\n\t\t\t\"alaw\", \"all\", \"amf\", \"amr\", \"ams\", \"ams\", \"aob\", \"ape\", \"apf\",\r\n\t\t\t\"apl\", \"ase\", \"at3\", \"atrac\", \"au\", \"aud\", \"aup\", \"avr\", \"awb\",\r\n\t\t\t\"band\", \"bap\", \"bdd\", \"box\", \"bun\", \"bwf\", \"c01\", \"caf\", \"cda\",\r\n\t\t\t\"cdda\", \"cdr\", \"cel\", \"cfa\", \"cidb\", \"cmf\", \"copy\", \"cpr\", \"cpt\",\r\n\t\t\t\"csh\", \"cwp\", \"d00\", \"d01\", \"dcf\", \"dcm\", \"dct\", \"ddt\", \"dewf\",\r\n\t\t\t\"df2\", \"dfc\", \"dig\", \"dig\", \"dls\", \"dm\", \"dmf\", \"dmsa\", \"dmse\",\r\n\t\t\t\"drg\", \"dsf\", \"dsm\", \"dsp\", \"dss\", \"dtm\", \"dts\", \"dtshd\", \"dvf\",\r\n\t\t\t\"dwd\", \"ear\", \"efa\", \"efe\", \"efk\", \"efq\", \"efs\", \"efv\", \"emd\",\r\n\t\t\t\"emp\", \"emx\", \"esps\", \"f2r\", \"f32\", \"f3r\", \"f4a\", \"f64\", \"far\",\r\n\t\t\t\"fff\", \"flac\", \"flp\", \"fls\", \"frg\", \"fsm\", \"fzb\", \"fzf\", \"fzv\",\r\n\t\t\t\"g721\", \"g723\", \"g726\", \"gig\", \"gp5\", \"gpk\", \"gsm\", \"gsm\", \"h0\",\r\n\t\t\t\"hdp\", \"hma\", \"hsb\", \"ics\", \"iff\", \"imf\", \"imp\", \"ins\", \"ins\",\r\n\t\t\t\"it\", \"iti\", \"its\", \"jam\", \"k25\", \"k26\", \"kar\", \"kin\", \"kit\",\r\n\t\t\t\"kmp\", \"koz\", \"koz\", \"kpl\", \"krz\", \"ksc\", \"ksf\", \"kt2\", \"kt3\",\r\n\t\t\t\"ktp\", \"l\", \"la\", \"lqt\", \"lso\", \"lvp\", \"lwv\", \"m1a\", \"m3u\", \"m4a\",\r\n\t\t\t\"m4b\", \"m4p\", \"m4r\", \"ma1\", \"mdl\", \"med\", \"mgv\", \"midi\", \"miniusf\",\r\n\t\t\t\"mka\", \"mlp\", \"mmf\", \"mmm\", \"mmp\", \"mo3\", \"mod\", \"mp1\", \"mp2\",\r\n\t\t\t\"mp3\", \"mpa\", \"mpc\", \"mpga\", \"mpu\", \"mp_\", \"mscx\", \"mscz\", \"msv\",\r\n\t\t\t\"mt2\", \"mt9\", \"mte\", \"mti\", \"mtm\", \"mtp\", \"mts\", \"mus\", \"mws\",\r\n\t\t\t\"mxl\", \"mzp\", \"nap\", \"nki\", \"nra\", \"nrt\", \"nsa\", \"nsf\", \"nst\",\r\n\t\t\t\"ntn\", \"nvf\", \"nwc\", \"odm\", \"oga\", \"ogg\", \"okt\", \"oma\", \"omf\",\r\n\t\t\t\"omg\", \"omx\", \"ots\", \"ove\", \"ovw\", \"pac\", \"pat\", \"pbf\", \"pca\",\r\n\t\t\t\"pcast\", \"pcg\", \"pcm\", \"peak\", \"phy\", \"pk\", \"pla\", \"pls\", \"pna\",\r\n\t\t\t\"ppc\", \"ppcx\", \"prg\", \"prg\", \"psf\", \"psm\", \"ptf\", \"ptm\", \"pts\",\r\n\t\t\t\"pvc\", \"qcp\", \"r\", \"r1m\", \"ra\", \"ram\", \"raw\", \"rax\", \"rbs\", \"rcy\",\r\n\t\t\t\"rex\", \"rfl\", \"rmf\", \"rmi\", \"rmj\", \"rmm\", \"rmx\", \"rng\", \"rns\",\r\n\t\t\t\"rol\", \"rsn\", \"rso\", \"rti\", \"rtm\", \"rts\", \"rvx\", \"rx2\", \"s3i\",\r\n\t\t\t\"s3m\", \"s3z\", \"saf\", \"sam\", \"sb\", \"sbg\", \"sbi\", \"sbk\", \"sc2\", \"sd\",\r\n\t\t\t\"sd\", \"sd2\", \"sd2f\", \"sdat\", \"sdii\", \"sds\", \"sdt\", \"sdx\", \"seg\",\r\n\t\t\t\"seq\", \"ses\", \"sf2\", \"sfk\", \"sfl\", \"shn\", \"sib\", \"sid\", \"sid\",\r\n\t\t\t\"smf\", \"smp\", \"snd\", \"snd\", \"snd\", \"sng\", \"sng\", \"sou\", \"sppack\",\r\n\t\t\t\"sprg\", \"sseq\", \"sseq\", \"ssnd\", \"stm\", \"stx\", \"sty\", \"svx\", \"sw\",\r\n\t\t\t\"swa\", \"syh\", \"syw\", \"syx\", \"td0\", \"tfmx\", \"thx\", \"toc\", \"tsp\",\r\n\t\t\t\"txw\", \"u\", \"ub\", \"ulaw\", \"ult\", \"ulw\", \"uni\", \"usf\", \"usflib\",\r\n\t\t\t\"uw\", \"uwf\", \"vag\", \"val\", \"vc3\", \"vmd\", \"vmf\", \"vmf\", \"voc\",\r\n\t\t\t\"voi\", \"vox\", \"vpm\", \"vqf\", \"vrf\", \"vyf\", \"w01\", \"wav\", \"wav\",\r\n\t\t\t\"wave\", \"wax\", \"wfb\", \"wfd\", \"wfp\", \"wma\", \"wow\", \"wpk\", \"wproj\",\r\n\t\t\t\"wrk\", \"wus\", \"wut\", \"wv\", \"wvc\", \"wve\", \"wwu\", \"xa\", \"xa\", \"xfs\",\r\n\t\t\t\"xi\", \"xm\", \"xmf\", \"xmi\", \"xmz\", \"xp\", \"xrns\", \"xsb\", \"xspf\", \"xt\",\r\n\t\t\t\"xwb\", \"ym\", \"zvd\", \"zvr\" };\r\n\r\n\tprivate static final HashSet<String> mHashVideo;\r\n\tprivate static final HashSet<String> mHashAudio;\r\n\tprivate static final double KB = 1024.0;\r\n\tprivate static final double MB = KB * KB;\r\n\tprivate static final double GB = KB * KB * KB;\r\n\r\n\tstatic {\r\n\t\tmHashVideo = new HashSet<String>(Arrays.asList(VIDEO_EXTENSIONS));\r\n\t\tmHashAudio = new HashSet<String>(Arrays.asList(AUDIO_EXTENSIONS));\r\n\t}\r\n\r\n\t/** 是否是音频或者视频 */\r\n\tpublic static boolean isVideoOrAudio(File f) {\r\n\t\tfinal String ext = getFileExtension(f);\r\n\t\treturn mHashVideo.contains(ext) || mHashAudio.contains(ext);\r\n\t}\r\n\r\n\tpublic static boolean isVideoOrAudio(String f) {\r\n\t\tfinal String ext = getUrlExtension(f);\r\n\t\treturn mHashVideo.contains(ext) || mHashAudio.contains(ext);\r\n\t}\r\n\r\n\tpublic static boolean isVideo(File f) {\r\n\t\tfinal String ext = getFileExtension(f);\r\n\t\treturn mHashVideo.contains(ext);\r\n\t}\r\n\r\n\t/** 获取文件后缀 */\r\n\tpublic static String getFileExtension(File f) {\r\n\t\tif (f != null) {\r\n\t\t\tString filename = f.getName();\r\n\t\t\tint i = filename.lastIndexOf('.');\r\n\t\t\tif (i > 0 && i < filename.length() - 1) {\r\n\t\t\t\treturn filename.substring(i + 1).toLowerCase();\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn null;\r\n\t}\r\n\r\n\tpublic static String getUrlFileName(String url) {\r\n\t\tint slashIndex = url.lastIndexOf('/');\r\n\t\tint dotIndex = url.lastIndexOf('.');\r\n\t\tString filenameWithoutExtension;\r\n\t\tif (dotIndex == -1) {\r\n\t\t\tfilenameWithoutExtension = url.substring(slashIndex + 1);\r\n\t\t} else {\r\n\t\t\tfilenameWithoutExtension = url.substring(slashIndex + 1, dotIndex);\r\n\t\t}\r\n\t\treturn filenameWithoutExtension;\r\n\t}\r\n\r\n\tpublic static String getUrlExtension(String url) {\r\n\t\tif (!StringUtils.isEmpty(url)) {\r\n\t\t\tint i = url.lastIndexOf('.');\r\n\t\t\tif (i > 0 && i < url.length() - 1) {\r\n\t\t\t\treturn url.substring(i + 1).toLowerCase();\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn \"\";\r\n\t}\r\n\r\n\tpublic static String getFileNameNoEx(String filename) {\r\n\t\tif ((filename != null) && (filename.length() > 0)) {\r\n\t\t\tint dot = filename.lastIndexOf('.');\r\n\t\t\tif ((dot > -1) && (dot < (filename.length()))) {\r\n\t\t\t\treturn filename.substring(0, dot);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn filename;\r\n\t}\r\n\r\n\tpublic static String showFileSize(long size) {\r\n\t\tString fileSize;\r\n\t\tif (size < KB)\r\n\t\t\tfileSize = size + \"B\";\r\n\t\telse if (size < MB)\r\n\t\t\tfileSize = String.format(\"%.1f\", size / KB) + \"KB\";\r\n\t\telse if (size < GB)\r\n\t\t\tfileSize = String.format(\"%.1f\", size / MB) + \"MB\";\r\n\t\telse\r\n\t\t\tfileSize = String.format(\"%.1f\", size / GB) + \"GB\";\r\n\r\n\t\treturn fileSize;\r\n\t}\r\n\r\n\t/** 显示SD卡剩余空间 */\r\n\tpublic static String showFileAvailable() {\r\n\t\tString result = \"\";\r\n\t\tif (Environment.MEDIA_MOUNTED.equals(Environment\r\n\t\t\t\t.getExternalStorageState())) {\r\n\t\t\tStatFs sf = new StatFs(Environment.getExternalStorageDirectory()\r\n\t\t\t\t\t.getPath());\r\n\t\t\tlong blockSize = sf.getBlockSize();\r\n\t\t\tlong blockCount = sf.getBlockCount();\r\n\t\t\tlong availCount = sf.getAvailableBlocks();\r\n\t\t\treturn showFileSize(availCount * blockSize) + \" / \"\r\n\t\t\t\t\t+ showFileSize(blockSize * blockCount);\r\n\t\t}\r\n\t\treturn result;\r\n\t}\r\n\r\n\t/** 如果不存在就创建 */\r\n\tpublic static boolean createIfNoExists(String path) {\r\n\t\tFile file = new File(path);\r\n\t\tboolean mk = false;\r\n\t\tif (!file.exists()) {\r\n\t\t\tmk = file.mkdirs();\r\n\t\t}\r\n\t\treturn mk;\r\n\t}\r\n\r\n\tprivate static HashMap<String, String> mMimeType = new HashMap<String, String>();\r\n\tstatic {\r\n\t\tmMimeType.put(\"M1V\", \"video/mpeg\");\r\n\t\tmMimeType.put(\"MP2\", \"video/mpeg\");\r\n\t\tmMimeType.put(\"MPE\", \"video/mpeg\");\r\n\t\tmMimeType.put(\"MPG\", \"video/mpeg\");\r\n\t\tmMimeType.put(\"MPEG\", \"video/mpeg\");\r\n\t\tmMimeType.put(\"MP4\", \"video/mp4\");\r\n\t\tmMimeType.put(\"M4V\", \"video/mp4\");\r\n\t\tmMimeType.put(\"3GP\", \"video/3gpp\");\r\n\t\tmMimeType.put(\"3GPP\", \"video/3gpp\");\r\n\t\tmMimeType.put(\"3G2\", \"video/3gpp2\");\r\n\t\tmMimeType.put(\"3GPP2\", \"video/3gpp2\");\r\n\t\tmMimeType.put(\"MKV\", \"video/x-matroska\");\r\n\t\tmMimeType.put(\"WEBM\", \"video/x-matroska\");\r\n\t\tmMimeType.put(\"MTS\", \"video/mp2ts\");\r\n\t\tmMimeType.put(\"TS\", \"video/mp2ts\");\r\n\t\tmMimeType.put(\"TP\", \"video/mp2ts\");\r\n\t\tmMimeType.put(\"WMV\", \"video/x-ms-wmv\");\r\n\t\tmMimeType.put(\"ASF\", \"video/x-ms-asf\");\r\n\t\tmMimeType.put(\"ASX\", \"video/x-ms-asf\");\r\n\t\tmMimeType.put(\"FLV\", \"video/x-flv\");\r\n\t\tmMimeType.put(\"MOV\", \"video/quicktime\");\r\n\t\tmMimeType.put(\"QT\", \"video/quicktime\");\r\n\t\tmMimeType.put(\"RM\", \"video/x-pn-realvideo\");\r\n\t\tmMimeType.put(\"RMVB\", \"video/x-pn-realvideo\");\r\n\t\tmMimeType.put(\"VOB\", \"video/dvd\");\r\n\t\tmMimeType.put(\"DAT\", \"video/dvd\");\r\n\t\tmMimeType.put(\"AVI\", \"video/x-divx\");\r\n\t\tmMimeType.put(\"OGV\", \"video/ogg\");\r\n\t\tmMimeType.put(\"OGG\", \"video/ogg\");\r\n\t\tmMimeType.put(\"VIV\", \"video/vnd.vivo\");\r\n\t\tmMimeType.put(\"VIVO\", \"video/vnd.vivo\");\r\n\t\tmMimeType.put(\"WTV\", \"video/wtv\");\r\n\t\tmMimeType.put(\"AVS\", \"video/avs-video\");\r\n\t\tmMimeType.put(\"SWF\", \"video/x-shockwave-flash\");\r\n\t\tmMimeType.put(\"YUV\", \"video/x-raw-yuv\");\r\n\t}\r\n\r\n\t/** 获取MIME */\r\n\tpublic static String getMimeType(String path) {\r\n\t\tint lastDot = path.lastIndexOf(\".\");\r\n\t\tif (lastDot < 0)\r\n\t\t\treturn null;\r\n\r\n\t\treturn mMimeType.get(path.substring(lastDot + 1).toUpperCase());\r\n\t}\r\n\r\n\t/** 多个SD卡时 取外置SD卡 */\r\n\tpublic static String getExternalStorageDirectory() {\r\n\t\t// 参考文章\r\n\t\t// http://blog.csdn.net/bbmiku/article/details/7937745\r\n\t\tMap<String, String> map = System.getenv();\r\n\t\tString[] values = new String[map.values().size()];\r\n\t\tmap.values().toArray(values);\r\n\t\tString path = values[values.length - 1];\r\n\t\tLog.e(\"nmbb\", \"FileUtils.getExternalStorageDirectory : \" + path);\r\n\t\tif (path.startsWith(\"/mnt/\")\r\n\t\t\t\t&& !Environment.getExternalStorageDirectory().getAbsolutePath()\r\n\t\t\t\t\t\t.equals(path))\r\n\t\t\treturn path;\r\n\t\telse\r\n\t\t\treturn null;\r\n\t}\r\n\r\n\tpublic static String getCanonical(File f) {\r\n\t\tif (f == null)\r\n\t\t\treturn null;\r\n\r\n\t\ttry {\r\n\t\t\treturn f.getCanonicalPath();\r\n\t\t} catch (IOException e) {\r\n\t\t\treturn f.getAbsolutePath();\r\n\t\t}\r\n\t}\r\n\t\r\n\tpublic static boolean sdAvailable() {\r\n\t\treturn Environment.MEDIA_MOUNTED_READ_ONLY.equals(Environment\r\n\t\t\t\t.getExternalStorageState())\r\n\t\t\t\t|| Environment.MEDIA_MOUNTED.equals(Environment\r\n\t\t\t\t\t\t.getExternalStorageState());\r\n\t}\r\n}\r\n"
  },
  {
    "path": "src/com/nmbb/oplayer/util/FractionalTouchDelegate.java",
    "content": "/*\n * Copyright (C) 2012 YIXIA.COM\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.nmbb.oplayer.util;\n\nimport android.graphics.Rect;\nimport android.graphics.RectF;\nimport android.view.MotionEvent;\nimport android.view.TouchDelegate;\nimport android.view.View;\n\n/**\n * {@link TouchDelegate} that gates {@link MotionEvent} instances by comparing\n * then against fractional dimensions of the source view.\n * <p>\n * This is particularly useful when you want to define a rectangle in terms of\n * the source dimensions, but when those dimensions might change due to pending\n * or future layout passes.\n * <p>\n * One example is catching touches that occur in the top-right quadrant of\n * {@code sourceParent}, and relaying them to {@code targetChild}. This could be\n * done with: <code>\n * FractionalTouchDelegate.setupDelegate(sourceParent, targetChild, new RectF(0.5f, 0f, 1f, 0.5f));\n * </code>\n */\npublic class FractionalTouchDelegate extends TouchDelegate {\n\n    private View mSource;\n    private View mTarget;\n\n    private RectF mSourceFraction;\n\n    private Rect mScrap = new Rect();\n\n    /** Cached full dimensions of {@link #mSource}. */\n    private Rect mSourceFull = new Rect();\n    /** Cached projection of {@link #mSourceFraction} onto {@link #mSource}. */\n    private Rect mSourcePartial = new Rect();\n\n    private boolean mDelegateTargeted;\n\n    public FractionalTouchDelegate(View source, View target, RectF sourceFraction) {\n        super(new Rect(0, 0, 0, 0), target);\n        mSource = source;\n        mTarget = target;\n        mSourceFraction = sourceFraction;\n    }\n\n    /**\n     * Helper to create and setup a {@link FractionalTouchDelegate} between the\n     * given {@link View}.\n     *\n     * @param source Larger source {@link View}, usually a parent, that will be\n     *            assigned {@link View#setTouchDelegate(TouchDelegate)}.\n     * @param target Smaller target {@link View} which will receive\n     *            {@link MotionEvent} that land in requested fractional area.\n     * @param sourceFraction Fractional area projected onto source {@link View}\n     *            which determines when {@link MotionEvent} will be passed to\n     *            target {@link View}.\n     */\n    public static void setupDelegate(View source, View target, RectF sourceFraction) {\n        source.setTouchDelegate(new FractionalTouchDelegate(source, target, sourceFraction));\n    }\n\n    /**\n     * Consider updating {@link #mSourcePartial} when {@link #mSource}\n     * dimensions have changed.\n     */\n    private void updateSourcePartial() {\n        mSource.getHitRect(mScrap);\n        if (!mScrap.equals(mSourceFull)) {\n            // Copy over and calculate fractional rectangle\n            mSourceFull.set(mScrap);\n\n            final int width = mSourceFull.width();\n            final int height = mSourceFull.height();\n\n            mSourcePartial.left = (int) (mSourceFraction.left * width);\n            mSourcePartial.top = (int) (mSourceFraction.top * height);\n            mSourcePartial.right = (int) (mSourceFraction.right * width);\n            mSourcePartial.bottom = (int) (mSourceFraction.bottom * height);\n        }\n    }\n\n    @Override\n    public boolean onTouchEvent(MotionEvent event) {\n        updateSourcePartial();\n\n        // The logic below is mostly copied from the parent class, since we\n        // can't update private mBounds variable.\n\n        // http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;\n        // f=core/java/android/view/TouchDelegate.java;hb=eclair#l98\n\n        final Rect sourcePartial = mSourcePartial;\n        final View target = mTarget;\n\n        int x = (int)event.getX();\n        int y = (int)event.getY();\n\n        boolean sendToDelegate = false;\n        boolean hit = true;\n        boolean handled = false;\n\n        switch (event.getAction()) {\n        case MotionEvent.ACTION_DOWN:\n            if (sourcePartial.contains(x, y)) {\n                mDelegateTargeted = true;\n                sendToDelegate = true;\n            }\n            break;\n        case MotionEvent.ACTION_UP:\n        case MotionEvent.ACTION_MOVE:\n            sendToDelegate = mDelegateTargeted;\n            if (sendToDelegate) {\n                if (!sourcePartial.contains(x, y)) {\n                    hit = false;\n                }\n            }\n            break;\n        case MotionEvent.ACTION_CANCEL:\n            sendToDelegate = mDelegateTargeted;\n            mDelegateTargeted = false;\n            break;\n        }\n\n        if (sendToDelegate) {\n            if (hit) {\n                event.setLocation(target.getWidth() / 2, target.getHeight() / 2);\n            } else {\n                event.setLocation(-1, -1);\n            }\n            handled = target.dispatchTouchEvent(event);\n        }\n        return handled;\n    }\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/util/ImageUtils.java",
    "content": "package com.nmbb.oplayer.util;\r\n\r\nimport java.io.ByteArrayOutputStream;\r\nimport java.io.File;\r\nimport java.io.FileNotFoundException;\r\nimport java.io.FileOutputStream;\r\nimport java.io.IOException;\r\n\r\nimport android.annotation.TargetApi;\r\nimport android.content.Context;\r\nimport android.graphics.Bitmap;\r\nimport android.graphics.Bitmap.Config;\r\nimport android.graphics.BitmapFactory;\r\nimport android.graphics.Canvas;\r\nimport android.graphics.Matrix;\r\nimport android.graphics.Paint;\r\nimport android.graphics.PixelFormat;\r\nimport android.graphics.PorterDuff.Mode;\r\nimport android.graphics.PorterDuffXfermode;\r\nimport android.graphics.Rect;\r\nimport android.graphics.RectF;\r\nimport android.graphics.drawable.Drawable;\r\nimport android.net.Uri;\r\nimport android.os.Build;\r\n\r\nimport com.nmbb.oplayer.exception.Logger;\r\n\r\npublic class ImageUtils {\r\n\t// http://zhuixinjian.javaeye.com/blog/743672\r\n\t// 图片圆角\r\n\t// 图片叠加\r\n\t// 图片缩放\r\n\t// 图片旋转\r\n\r\n\t@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)\r\n\tpublic static int getBitmapSize(Bitmap bitmap) {\r\n\t\tif (DeviceUtils.hasHoneycombMR1()) {\r\n\t\t\treturn bitmap.getByteCount();\r\n\t\t}\r\n\t\t// Pre HC-MR1\r\n\t\treturn bitmap.getRowBytes() * bitmap.getHeight();\r\n\t}\r\n\r\n\t/** 旋转图片 */\r\n\tpublic static Bitmap rotate(Bitmap b, int degrees) {\r\n\t\tif (degrees != 0 && b != null) {\r\n\t\t\tMatrix m = new Matrix();\r\n\t\t\tm.setRotate(degrees, (float) b.getWidth() / 2,\r\n\t\t\t\t\t(float) b.getHeight() / 2);\r\n\t\t\ttry {\r\n\t\t\t\tBitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(),\r\n\t\t\t\t\t\tb.getHeight(), m, true);\r\n\t\t\t\tif (b != b2) {\r\n\t\t\t\t\tb.recycle();\r\n\t\t\t\t\tb = b2;\r\n\t\t\t\t}\r\n\t\t\t} catch (OutOfMemoryError ex) {\r\n\t\t\t\tLogger.e(ex);\r\n\t\t\t} catch (Exception ex) {\r\n\t\t\t\tLogger.e(ex);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn b;\r\n\t}\r\n\r\n\t/**\r\n\t * Decode and sample down a bitmap from a file to the requested width and\r\n\t * height.\r\n\t * \r\n\t * @param filename\r\n\t *            The full path of the file to decode\r\n\t * @param reqWidth\r\n\t *            The requested width of the resulting bitmap\r\n\t * @param reqHeight\r\n\t *            The requested height of the resulting bitmap\r\n\t * @return A bitmap sampled down from the original with the same aspect\r\n\t *         ratio and dimensions that are equal to or greater than the\r\n\t *         requested width and height\r\n\t */\r\n\tpublic static synchronized Bitmap decodeSampledBitmapFromFile(\r\n\t\t\tString filename, int reqWidth, int reqHeight) {\r\n\r\n\t\t// First decode with inJustDecodeBounds=true to check dimensions\r\n\t\tfinal BitmapFactory.Options options = new BitmapFactory.Options();\r\n\t\toptions.inJustDecodeBounds = true;\r\n\t\tBitmapFactory.decodeFile(filename, options);\r\n\r\n\t\t// Calculate inSampleSize\r\n\t\toptions.inSampleSize = calculateInSampleSize(options, reqWidth,\r\n\t\t\t\treqHeight);\r\n\r\n\t\t// Decode bitmap with inSampleSize set\r\n\t\toptions.inJustDecodeBounds = false;\r\n\t\treturn BitmapFactory.decodeFile(filename, options);\r\n\t}\r\n\r\n\t/**\r\n\t * Calculate an inSampleSize for use in a\r\n\t * {@link android.graphics.BitmapFactory.Options} object when decoding\r\n\t * bitmaps using the decode* methods from {@link BitmapFactory}. This\r\n\t * implementation calculates the closest inSampleSize that will result in\r\n\t * the final decoded bitmap having a width and height equal to or larger\r\n\t * than the requested width and height. This implementation does not ensure\r\n\t * a power of 2 is returned for inSampleSize which can be faster when\r\n\t * decoding but results in a larger bitmap which isn't as useful for caching\r\n\t * purposes.\r\n\t * \r\n\t * @param options\r\n\t *            An options object with out* params already populated (run\r\n\t *            through a decode* method with inJustDecodeBounds==true\r\n\t * @param reqWidth\r\n\t *            The requested width of the resulting bitmap\r\n\t * @param reqHeight\r\n\t *            The requested height of the resulting bitmap\r\n\t * @return The value to be used for inSampleSize\r\n\t */\r\n\tpublic static int calculateInSampleSize(BitmapFactory.Options options,\r\n\t\t\tint reqWidth, int reqHeight) {\r\n\t\t// Raw height and width of image\r\n\t\tfinal int height = options.outHeight;\r\n\t\tfinal int width = options.outWidth;\r\n\t\tint inSampleSize = 1;\r\n\r\n\t\tif (height > reqHeight || width > reqWidth) {\r\n\t\t\tif (width > height) {\r\n\t\t\t\tinSampleSize = Math.round((float) height / (float) reqHeight);\r\n\t\t\t} else {\r\n\t\t\t\tinSampleSize = Math.round((float) width / (float) reqWidth);\r\n\t\t\t}\r\n\r\n\t\t\t// This offers some additional logic in case the image has a strange\r\n\t\t\t// aspect ratio. For example, a panorama may have a much larger\r\n\t\t\t// width than height. In these cases the total pixels might still\r\n\t\t\t// end up being too large to fit comfortably in memory, so we should\r\n\t\t\t// be more aggressive with sample down the image (=larger\r\n\t\t\t// inSampleSize).\r\n\r\n\t\t\tfinal float totalPixels = width * height;\r\n\r\n\t\t\t// Anything more than 2x the requested pixels we'll sample down\r\n\t\t\t// further.\r\n\t\t\tfinal float totalReqPixelsCap = reqWidth * reqHeight * 2;\r\n\r\n\t\t\twhile (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {\r\n\t\t\t\tinSampleSize++;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn inSampleSize;\r\n\t}\r\n\r\n\tpublic static boolean saveBitmap(String path, Bitmap bitmap) {\r\n\t\treturn saveBitmap(new File(path), bitmap);\r\n\t}\r\n\r\n\t/** 保存图片到文件 */\r\n\tpublic static boolean saveBitmap(File f, Bitmap bitmap) {\r\n\t\tif (bitmap == null || bitmap.isRecycled())\r\n\t\t\treturn false;\r\n\r\n\t\tFileOutputStream fOut = null;\r\n\t\ttry {\r\n\t\t\tif (f.exists())\r\n\t\t\t\tf.createNewFile();\r\n\r\n\t\t\tfOut = new FileOutputStream(f);\r\n\t\t\tbitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);\r\n\r\n\t\t\tfOut.flush();\r\n\t\t\treturn true;\r\n\t\t} catch (FileNotFoundException e) {\r\n\t\t\tLogger.e(e);\r\n\t\t} catch (IOException e) {\r\n\t\t\tLogger.e(e);\r\n\t\t} catch (Exception e) {\r\n\t\t\tLogger.e(e);\r\n\t\t} finally {\r\n\t\t\tif (fOut != null) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tfOut.close();\r\n\t\t\t\t} catch (IOException e) {\r\n\t\t\t\t\tLogger.e(e);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn false;\r\n\t}\r\n\r\n\tpublic static Bitmap decodeUriAsBitmap(Context ctx, Uri uri) {\r\n\t\tBitmap bitmap = null;\r\n\t\ttry {\r\n\t\t\tfinal BitmapFactory.Options options = new BitmapFactory.Options();\r\n\t\t\toptions.inJustDecodeBounds = true;\r\n\t\t\t// options.outWidth = reqWidth;\r\n\t\t\t// options.outHeight = reqHeight;\r\n\t\t\tBitmapFactory.decodeStream(ctx.getContentResolver()\r\n\t\t\t\t\t.openInputStream(uri), null, options);\r\n\t\t\tLogger.i(\"orgi:\" + options.outWidth + \"x\" + options.outHeight);\r\n\t\t\tint be = (int) (options.outHeight / (float) 350);\r\n\t\t\tif (be <= 0)\r\n\t\t\t\tbe = 1;\r\n\t\t\toptions.inSampleSize = be;// calculateInSampleSize(options,\r\n\t\t\t\t\t\t\t\t\t\t// reqWidth, reqHeight);\r\n\t\t\tLogger.i(\"inSampleSize:\" + options.inSampleSize);\r\n\t\t\toptions.inJustDecodeBounds = false;\r\n\t\t\tbitmap = BitmapFactory.decodeStream(ctx.getContentResolver()\r\n\t\t\t\t\t.openInputStream(uri), null, options);\r\n\t\t} catch (FileNotFoundException e) {\r\n\t\t\tLogger.e(e);\r\n\t\t} catch (OutOfMemoryError e) {\r\n\t\t\tLogger.e(e);\r\n\t\t}\r\n\t\treturn bitmap;\r\n\t}\r\n\r\n\tpublic static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) {\r\n\t\tint width = bitmap.getWidth();\r\n\t\tint height = bitmap.getHeight();\r\n\t\tMatrix matrix = new Matrix();\r\n\t\tfloat scaleWidht = ((float) w / width);\r\n\t\tfloat scaleHeight = ((float) h / height);\r\n\t\tmatrix.postScale(scaleWidht, scaleHeight);\r\n\t\tBitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height,\r\n\t\t\t\tmatrix, true);\r\n\t\treturn newbmp;\r\n\t}\r\n\r\n\tpublic static Bitmap drawableToBitmap(Drawable drawable) {\r\n\t\tint width = drawable.getIntrinsicWidth();\r\n\t\tint height = drawable.getIntrinsicHeight();\r\n\t\tBitmap bitmap = Bitmap.createBitmap(width, height, drawable\r\n\t\t\t\t.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888\r\n\t\t\t\t: Bitmap.Config.RGB_565);\r\n\t\tCanvas canvas = new Canvas(bitmap);\r\n\t\tdrawable.setBounds(0, 0, width, height);\r\n\t\tdrawable.draw(canvas);\r\n\t\treturn bitmap;\r\n\r\n\t}\r\n\r\n\t/**\r\n\t * 获取图片圆角\r\n\t * \r\n\t * @param bitmap\r\n\t * @param roundPx\r\n\t *            圆角度数\r\n\t * @return\r\n\t */\r\n\tpublic static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {\r\n\r\n\t\tBitmap output = Bitmap.createBitmap(bitmap.getWidth(),\r\n\t\t\t\tbitmap.getHeight(), Config.ARGB_8888);\r\n\t\tCanvas canvas = new Canvas(output);\r\n\r\n\t\tfinal int color = 0xff424242;\r\n\t\tfinal Paint paint = new Paint();\r\n\t\tfinal Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());\r\n\t\tfinal RectF rectF = new RectF(rect);\r\n\r\n\t\tpaint.setAntiAlias(true);\r\n\t\tcanvas.drawARGB(0, 0, 0, 0);\r\n\t\tpaint.setColor(color);\r\n\t\tcanvas.drawRoundRect(rectF, roundPx, roundPx, paint);\r\n\r\n\t\tpaint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));\r\n\t\tcanvas.drawBitmap(bitmap, rect, rect, paint);\r\n\t\treturn output;\r\n\t}\r\n\r\n\t/**\r\n\t * 转行Drawable为Bitmap对象\r\n\t * \r\n\t * @param drawable\r\n\t * @return\r\n\t */\r\n\tpublic static Bitmap toBitmap(Drawable drawable) {\r\n\t\tint width = drawable.getIntrinsicWidth();\r\n\t\tint height = drawable.getIntrinsicHeight();\r\n\t\tBitmap bitmap = Bitmap.createBitmap(width, height, drawable\r\n\t\t\t\t.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888\r\n\t\t\t\t: Bitmap.Config.RGB_565);\r\n\t\tCanvas canvas = new Canvas(bitmap);\r\n\t\tdrawable.setBounds(0, 0, width, height);\r\n\t\tdrawable.draw(canvas);\r\n\t\treturn bitmap;\r\n\t}\r\n\r\n\t/**\r\n\t * 缩放图片\r\n\t * \r\n\t * @param src\r\n\t *            缩放原图\r\n\t * @param dstWidth\r\n\t *            缩放后宽\r\n\t * @param dstHeight\r\n\t *            缩放后高\r\n\t * @return\r\n\t */\r\n\tpublic static Bitmap scaledBitmap(Bitmap src, int dstWidth, int dstHeight) {\r\n\t\t// 原图不能为空也不能已经被回收掉了\r\n\t\tBitmap result = null;\r\n\t\tif (src != null && !src.isRecycled()) {\r\n\t\t\tif (src.getWidth() == dstWidth && src.getHeight() == dstHeight) {\r\n\t\t\t\tresult = src;\r\n\t\t\t} else {\r\n\t\t\t\tresult = Bitmap.createScaledBitmap(src, dstWidth, dstHeight,\r\n\t\t\t\t\t\ttrue);\r\n\t\t\t}\r\n\t\t}\r\n\t\t// ThumbnailUtils.extractThumbnail(source, width, height)\r\n\t\treturn result;\r\n\t}\r\n\r\n\t/**\r\n\t * 按比例缩放图片\r\n\t * \r\n\t * @param src\r\n\t * @param scale\r\n\t *            例如2 就是二分之一\r\n\t * @return\r\n\t */\r\n\tpublic static Bitmap scaledBitmap(Bitmap src, int scale) {\r\n\t\tif (src == null || src.isRecycled()) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\t\tint dstWidth = src.getWidth() / scale;\r\n\t\tint dstHeight = src.getHeight() / scale;\r\n\t\treturn Bitmap.createScaledBitmap(src, dstWidth, dstHeight, true);\r\n\t}\r\n\r\n\t/**\r\n\t * 将图片转换成字节数组\r\n\t * \r\n\t * @param bitmap\r\n\t * @return\r\n\t */\r\n\tpublic static byte[] toBytes(Bitmap bitmap) {\r\n\t\tByteArrayOutputStream outputStream = new ByteArrayOutputStream();\r\n\t\tbitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);\r\n\t\treturn outputStream.toByteArray();\r\n\t}\r\n}\r\n"
  },
  {
    "path": "src/com/nmbb/oplayer/util/IntentHelper.java",
    "content": "/*\n * Copyright (C) 2012 YIXIA.COM\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.nmbb.oplayer.util;\n\nimport io.vov.vitamio.utils.Log;\n\nimport java.util.List;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport android.content.ComponentName;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.content.pm.PackageInfo;\nimport android.content.pm.PackageManager;\nimport android.content.pm.PackageManager.NameNotFoundException;\nimport android.content.pm.ResolveInfo;\nimport android.net.Uri;\nimport android.os.Parcelable;\nimport android.text.Html;\n\npublic final class IntentHelper {\n\n\tpublic static final String MEDIA_PATTERN = \"(http[s]?://)+([\\\\w-]+\\\\.)+[\\\\w-]+([\\\\w-./?%&=]*)?\";\n\tprivate static final Pattern mMediaPattern;\n\n\tstatic {\n\t\tmMediaPattern = Pattern.compile(MEDIA_PATTERN);\n\t}\n\n\tpublic static Uri getIntentUri(Intent intent) {\n\t\tUri result = null;\n\t\tif (intent != null) {\n\t\t\tresult = intent.getData();\n\t\t\tif (result == null) {\n\t\t\t\tfinal String type = intent.getType();\n\t\t\t\tString sharedUrl = intent.getStringExtra(Intent.EXTRA_TEXT);\n\t\t\t\tif (!StringUtils.isEmpty(sharedUrl)) {\n\t\t\t\t\tif (\"text/plain\".equals(type) && sharedUrl != null) {\n\t\t\t\t\t\tresult = getTextUri(sharedUrl);\n\t\t\t\t\t} else if (\"text/html\".equals(type) && sharedUrl != null) {\n\t\t\t\t\t\tresult = getTextUri(Html.fromHtml(sharedUrl).toString());\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tParcelable parce = intent.getParcelableExtra(Intent.EXTRA_STREAM);\n\t\t\t\t\tif (parce != null)\n\t\t\t\t\t\tresult = (Uri) parce;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate static Uri getTextUri(String sharedUrl) {\n\t\tMatcher matcher = mMediaPattern.matcher(sharedUrl);\n\t\tif (matcher.find()) {\n\t\t\tsharedUrl = matcher.group();\n\t\t\tif (!StringUtils.isEmpty(sharedUrl)) {\n\t\t\t\treturn Uri.parse(sharedUrl);\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tpublic static boolean existPackage(final Context ctx, String packageName) {\n\t\tif (!StringUtils.isEmpty(packageName)) {\n\t\t\tfor (PackageInfo p : ctx.getPackageManager().getInstalledPackages(0)) {\n\t\t\t\tif (packageName.equals(p.packageName))\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tpublic static void startApkActivity(final Context ctx, String packageName) {\n\t\tPackageManager pm = ctx.getPackageManager();\n\t\tPackageInfo pi;\n\t\ttry {\n\t\t\tpi = pm.getPackageInfo(packageName, 0);\n\t\t\tIntent intent = new Intent(Intent.ACTION_MAIN, null);\n\t\t\tintent.setPackage(pi.packageName);\n\n\t\t\tList<ResolveInfo> apps = pm.queryIntentActivities(intent, 0);\n\n\t\t\tResolveInfo ri = apps.iterator().next();\n\t\t\tif (ri != null) {\n\t\t\t\tString className = ri.activityInfo.name;\n\t\t\t\tintent.setComponent(new ComponentName(packageName, className));\n\t\t\t\tctx.startActivity(intent);\n\t\t\t}\n\t\t} catch (NameNotFoundException e) {\n\t\t\tLog.e(\"startActivity\", e);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/util/MediaUtils.java",
    "content": "/*\n * Copyright (C) 2012 YIXIA.COM\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.nmbb.oplayer.util;\n\nimport java.io.File;\nimport java.util.regex.Pattern;\n\nimport android.net.Uri;\n\npublic final class MediaUtils {\n\tpublic static final String[] EXTENSIONS;\n\t// http://www.fileinfo.com/filetypes/video\n\tpublic static final String[] VIDEO_EXTENSIONS = { \"\\\\.264\", \"\\\\.3g2\", \"\\\\.3gp\", \"\\\\.3gp2\", \"\\\\.3gpp\", \"\\\\.3gpp2\", \"\\\\.3mm\", \"\\\\.3p2\", \"\\\\.60d\", \"\\\\.aep\", \"\\\\.ajp\", \"\\\\.amv\", \"\\\\.amx\", \"\\\\.arf\", \"\\\\.asf\", \"\\\\.asx\", \"\\\\.avb\", \"\\\\.avd\", \"\\\\.avi\", \"\\\\.avs\", \"\\\\.avs\", \"\\\\.axm\", \"\\\\.bdm\", \"\\\\.bdmv\", \"\\\\.bik\", \"\\\\.bin\", \"\\\\.bix\", \"\\\\.bmk\", \"\\\\.box\", \"\\\\.bs4\", \"\\\\.bsf\", \"\\\\.byu\", \"\\\\.camre\", \"\\\\.clpi\", \"\\\\.cpi\", \"\\\\.cvc\", \"\\\\.d2v\", \"\\\\.d3v\", \"\\\\.dat\", \"\\\\.dav\", \"\\\\.dce\", \"\\\\.dck\", \"\\\\.ddat\", \"\\\\.dif\", \"\\\\.dir\", \"\\\\.divx\", \"\\\\.dlx\", \"\\\\.dmb\", \"\\\\.dmsm\", \"\\\\.dmss\", \"\\\\.dnc\", \"\\\\.dpg\", \"\\\\.dream\", \"\\\\.dsy\", \"\\\\.dv\", \"\\\\.dv-avi\", \"\\\\.dv4\", \"\\\\.dvdmedia\", \"\\\\.dvr-ms\", \"\\\\.dvx\", \"\\\\.dxr\", \"\\\\.dzm\", \"\\\\.dzp\", \"\\\\.dzt\", \"\\\\.evo\", \"\\\\.eye\", \"\\\\.f4p\", \"\\\\.f4v\", \"\\\\.fbr\", \"\\\\.fbr\", \"\\\\.fbz\", \"\\\\.fcp\", \"\\\\.flc\", \"\\\\.flh\", \"\\\\.fli\", \"\\\\.flv\", \"\\\\.flx\", \"\\\\.gl\", \"\\\\.grasp\", \"\\\\.gts\", \"\\\\.gvi\", \"\\\\.gvp\", \"\\\\.hdmov\", \"\\\\.hkm\", \"\\\\.ifo\", \"\\\\.imovi\", \"\\\\.imovi\", \"\\\\.iva\", \"\\\\.ivf\", \"\\\\.ivr\", \"\\\\.ivs\", \"\\\\.izz\", \"\\\\.izzy\", \"\\\\.jts\", \"\\\\.lsf\", \"\\\\.lsx\", \"\\\\.m15\", \"\\\\.m1pg\", \"\\\\.m1v\", \"\\\\.m21\", \"\\\\.m21\", \"\\\\.m2a\", \"\\\\.m2p\", \"\\\\.m2t\", \"\\\\.m2ts\", \"\\\\.m2v\", \"\\\\.m4e\", \"\\\\.m4u\", \"\\\\.m4v\", \"\\\\.m75\", \"\\\\.meta\", \"\\\\.mgv\", \"\\\\.mj2\", \"\\\\.mjp\", \"\\\\.mjpg\", \"\\\\.mkv\", \"\\\\.mmv\", \"\\\\.mnv\", \"\\\\.mod\", \"\\\\.modd\", \"\\\\.moff\", \"\\\\.moi\", \"\\\\.moov\", \"\\\\.mov\", \"\\\\.movie\", \"\\\\.mp21\", \"\\\\.mp21\", \"\\\\.mp2v\", \"\\\\.mp4\", \"\\\\.mp4v\", \"\\\\.mpe\", \"\\\\.mpeg\", \"\\\\.mpeg4\", \"\\\\.mpf\", \"\\\\.mpg\", \"\\\\.mpg2\", \"\\\\.mpgin\", \"\\\\.mpl\", \"\\\\.mpls\", \"\\\\.mpv\", \"\\\\.mpv2\", \"\\\\.mqv\", \"\\\\.msdvd\", \"\\\\.msh\", \"\\\\.mswmm\", \"\\\\.mts\", \"\\\\.mtv\", \"\\\\.mvb\", \"\\\\.mvc\", \"\\\\.mvd\", \"\\\\.mve\", \"\\\\.mvp\", \"\\\\.mxf\", \"\\\\.mys\", \"\\\\.ncor\", \"\\\\.nsv\", \"\\\\.nvc\", \"\\\\.ogm\", \"\\\\.ogv\", \"\\\\.ogx\", \"\\\\.osp\", \"\\\\.par\", \"\\\\.pds\", \"\\\\.pgi\", \"\\\\.piv\", \"\\\\.playlist\", \"\\\\.pmf\", \"\\\\.prel\", \"\\\\.pro\", \"\\\\.prproj\", \"\\\\.psh\", \"\\\\.pva\", \"\\\\.pvr\", \"\\\\.pxv\", \"\\\\.qt\", \"\\\\.qtch\", \"\\\\.qtl\", \"\\\\.qtm\", \"\\\\.qtz\", \"\\\\.rcproject\", \"\\\\.rdb\", \"\\\\.rec\", \"\\\\.rm\", \"\\\\.rmd\", \"\\\\.rmp\", \"\\\\.rms\", \"\\\\.rmvb\", \"\\\\.roq\", \"\\\\.rp\", \"\\\\.rts\", \"\\\\.rts\", \"\\\\.rum\", \"\\\\.rv\", \"\\\\.sbk\", \"\\\\.sbt\", \"\\\\.scm\", \"\\\\.scm\", \"\\\\.scn\", \"\\\\.sec\", \"\\\\.seq\", \"\\\\.sfvidcap\", \"\\\\.smil\", \"\\\\.smk\", \"\\\\.sml\", \"\\\\.smv\", \"\\\\.spl\", \"\\\\.ssm\", \"\\\\.str\", \"\\\\.stx\", \"\\\\.svi\", \"\\\\.swf\", \"\\\\.swi\", \"\\\\.swt\", \"\\\\.tda3mt\", \"\\\\.tivo\", \"\\\\.tix\", \"\\\\.tod\", \"\\\\.tp\", \"\\\\.tp0\", \"\\\\.tpd\", \"\\\\.tpr\", \"\\\\.trp\", \"\\\\.ts\", \"\\\\.tvs\", \"\\\\.vc1\", \"\\\\.vcr\", \"\\\\.vcv\", \"\\\\.vdo\", \"\\\\.vdr\", \"\\\\.veg\", \"\\\\.vem\", \"\\\\.vf\", \"\\\\.vfw\", \"\\\\.vfz\", \"\\\\.vgz\", \"\\\\.vid\", \"\\\\.viewlet\", \"\\\\.viv\", \"\\\\.vivo\", \"\\\\.vlab\", \"\\\\.vob\", \"\\\\.vp3\", \"\\\\.vp6\", \"\\\\.vp7\", \"\\\\.vpj\", \"\\\\.vro\", \"\\\\.vsp\", \"\\\\.w32\", \"\\\\.wcp\", \"\\\\.webm\", \"\\\\.wm\", \"\\\\.wmd\", \"\\\\.wmmp\", \"\\\\.wmv\", \"\\\\.wmx\", \"\\\\.wp3\", \"\\\\.wpl\", \"\\\\.wtv\", \"\\\\.wvx\", \"\\\\.xfl\", \"\\\\.xvid\", \"\\\\.yuv\", \"\\\\.zm1\", \"\\\\.zm2\", \"\\\\.zm3\", \"\\\\.zmv\" };\n\t// http://www.fileinfo.com/filetypes/audio\n\tpublic static final String[] AUDIO_EXTENSIONS = { \"\\\\.4mp\", \"\\\\.669\", \"\\\\.6cm\", \"\\\\.8cm\", \"\\\\.8med\", \"\\\\.8svx\", \"\\\\.a2m\", \"\\\\.aa\", \"\\\\.aa3\", \"\\\\.aac\", \"\\\\.aax\", \"\\\\.abc\", \"\\\\.abm\", \"\\\\.ac3\", \"\\\\.acd\", \"\\\\.acd-bak\", \"\\\\.acd-zip\", \"\\\\.acm\", \"\\\\.act\", \"\\\\.adg\", \"\\\\.afc\", \"\\\\.agm\", \"\\\\.ahx\", \"\\\\.aif\", \"\\\\.aifc\", \"\\\\.aiff\", \"\\\\.ais\", \"\\\\.akp\", \"\\\\.al\", \"\\\\.alaw\", \"\\\\.all\", \"\\\\.amf\", \"\\\\.amr\", \"\\\\.ams\", \"\\\\.ams\", \"\\\\.aob\", \"\\\\.ape\", \"\\\\.apf\", \"\\\\.apl\", \"\\\\.ase\", \"\\\\.at3\", \"\\\\.atrac\", \"\\\\.au\", \"\\\\.aud\", \"\\\\.aup\", \"\\\\.avr\", \"\\\\.awb\", \"\\\\.band\", \"\\\\.bap\", \"\\\\.bdd\", \"\\\\.box\", \"\\\\.bun\", \"\\\\.bwf\", \"\\\\.c01\", \"\\\\.caf\", \"\\\\.cda\", \"\\\\.cdda\", \"\\\\.cdr\", \"\\\\.cel\", \"\\\\.cfa\", \"\\\\.cidb\", \"\\\\.cmf\", \"\\\\.copy\", \"\\\\.cpr\", \"\\\\.cpt\", \"\\\\.csh\", \"\\\\.cwp\", \"\\\\.d00\", \"\\\\.d01\", \"\\\\.dcf\", \"\\\\.dcm\", \"\\\\.dct\", \"\\\\.ddt\", \"\\\\.dewf\", \"\\\\.df2\", \"\\\\.dfc\", \"\\\\.dig\", \"\\\\.dig\", \"\\\\.dls\", \"\\\\.dm\", \"\\\\.dmf\", \"\\\\.dmsa\", \"\\\\.dmse\", \"\\\\.drg\", \"\\\\.dsf\", \"\\\\.dsm\", \"\\\\.dsp\", \"\\\\.dss\", \"\\\\.dtm\", \"\\\\.dts\", \"\\\\.dtshd\", \"\\\\.dvf\", \"\\\\.dwd\", \"\\\\.ear\", \"\\\\.efa\", \"\\\\.efe\", \"\\\\.efk\", \"\\\\.efq\", \"\\\\.efs\", \"\\\\.efv\", \"\\\\.emd\", \"\\\\.emp\", \"\\\\.emx\", \"\\\\.esps\", \"\\\\.f2r\", \"\\\\.f32\", \"\\\\.f3r\", \"\\\\.f4a\", \"\\\\.f64\", \"\\\\.far\", \"\\\\.fff\", \"\\\\.flac\", \"\\\\.flp\", \"\\\\.fls\", \"\\\\.frg\", \"\\\\.fsm\", \"\\\\.fzb\", \"\\\\.fzf\", \"\\\\.fzv\", \"\\\\.g721\", \"\\\\.g723\", \"\\\\.g726\", \"\\\\.gig\", \"\\\\.gp5\", \"\\\\.gpk\", \"\\\\.gsm\", \"\\\\.gsm\", \"\\\\.h0\", \"\\\\.hdp\", \"\\\\.hma\", \"\\\\.hsb\", \"\\\\.ics\", \"\\\\.iff\", \"\\\\.imf\", \"\\\\.imp\", \"\\\\.ins\", \"\\\\.ins\", \"\\\\.it\", \"\\\\.iti\", \"\\\\.its\", \"\\\\.jam\", \"\\\\.k25\", \"\\\\.k26\", \"\\\\.kar\", \"\\\\.kin\", \"\\\\.kit\", \"\\\\.kmp\", \"\\\\.koz\", \"\\\\.koz\", \"\\\\.kpl\", \"\\\\.krz\", \"\\\\.ksc\", \"\\\\.ksf\", \"\\\\.kt2\", \"\\\\.kt3\", \"\\\\.ktp\", \"\\\\.l\", \"\\\\.la\", \"\\\\.lqt\", \"\\\\.lso\", \"\\\\.lvp\", \"\\\\.lwv\", \"\\\\.m1a\", \"\\\\.m3u\", \"\\\\.m4a\", \"\\\\.m4b\", \"\\\\.m4p\", \"\\\\.m4r\", \"\\\\.ma1\", \"\\\\.mdl\", \"\\\\.med\", \"\\\\.mgv\", \"\\\\.mid\", \"\\\\.midi\", \"\\\\.miniusf\", \"\\\\.mka\", \"\\\\.mlp\", \"\\\\.mmf\", \"\\\\.mmm\", \"\\\\.mmp\", \"\\\\.mo3\", \"\\\\.mod\", \"\\\\.mp1\", \"\\\\.mp2\", \"\\\\.mp3\", \"\\\\.mpa\", \"\\\\.mpc\", \"\\\\.mpga\", \"\\\\.mpu\", \"\\\\.mp_\", \"\\\\.mscx\", \"\\\\.mscz\", \"\\\\.msv\", \"\\\\.mt2\", \"\\\\.mt9\", \"\\\\.mte\", \"\\\\.mti\", \"\\\\.mtm\", \"\\\\.mtp\", \"\\\\.mts\", \"\\\\.mus\", \"\\\\.mws\", \"\\\\.mxl\", \"\\\\.mzp\", \"\\\\.nap\", \"\\\\.nki\", \"\\\\.nra\", \"\\\\.nrt\", \"\\\\.nsa\", \"\\\\.nsf\", \"\\\\.nst\", \"\\\\.ntn\", \"\\\\.nvf\", \"\\\\.nwc\", \"\\\\.odm\", \"\\\\.oga\", \"\\\\.ogg\", \"\\\\.okt\", \"\\\\.oma\", \"\\\\.omf\", \"\\\\.omg\", \"\\\\.omx\", \"\\\\.ots\", \"\\\\.ove\", \"\\\\.ovw\", \"\\\\.pac\", \"\\\\.pat\", \"\\\\.pbf\", \"\\\\.pca\", \"\\\\.pcast\", \"\\\\.pcg\", \"\\\\.pcm\", \"\\\\.peak\", \"\\\\.phy\", \"\\\\.pk\", \"\\\\.pla\", \"\\\\.pls\", \"\\\\.pna\", \"\\\\.ppc\", \"\\\\.ppcx\", \"\\\\.prg\", \"\\\\.prg\", \"\\\\.psf\", \"\\\\.psm\", \"\\\\.ptf\", \"\\\\.ptm\", \"\\\\.pts\", \"\\\\.pvc\", \"\\\\.qcp\", \"\\\\.r\", \"\\\\.r1m\", \"\\\\.ra\", \"\\\\.ram\", \"\\\\.raw\", \"\\\\.rax\", \"\\\\.rbs\", \"\\\\.rcy\", \"\\\\.rex\", \"\\\\.rfl\", \"\\\\.rmf\", \"\\\\.rmi\", \"\\\\.rmj\", \"\\\\.rmm\", \"\\\\.rmx\", \"\\\\.rng\", \"\\\\.rns\", \"\\\\.rol\", \"\\\\.rsn\", \"\\\\.rso\", \"\\\\.rti\", \"\\\\.rtm\", \"\\\\.rts\", \"\\\\.rvx\", \"\\\\.rx2\", \"\\\\.s3i\", \"\\\\.s3m\", \"\\\\.s3z\", \"\\\\.saf\", \"\\\\.sam\", \"\\\\.sb\", \"\\\\.sbg\", \"\\\\.sbi\", \"\\\\.sbk\", \"\\\\.sc2\", \"\\\\.sd\", \"\\\\.sd\", \"\\\\.sd2\", \"\\\\.sd2f\", \"\\\\.sdat\", \"\\\\.sdii\", \"\\\\.sds\", \"\\\\.sdt\", \"\\\\.sdx\", \"\\\\.seg\", \"\\\\.seq\", \"\\\\.ses\", \"\\\\.sf\", \"\\\\.sf2\", \"\\\\.sfk\", \"\\\\.sfl\", \"\\\\.shn\", \"\\\\.sib\", \"\\\\.sid\", \"\\\\.sid\", \"\\\\.smf\", \"\\\\.smp\", \"\\\\.snd\", \"\\\\.snd\", \"\\\\.snd\", \"\\\\.sng\", \"\\\\.sng\", \"\\\\.sou\", \"\\\\.sppack\", \"\\\\.sprg\", \"\\\\.spx\", \"\\\\.sseq\", \"\\\\.sseq\", \"\\\\.ssnd\", \"\\\\.stm\", \"\\\\.stx\", \"\\\\.sty\", \"\\\\.svx\", \"\\\\.sw\", \"\\\\.swa\", \"\\\\.syh\", \"\\\\.syw\", \"\\\\.syx\", \"\\\\.td0\", \"\\\\.tfmx\", \"\\\\.thx\", \"\\\\.toc\", \"\\\\.tsp\", \"\\\\.txw\", \"\\\\.u\", \"\\\\.ub\", \"\\\\.ulaw\", \"\\\\.ult\", \"\\\\.ulw\", \"\\\\.uni\", \"\\\\.usf\", \"\\\\.usflib\", \"\\\\.uw\", \"\\\\.uwf\", \"\\\\.vag\", \"\\\\.val\", \"\\\\.vc3\", \"\\\\.vmd\", \"\\\\.vmf\", \"\\\\.vmf\", \"\\\\.voc\", \"\\\\.voi\", \"\\\\.vox\", \"\\\\.vpm\", \"\\\\.vqf\", \"\\\\.vrf\", \"\\\\.vyf\", \"\\\\.w01\", \"\\\\.wav\", \"\\\\.wav\", \"\\\\.wave\", \"\\\\.wax\", \"\\\\.wfb\", \"\\\\.wfd\", \"\\\\.wfp\", \"\\\\.wma\", \"\\\\.wow\", \"\\\\.wpk\", \"\\\\.wproj\", \"\\\\.wrk\", \"\\\\.wus\", \"\\\\.wut\", \"\\\\.wv\", \"\\\\.wvc\", \"\\\\.wve\", \"\\\\.wwu\", \"\\\\.xa\", \"\\\\.xa\", \"\\\\.xfs\", \"\\\\.xi\", \"\\\\.xm\", \"\\\\.xmf\", \"\\\\.xmi\", \"\\\\.xmz\", \"\\\\.xp\", \"\\\\.xrns\", \"\\\\.xsb\", \"\\\\.xspf\", \"\\\\.xt\", \"\\\\.xwb\", \"\\\\.ym\", \"\\\\.zvd\", \"\\\\.zvr\" };\n\tpublic static final String[] SUBTRACK_EXTENSIONS = { \".srt\", \".ssa\", \".smi\", \".txt\", \".sub\", \".ass\" };\n\tpublic static final Pattern VIDEO_EXTENSIONS_PATTERN;\n\tpublic static final Pattern AUDIO_EXTENSIONS_PATTERN;\n\tpublic static final Pattern EXTENSIONS_PATTERN;\n\tpublic static final Pattern SUBTRACK_EXTENSIONS_PATTERN;\n\tstatic {\n\t\tEXTENSIONS = ArrayUtils.concat(VIDEO_EXTENSIONS, AUDIO_EXTENSIONS);\n\t\tEXTENSIONS_PATTERN = generatePattern(EXTENSIONS);\n\t\tVIDEO_EXTENSIONS_PATTERN = generatePattern(VIDEO_EXTENSIONS);\n\t\tAUDIO_EXTENSIONS_PATTERN = generatePattern(AUDIO_EXTENSIONS);\n\t\tSUBTRACK_EXTENSIONS_PATTERN = generatePattern(SUBTRACK_EXTENSIONS);\n\t}\n\n\tpublic static boolean isVideoOrAudio(String url) {\n\t\treturn EXTENSIONS_PATTERN.matcher(url.trim()).find();\n\t}\n\n\tpublic static boolean isVideoOrAudio(File file) {\n\t\treturn EXTENSIONS_PATTERN.matcher(file.getName().trim()).find();\n\t}\n\n\tpublic static boolean isVideo(String url) {\n\t\treturn VIDEO_EXTENSIONS_PATTERN.matcher(url.trim()).find();\n\t}\n\n\tpublic static boolean isVideo(File file) {\n\t\treturn VIDEO_EXTENSIONS_PATTERN.matcher(file.getName().trim()).find();\n\t}\n\n\tpublic static boolean isAudio(String url) {\n\t\treturn AUDIO_EXTENSIONS_PATTERN.matcher(url.trim()).find();\n\t}\n\n\tpublic static boolean isAudio(File file) {\n\t\treturn AUDIO_EXTENSIONS_PATTERN.matcher(file.getName().trim()).find();\n\t}\n\n\tpublic static boolean isSubTrack(File file) {\n\t\treturn SUBTRACK_EXTENSIONS_PATTERN.matcher(file.getName().trim()).find();\n\t}\n\n\tpublic static boolean isNative(String uri) {\n\t\turi = Uri.decode(uri);\n\t\treturn uri != null && (uri.startsWith(\"/\") || uri.startsWith(\"content:\") || uri.startsWith(\"file:\"));\n\t}\n\n\tprivate static Pattern generatePattern(String[] args) {\n\t\tStringBuffer sb = new StringBuffer();\n\t\tfor (String ext : args) {\n\t\t\tif (sb.length() > 0)\n\t\t\t\tsb.append(\"|\");\n\t\t\tsb.append(ext);\n\t\t}\n\t\treturn Pattern.compile(\"(\" + sb.toString() + \")$\", Pattern.CASE_INSENSITIVE);\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/util/PinyinUtils.java",
    "content": "package com.nmbb.oplayer.util;\r\n\r\nimport net.sourceforge.pinyin4j.PinyinHelper;\r\nimport net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;\r\nimport net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;\r\nimport net.sourceforge.pinyin4j.format.HanyuPinyinToneType;\r\nimport net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;\r\n\r\npublic final class PinyinUtils {\r\n\r\n\tprivate static HanyuPinyinOutputFormat spellFormat = new HanyuPinyinOutputFormat();\r\n\r\n\tstatic {\r\n\t\tspellFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);\r\n\t\tspellFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);\r\n\t\t//spellFormat.setVCharType(HanyuPinyinVCharType.WITH_V);\r\n\t}\r\n\r\n\tpublic static String chineneToSpell(String chineseStr) throws BadHanyuPinyinOutputFormatCombination {\r\n\t\tStringBuffer result = new StringBuffer();\r\n\t\tfor (char c : chineseStr.toCharArray()) {\r\n\t\t\tif (c > 128) {\r\n\t\t\t\tString[] array = PinyinHelper.toHanyuPinyinStringArray(c, spellFormat);\r\n\t\t\t\tif (array != null && array.length > 0)\r\n\t\t\t\t\tresult.append(array[0]);\r\n\t\t\t\telse\r\n\t\t\t\t\tresult.append(\" \");\r\n\t\t\t} else\r\n\t\t\t\tresult.append(c);\r\n\t\t}\r\n\t\treturn result.toString();\r\n\t}\r\n}\r\n"
  },
  {
    "path": "src/com/nmbb/oplayer/util/StringUtils.java",
    "content": "package com.nmbb.oplayer.util;\n\nimport java.io.UnsupportedEncodingException;\nimport java.net.URLEncoder;\nimport java.text.SimpleDateFormat;\nimport java.util.ArrayList;\nimport java.util.Calendar;\nimport java.util.Date;\nimport java.util.Iterator;\nimport java.util.TimeZone;\n\nimport android.text.TextPaint;\n\nimport com.nmbb.oplayer.exception.Logger;\n\n/**\n * 字符串工具类\n * \n * @author tangjun\n * \n */\npublic class StringUtils {\n\n\tpublic static final String EMPTY = \"\";\n\n\tprivate static final String DEFAULT_DATE_PATTERN = \"yyyy-MM-dd\";\n\tprivate static final String DEFAULT_DATETIME_PATTERN = \"yyyy-MM-dd hh:mm:ss\";\n\t/** 用于生成文件 */\n\tprivate static final String DEFAULT_FILE_PATTERN = \"yyyy-MM-dd-HH-mm-ss\";\n\tprivate static final double KB = 1024.0;\n\tprivate static final double MB = 1048576.0;\n\tprivate static final double GB = 1073741824.0;\n\tpublic static final SimpleDateFormat DATE_FORMAT_PART = new SimpleDateFormat(\n\t\t\t\"HH:mm\");\n\n\tpublic static String currentTimeString() {\n\t\treturn DATE_FORMAT_PART.format(Calendar.getInstance().getTime());\n\t}\n\n\tpublic static char chatAt(String pinyin, int index) {\n\t\tif (pinyin != null && pinyin.length() > 0)\n\t\t\treturn pinyin.charAt(index);\n\t\treturn ' ';\n\t}\n\n\t/** 获取字符串宽度 */\n\tpublic static float GetTextWidth(String Sentence, float Size) {\n\t\tif (isEmpty(Sentence))\n\t\t\treturn 0;\n\t\tTextPaint FontPaint = new TextPaint();\n\t\tFontPaint.setTextSize(Size);\n\t\treturn FontPaint.measureText(Sentence.trim()) + (int) (Size * 0.1); // 留点余地\n\t}\n\n\t/**\n\t * 格式化日期字符串\n\t * \n\t * @param date\n\t * @param pattern\n\t * @return\n\t */\n\tpublic static String formatDate(Date date, String pattern) {\n\t\tSimpleDateFormat format = new SimpleDateFormat(pattern);\n\t\treturn format.format(date);\n\t}\n\n\t/**\n\t * 格式化日期字符串\n\t * \n\t * @param date\n\t * @return 例如2011-3-24\n\t */\n\tpublic static String formatDate(Date date) {\n\t\treturn formatDate(date, DEFAULT_DATE_PATTERN);\n\t}\n\n\tpublic static String formatDate(long date) {\n\t\treturn formatDate(new Date(date), DEFAULT_DATE_PATTERN);\n\t}\n\n\t/**\n\t * 获取当前时间 格式为yyyy-MM-dd 例如2011-07-08\n\t * \n\t * @return\n\t */\n\tpublic static String getDate() {\n\t\treturn formatDate(new Date(), DEFAULT_DATE_PATTERN);\n\t}\n\n\t/** 生成一个文件名，不含后缀 */\n\tpublic static String createFileName() {\n\t\tDate date = new Date(System.currentTimeMillis());\n\t\tSimpleDateFormat format = new SimpleDateFormat(DEFAULT_FILE_PATTERN);\n\t\treturn format.format(date);\n\t}\n\n\t/**\n\t * 获取当前时间\n\t * \n\t * @return\n\t */\n\tpublic static String getDateTime() {\n\t\treturn formatDate(new Date(), DEFAULT_DATETIME_PATTERN);\n\t}\n\n\t/**\n\t * 格式化日期时间字符串\n\t * \n\t * @param date\n\t * @return 例如2011-11-30 16:06:54\n\t */\n\tpublic static String formatDateTime(Date date) {\n\t\treturn formatDate(date, DEFAULT_DATETIME_PATTERN);\n\t}\n\n\tpublic static String formatDateTime(long date) {\n\t\treturn formatDate(new Date(date), DEFAULT_DATETIME_PATTERN);\n\t}\n\t\n\t/**\n\t * 格林威时间转换\n\t * \n\t * @param gmt\n\t * @return\n\t */\n\tpublic static String formatGMTDate(String gmt) {\n\t\tTimeZone timeZoneLondon = TimeZone.getTimeZone(gmt);\n\t\treturn formatDate(Calendar.getInstance(timeZoneLondon)\n\t\t\t\t.getTimeInMillis());\n\t}\n\n\t/**\n\t * 拼接数组\n\t * \n\t * @param array\n\t * @param separator\n\t * @return\n\t */\n\tpublic static String join(final ArrayList<String> array,\n\t\t\tfinal String separator) {\n\t\tStringBuffer result = new StringBuffer();\n\t\tif (array != null && array.size() > 0) {\n\t\t\tfor (String str : array) {\n\t\t\t\tresult.append(str);\n\t\t\t\tresult.append(separator);\n\t\t\t}\n\t\t\tresult.delete(result.length() - 1, result.length());\n\t\t}\n\t\treturn result.toString();\n\t}\n\n\tpublic static String join(final Iterator<String> iter,\n\t\t\tfinal String separator) {\n\t\tStringBuffer result = new StringBuffer();\n\t\tif (iter != null) {\n\t\t\twhile (iter.hasNext()) {\n\t\t\t\tString key = iter.next();\n\t\t\t\tresult.append(key);\n\t\t\t\tresult.append(separator);\n\t\t\t}\n\t\t\tif (result.length() > 0)\n\t\t\t\tresult.delete(result.length() - 1, result.length());\n\t\t}\n\t\treturn result.toString();\n\t}\n\n\t/**\n\t * 判断字符串是否为空\n\t * \n\t * @param str\n\t * @return\n\t */\n\tpublic static boolean isEmpty(String str) {\n\t\treturn str == null || str.length() == 0;\n\t}\n\n\t/**\n\t * \n\t * @param str\n\t * @return\n\t */\n\tpublic static String trim(String str) {\n\t\treturn str == null ? EMPTY : str.trim();\n\t}\n\n\t/**\n\t * 转换时间显示\n\t * \n\t * @param time\n\t *            毫秒\n\t * @return\n\t */\n\tpublic static String generateTime(long time) {\n\t\tint totalSeconds = (int) (time / 1000);\n\t\tint seconds = totalSeconds % 60;\n\t\tint minutes = (totalSeconds / 60) % 60;\n\t\tint hours = totalSeconds / 3600;\n\n\t\treturn hours > 0 ? String.format(\"%02d:%02d:%02d\", hours, minutes,\n\t\t\t\tseconds) : String.format(\"%02d:%02d\", minutes, seconds);\n\t}\n\n\t/** 根据秒速获取时间格式 */\n\tpublic static String gennerTime(int totalSeconds) {\n\t\tint seconds = totalSeconds % 60;\n\t\tint minutes = (totalSeconds / 60) % 60;\n\t\treturn String.format(\"%02d:%02d\", minutes, seconds);\n\t}\n\n\t/**\n\t * 转换文件大小\n\t * \n\t * @param size\n\t * @return\n\t */\n\tpublic static String generateFileSize(long size) {\n\t\tString fileSize;\n\t\tif (size < KB)\n\t\t\tfileSize = size + \"B\";\n\t\telse if (size < MB)\n\t\t\tfileSize = String.format(\"%.1f\", size / KB) + \"KB\";\n\t\telse if (size < GB)\n\t\t\tfileSize = String.format(\"%.1f\", size / MB) + \"MB\";\n\t\telse\n\t\t\tfileSize = String.format(\"%.1f\", size / GB) + \"GB\";\n\n\t\treturn fileSize;\n\t}\n\n\tpublic static String getTimeDiff(long time) {\n\t\t// Calendar cal = Calendar.getInstance();\n\t\tlong diff = 0;\n\t\t// Date dnow = cal.getTime();\n\t\tString str = \"\";\n\t\tdiff = System.currentTimeMillis() - time;\n\n\t\tif (diff > 2592000000L) {// 30 * 24 * 60 * 60 * 1000=2592000000 毫秒\n\t\t\tstr = \"1个月前\";\n\t\t} else if (diff > 1814400000) {// 21 * 24 * 60 * 60 * 1000=1814400000 毫秒\n\t\t\tstr = \"3周前\";\n\t\t} else if (diff > 1209600000) {// 14 * 24 * 60 * 60 * 1000=1209600000 毫秒\n\t\t\tstr = \"2周前\";\n\t\t} else if (diff > 604800000) {// 7 * 24 * 60 * 60 * 1000=604800000 毫秒\n\t\t\tstr = \"1周前\";\n\t\t} else if (diff > 86400000) { // 24 * 60 * 60 * 1000=86400000 毫秒\n\t\t\t// System.out.println(\"X天前\");\n\t\t\tstr = (int) Math.floor(diff / 86400000f) + \"天前\";\n\t\t} else if (diff > 18000000) {// 5 * 60 * 60 * 1000=18000000 毫秒\n\t\t\t// System.out.println(\"X小时前\");\n\t\t\tstr = (int) Math.floor(diff / 18000000f) + \"小时前\";\n\t\t} else if (diff > 60000) {// 1 * 60 * 1000=60000 毫秒\n\t\t\t// System.out.println(\"X分钟前\");\n\t\t\tstr = (int) Math.floor(diff / 60000) + \"分钟前\";\n\t\t} else {\n\t\t\tstr = (int) Math.floor(diff / 1000) + \"秒前\";\n\t\t}\n\t\treturn str;\n\t}\n\n\t/**\n\t * 截取字符串\n\t * \n\t * @param search\n\t *            待搜索的字符串\n\t * @param start\n\t *            起始字符串 例如：<title>\n\t * @param end\n\t *            结束字符串 例如：</title>\n\t * @param defaultValue\n\t * @return\n\t */\n\tpublic static String substring(String search, String start, String end,\n\t\t\tString defaultValue) {\n\t\tint start_len = start.length();\n\t\tint start_pos = StringUtils.isEmpty(start) ? 0 : search.indexOf(start);\n\t\tif (start_pos > -1) {\n\t\t\tint end_pos = StringUtils.isEmpty(end) ? -1 : search.indexOf(end,\n\t\t\t\t\tstart_pos + start_len);\n\t\t\tif (end_pos > -1)\n\t\t\t\treturn search.substring(start_pos + start.length(), end_pos);\n\t\t\telse\n\t\t\t\treturn search.substring(start_pos + start.length());\n\t\t}\n\t\treturn defaultValue;\n\t}\n\n\t/**\n\t * 截取字符串\n\t * \n\t * @param search\n\t *            待搜索的字符串\n\t * @param start\n\t *            起始字符串 例如：<title>\n\t * @param end\n\t *            结束字符串 例如：</title>\n\t * @return\n\t */\n\tpublic static String substring(String search, String start, String end) {\n\t\treturn substring(search, start, end, \"\");\n\t}\n\n\t/**\n\t * 拼接字符串\n\t * \n\t * @param strs\n\t * @return\n\t */\n\tpublic static String concat(String... strs) {\n\t\tStringBuffer result = new StringBuffer();\n\t\tif (strs != null) {\n\t\t\tfor (String str : strs) {\n\t\t\t\tif (str != null)\n\t\t\t\t\tresult.append(str);\n\t\t\t}\n\t\t}\n\t\treturn result.toString();\n\t}\n\n\t/** 获取中文字符个数 */\n\tpublic static int getChineseCharCount(String str) {\n\t\tString tempStr;\n\t\tint count = 0;\n\t\tfor (int i = 0; i < str.length(); i++) {\n\t\t\ttempStr = String.valueOf(str.charAt(i));\n\t\t\tif (tempStr.getBytes().length == 3) {\n\t\t\t\tcount++;\n\t\t\t}\n\t\t}\n\t\treturn count;\n\t}\n\n\t/** 获取英文字符个数 */\n\tpublic static int getEnglishCount(String str) {\n\t\tString tempStr;\n\t\tint count = 0;\n\t\tfor (int i = 0; i < str.length(); i++) {\n\t\t\ttempStr = String.valueOf(str.charAt(i));\n\t\t\tif (!(tempStr.getBytes().length == 3)) {\n\t\t\t\tcount++;\n\t\t\t}\n\t\t}\n\t\treturn count;\n\t}\n\n\tpublic static String encode(String url) {\n\t\ttry {\n\t\t\treturn URLEncoder.encode(url, \"UTF-8\");\n\t\t} catch (UnsupportedEncodingException e) {\n\t\t\tLogger.e(e);\n\t\t}\n\t\treturn url;\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/util/ToastUtils.java",
    "content": "package com.nmbb.oplayer.util;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.view.View;\nimport android.widget.Toast;\n\nimport com.nmbb.oplayer.OPlayerApplication;\nimport com.nmbb.oplayer.R;\n\npublic class ToastUtils {\n\n\tpublic static void showToast(int resID) {\n\t\tshowToast(OPlayerApplication.getContext(), Toast.LENGTH_SHORT, resID);\n\t}\n\n\tpublic static void showToast(String text) {\n\t\tshowToast(OPlayerApplication.getContext(), Toast.LENGTH_SHORT, text);\n\t}\n\n\tpublic static void showToast(Context ctx, int resID) {\n\t\tshowToast(ctx, Toast.LENGTH_SHORT, resID);\n\t}\n\n\tpublic static void showToast(Context ctx, String text) {\n\t\tshowToast(ctx, Toast.LENGTH_SHORT, text);\n\t}\n\n\tpublic static void showLongToast(Context ctx, int resID) {\n\t\tshowToast(ctx, Toast.LENGTH_LONG, resID);\n\t}\n\n\tpublic static void showLongToast(int resID) {\n\t\tshowToast(OPlayerApplication.getContext(), Toast.LENGTH_LONG, resID);\n\t}\n\n\tpublic static void showLongToast(Context ctx, String text) {\n\t\tshowToast(ctx, Toast.LENGTH_LONG, text);\n\t}\n\n\tpublic static void showLongToast(String text) {\n\t\tshowToast(OPlayerApplication.getContext(), Toast.LENGTH_LONG, text);\n\t}\n\n\tpublic static void showToast(Context ctx, int duration, int resID) {\n\t\tshowToast(ctx, duration, ctx.getString(resID));\n\t}\n\n\tpublic static void showToast(Context ctx, int duration, String text) {\n\t\tToast toast = Toast.makeText(ctx, text, duration);\n\t\tView mNextView = toast.getView();\n\t\tif (mNextView != null)\n\t\t\tmNextView.setBackgroundResource(R.drawable.toast_frame);\n\t\ttoast.show();\n\t\t// Toast.makeText(ctx, text, duration).show();\n\t}\n\n\t// public static void showToastOnUiThread(final String text) {\n\t// showToastOnUiThread(FSAppliction.getCurrentActivity(), text);\n\t// }\n\n\t/** 在UI线程运行弹出 */\n\tpublic static void showToastOnUiThread(final Activity ctx, final String text) {\n\t\tif (ctx != null) {\n\t\t\tctx.runOnUiThread(new Runnable() {\n\n\t\t\t\t@Override\n\t\t\t\tpublic void run() {\n\t\t\t\t\tshowToast(ctx, text);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/com/nmbb/oplayer/video/VideoThumbnailUtils.java",
    "content": "package com.nmbb.oplayer.video;\r\n\r\nimport android.graphics.Bitmap;\r\n\r\npublic final class VideoThumbnailUtils {\r\n\t\r\n\t/** 获取视频的缩略图 */\r\n\tpublic static Bitmap createVideoThumbnail() {\r\n\t\treturn null;\r\n\t}\r\n\r\n\t/** 获取视频的时长 */\r\n\tpublic int getDuration() {\r\n\t\treturn 1;\r\n\t}\r\n\r\n\t/** 获取视频的高度 */\r\n\tpublic int getVideoHeight() {\r\n\t\treturn 1;\r\n\t}\r\n\r\n\t/** 获取视频的宽度 */\r\n\tpublic int getVideoWidth() {\r\n\t\treturn 1;\r\n\t}\r\n}\r\n"
  }
]