Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
ail36413 opened this issue Feb 27, 2024 · 25 comments
Open

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

ail36413 opened this issue Feb 27, 2024 · 25 comments

Comments

@ail36413
Copy link

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

@ywl5320
Copy link
Owner

ywl5320 commented Feb 27, 2024

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

@ail36413
Copy link
Author

ail36413 commented Feb 28, 2024

播放这边简单的文件加密要如何处理?
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回调解密,不可以

@ywl5320
Copy link
Owner

ywl5320 commented Feb 28, 2024

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

@ail36413
Copy link
Author

好的。我去试试看

@ail36413
Copy link
Author

ail36413 commented Mar 6, 2024

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

@ail36413
Copy link
Author

ail36413 commented Mar 6, 2024

我通过位移加解密,目前是可以正常播放的。但是遇到了一个新的问题,就是 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;
}

@ail36413
Copy link
Author

ail36413 commented Mar 6, 2024

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

@ywl5320
Copy link
Owner

ywl5320 commented Mar 6, 2024

未加密文件播放正常不呢

@ail36413
Copy link
Author

ail36413 commented Mar 6, 2024

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

@ail36413
Copy link
Author

ail36413 commented Mar 6, 2024

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

@ail36413
Copy link
Author

ail36413 commented Mar 6, 2024

这个日志回调有点奇怪
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秒全部播完的时候,会再次回调一次数据,所以导致又继续播了一次

@ail36413
Copy link
Author

ail36413 commented Mar 6, 2024

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

@ywl5320
Copy link
Owner

ywl5320 commented Mar 6, 2024

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

@ail36413
Copy link
Author

ail36413 commented Mar 6, 2024

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

@ywl5320
Copy link
Owner

ywl5320 commented Mar 6, 2024

那现在解决了嘛

@ail36413
Copy link
Author

ail36413 commented Mar 6, 2024

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

@ywl5320
Copy link
Owner

ywl5320 commented Mar 6, 2024

好的

@ail36413
Copy link
Author

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

@ywl5320
Copy link
Owner

ywl5320 commented Mar 21, 2024

好的 我们测试一下

@ywl5320
Copy link
Owner

ywl5320 commented May 20, 2024

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

@ail36413
Copy link
Author

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日志都不打印,是哪里有问题吗?

@ywl5320
Copy link
Owner

ywl5320 commented Sep 11, 2024

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

@ail36413
Copy link
Author

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

@ywl5320
Copy link
Owner

ywl5320 commented Sep 11, 2024

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

@ail36413
Copy link
Author

好的

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants