Skip to content

arnozhang/android-LocalMediaServer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 

Repository files navigation

android-LocalMediaServer 简介

android-LocalMediaServer 用来在本地搭建一个 MediaServer,用于提供 Audio/Video 数据服务。

1、用途

一般来说,本地多媒体文件访问可以通过下面的方法来播放:

// ...

String filePath = Environment.getExternalStorageDirectory().getPath() + "/media.mp4";
MediaPlayer mediaPlayer = new MediaPlayer();

try {
    mediaPlayer.setDataSource(this, Uri.fromFile(new File(filePath)));
} catch (IOException e) {
    e.printStackTrace();
    return ;
}

mediaPlayer.prepare();
mediaPlayer.start();

// ...

但如果碰上一些特殊需求——比如视频文件加密后缓存在本地,然后后续再进行播放。

针对上面的需求,Android 系统自带的 MediaPlayer 将不再适用——它不会识别/解密我们通过特定算法加密的视频文件。要播放这种文件,有下面几种方法:

  1. 将文件先解密到本地文件夹,然后再播放解密后的文件;
  2. 通过本例提供的本地 MediaServer 的方法,边解密,边播放。

2、方案分析

上面提供的方法,第一种会泄露文件——解密后用户仍然可以将解密后的文件拷贝出去;第二种(亦即本例)方法安全性稍有提高,但仍然无法彻底避免加密后的视频文件被获取到——充其量只是提高了一点技术壁垒,增加了大量复制传播的成本而已。

通过 LocalMediaServer,将一个本地文件转换为类似 http://localserver:port/encode_filepath 类似的 URL,然后通过 Android 中的 ServerSocket 监听 port 端口,按 Http Live Streaming(利用好 206 Http 返回码以及 Content-Range 字段) 的要求将数据返回即可。在返回数据时,根据数据段先解密相应数据,再返回数据。

这种方案,如果别人要获取你解密的视频,其实也是比较容易的——因为他可以在手机端抓包,获取到你正在播放的 URL,然后他用一个 HTTP 请求,就可以很容易的将你的整个文件 Download 下来。

总体来说,除非你彻底定制一个自己的 MediaPlayer,实现视频文件的解密、播放,否则单纯利用 Android 系统的 MediaPlayer,是无法彻底保证视频文件不被复制的。

3、使用示例

具体例子详见工程中的 Demo。下面贴出部分代码示例:

String mediaPath = Environment.getExternalStorageDirectory().getPath() + "/media.mp4";
LocalMediaServer mediaServer = new LocalMediaServer();
String url = mediaServer.prepare(mediaPath);
if (TextUtils.isEmpty(url)) {
    String msg = String.format("Cannot resolve Media-Url ! ensure file \"%s\" exists!", mediaPath);
    Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    return;
}

mediaServer.start();

MediaPlayer mediaPlayer = new MediaPlayer();
// ...

try {
    mediaPlayer.setDataSource(this, Uri.parse(url));
    mediaPlayer.prepareAsync();
} catch (IOException e) {
    e.printStackTrace();
}

// ...

自定义解密器:

byte[] encryptKey = ...;
final Encryptor encryptor = new Encryptor() {
    @Override
    public byte[] encrypt(byte[] buffer, byte[] encryptKey) {
		// ...
    }

    @Override
    public byte[] decrypt(byte[] buffer, byte[] encryptKey) {
		// ...
    }

    @Override
    public byte[] encrypt(byte[] buffer, int start, int count, byte[] encryptKey) {
		// ...
    }

    @Override
    public byte[] decrypt(byte[] buffer, int start, int count, byte[] encryptKey) {
		// ...
    }
};

LocalMediaServer mediaServer = new LocalMediaServer() {
	@Override
    protected MediaDataProvider createMediaProvider(String filePath) {
        return new EncryptedMediaProvider(filePath, encryptor, encryptKey);
    }
};

// ...
String url = mediaServer.prepare(mediaPath);
mediaServer.start();

About

Local media(audio/video) server for Android.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages