ywl5320/wlmedia

是否支持播放加密音频(自定义加解密)

Closed this issue · 28 comments

我好像只看到视频解密,音频好像没看到

加密不区分音频还是视频的,都可以用加密功能

播放这边简单的文件加密要如何处理?
private static final String AES_ALGORITHM = "AES/CBC/PKCS5Padding";

public static byte[] generateIV() {
    SecureRandom secureRandom = new SecureRandom();
    byte[] ivBytes = new byte[16];
    secureRandom.nextBytes(ivBytes);
    return ivBytes;
}

public static byte[] encryptFile(File inputFile,byte[] keyBytes,byte[] ivBytes) throws Exception {
    Key secretKey = new SecretKeySpec(keyBytes, "AES");
    Cipher encryptCipher = Cipher.getInstance(AES_ALGORITHM);
    encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(ivBytes));
    byte[] encryptedBytes = fileToBytes(inputFile);
    return encryptCipher.doFinal(encryptedBytes);
}

public static  byte[] decryptFile(File inputFile,byte[] keyBytes,byte[] ivBytes) throws Exception {
    Key secretKey = new SecretKeySpec(keyBytes, "AES");
    Cipher decryptCipher = Cipher.getInstance(AES_ALGORITHM);
    decryptCipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(ivBytes));
    byte[] encryptedBytes = fileToBytes(inputFile);
    return decryptCipher.doFinal(encryptedBytes);
}

public static  byte[] fileToBytes(File file) throws IOException {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    FileInputStream inputStream = new FileInputStream(file);
    byte[] buffer = new byte[1024];
    int length;
    while ((length = inputStream.read(buffer)) != -1) {
        outputStream.write(buffer, 0, length);
    }
    inputStream.close();
    return outputStream.toByteArray();
}

我设置 wlMedia.setSourceType(WlSourceType.ENCRYPT_FILE);
然后在 decryptBuffer回调解密,不可以

解密回调里面是返回的部分数据,要用能任一部分数据都能解码的加密算法,比如最简单的按位操作,你可以这样修改试试

好的。我去试试看

我通过位移加解密,目前是可以正常播放的。但是遇到了一个新的问题,就是 mWlMedia.getDuration() 这个获取音频总时长的 数据是错误的

我通过位移加解密,目前是可以正常播放的。但是遇到了一个新的问题,就是 mWlMedia.getDuration() 这个获取音频总时长的,有的问题这个时间会是错误的,但是播放正常的,这个发现的概率挺大的。代码如下:
/**
* 解密文件
*
* @param inputPath 需要加密的文件路径
* @param outputPath 加密完的新文件路径
* @return 是否加密成功
*/
public static boolean encryptFile(String inputPath, String outputPath) {
File parentFile = new File(outputPath).getParentFile();
FileUtils.createOrExistsDir(parentFile);

    // 读取源文件
    try (FileInputStream fis = new FileInputStream(inputPath);
         FileOutputStream fos = new FileOutputStream(outputPath)) {
        byte[] buffer = new byte[1024];
        int read;
        while ((read = fis.read(buffer)) != -1) {
            for (int i = 0; i < read; i++) {
                buffer[i] = (byte) (buffer[i] ^ 66 ^ 88);
            }
            fos.write(buffer, 0, read);
        }
        return true;
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return false;
}

/**
 * 解密数据流
 *
 * @param bytes 需要解密的数据流
 * @return 解密完成的数据流
 */
public static byte[] decryptByte(byte[] bytes) {
    int length = bytes.length;
    for (int i = 0; i < length; i++) {
        bytes[i] = (byte) ((int) bytes[i] ^ 66 ^ 88);
    }
    return bytes;
}

不对。这个mWlMedia.getDuration() 返回的时间是对的,但是decryptBuffer里面回调的数据会多了一些出来,音频会多播了一段时间

未加密文件播放正常不呢

未加密的播放正常,比如现在有一个原文件280k的 17秒的音频,加密后的文件也是280k,mWlMedia.getDuration() 获取到的也是17秒,但是播放会播放32秒,17秒以后会继续播,会继续从开头开始播

会播放32秒,但是全17秒播放的数据都是正确的,就是播放完成以后 ,为啥还会继续播,我文件就是做了一个简单的异或加密

这个日志回调有点奇怪
2024-03-06 14:34:57.968 21821-21875/? E/AnchorPlayerMgr: decryptBuffer
2024-03-06 14:34:57.987 21821-21821/? E/AnchorPlayerMgr: onPrepared
2024-03-06 14:34:58.010 21821-21821/? E/AnchorPlayerMgr: onLoad
2024-03-06 14:35:13.099 21821-21876/? E/AnchorPlayerMgr: decryptBuffer
在onPrepared之前会回调一次数据,然后在17秒全部播完的时候,会再次回调一次数据,所以导致又继续播了一次

经过测试,如果是一个没有加密的音频文件,按加密的方式来播放,然后在decryptBuffer不处理数据直接返回数据,也是一样的情况,会多播放一段

这个还没注意过呢 如果是问题 新版本我们会解决的哈

我找到问题了,decryptBuffer多次返回的数据总长度超过原数据的长度,如果在最后一次,把多余的数据截取掉,那么就刚好正常

那现在解决了嘛

现在只有去记录播放的数据长度,然后做截取。这算是个BUG吧。你有空的时候,更新解决下呗

好的

这种情况,现在播放正常了,但是有的文件获取 获取总时长的getDuration 也有问题。一个196秒的文件,解密播放正常,能播196秒,但是getDuration 到的时间长23秒

好的 我们测试一下

新版本已优化,你再测一下呢

wlPlayer = WlPlayer()
wlPlayer?.playModel = WlPlayModel.WL_PLAY_MODEL_ONLY_AUDIO
wlPlayer?.sourceType = WlSourceType.WL_SOURCE_ENCRYPT_FILE
wlPlayer?.setOnMediaInfoListener(object : WlOnMediaInfoListener {
override fun onPrepared() {
LoggerUtils.e("LiveSettingScene", "onPrepared")
wlPlayer?.start()
}

        override fun onTimeInfo(p0: Double, p1: Double) {
            LoggerUtils.e("LiveSettingScene", "onTimeInfo")
        }

        override fun onComplete(p0: WlCompleteType?, p1: String?) {
            LoggerUtils.e("LiveSettingScene", "onComplete")
        }

        override fun onLoad(p0: WlLoadStatus?, p1: Int, p2: Long) {
            LoggerUtils.e("LiveSettingScene", "onLoad")
        }

        override fun decryptBuffer(encryptBuffer: ByteArray?, position: Long): ByteArray {
            LoggerUtils.e("LiveSettingScene", "decryptBuffer")
            return super.decryptBuffer(encryptBuffer, position)
        }
    })
    wlPlayer?.source = playPath
    wlPlayer?.prepare()
    今天使用新版3.0.1测试,以上这个写法,onPrepared日志都不打印,是哪里有问题吗?

这个版本有包名限制,改为demo包名就可以测了

好吧。播放语音都包名限制啊。我以为还是视频水印限制。那先用旧版的

可以测一下问题解决没,后续版本会把包名限制去掉的

好的

可以测一下问题解决没,后续版本会把包名限制去掉的

好像还是限制了

新版本还没有发布哈,新版本和2.0一样也是水印版本的。

你好,新版本已更新,无包名限制了。