Android Exoplayer从SD卡播放加密媒体的问题

时间:2017-07-08 11:31:05

标签: android aes media exoplayer

我正在开发一个从设备的SD卡读取加密数据并使用exoplayer播放的应用程序,我的代码在加密媒体时成功运行并且在这种情况下播放它完美地工作但我在重新启动应用程序时遇到问题(当我已经有加密的媒体文件时)并直接播放媒体,它给了我以下异常

  

om.example.myapplication E / ExoPlayerImplInternal:源错误。   com.google.android.exoplayer2.source.UnrecognizedInputFormatException:   没有可用的提取器(MatroskaExtractor,   FragmentedMp4Extractor,Mp4Extractor,Mp3Extractor,AdtsExtractor,   Ac3Extractor,TsExtractor,FlvExtractor,OggExtractor,PsExtractor,   WavExtractor)可以读取流。在   com.google.android.exoplayer2.source.ExtractorMediaPeriod $ ExtractorHolder.selectExtractor(ExtractorMediaPeriod.java:722)   在   com.google.android.exoplayer2.source.ExtractorMediaPeriod $ ExtractingLoadable.load(ExtractorMediaPeriod.java:645)   在   com.google.android.exoplayer2.upstream.Loader $ LoadTask.run(Loader.java:295)   在   java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)   在   java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:587)   在java.lang.Thread.run(Thread.java:841)

下面是我播放媒体的代码

    public void playVideo(View view) {
        mEncryptedFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
                + "/enc_oliver.mp4");
        Log.e("Enc Filename =", mEncryptedFile.getName());
        if (hasFile()) {
        DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
        TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(
                bandwidthMeter);
        TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
//        LoadControl loadControl = new DefaultLoadControl();
        SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(this, trackSelector);
        mSimpleExoPlayerView.setPlayer(player);
        DataSource.Factory dataSourceFactory = new EncryptedFileDataSourceFactory(mCipher,
                mSecretKeySpec, mIvParameterSpec, bandwidthMeter);
        ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
        try {
            Uri uri = Uri.fromFile(inputFile);
            MediaSource videoSource = new ExtractorMediaSource(uri, dataSourceFactory,
                    extractorsFactory, null, null);
            player.prepare(videoSource);
            player.setPlayWhenReady(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        } else {
            Log.e("ERROR!!", "File not found");
        }
    }

 public void playAudio(View view) {
        BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
        ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();

        TrackSelection.Factory trackSelectionFactory = new AdaptiveTrackSelection.Factory(
                bandwidthMeter);

        TrackSelector trackSelector = new DefaultTrackSelector(trackSelectionFactory);

        DefaultBandwidthMeter defaultBandwidthMeter = new DefaultBandwidthMeter();
        DataSource.Factory dataSourceFactory = new EncryptedFileDataSourceFactory(mCipher,
                mSecretKeySpec, mIvParameterSpec, defaultBandwidthMeter);

        Uri uri = Uri.fromFile(mEncryptedFile);
        MediaSource mediaSource = new ExtractorMediaSource(uri, dataSourceFactory,
                extractorsFactory, null, null);
        SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(this, trackSelector);
        player.prepare(mediaSource);
        player.setPlayWhenReady(true);
    }

我正在使用以下机制来第一次加密文件,这导致第一次成功第二次它不会执行'我已经有加密文件

public static final String AES_ALGORITHM = "AES";
    public static final String AES_TRANSFORMATION = "AES/CTR/NoPadding";
    private void initKey() {
        SecureRandom secureRandom = new SecureRandom();
        byte[] key = new byte[16];
        byte[] iv = new byte[16];
        key = "abctestkeyforand".getBytes();
        secureRandom.nextBytes(iv);

        mSecretKeySpec = new SecretKeySpec(key, AES_ALGORITHM);
        mIvParameterSpec = new IvParameterSpec(iv);


    }

public void encryptFiles(View view) {
        File musicDirectory = new File(Environment.getExternalStorageDirectory().getAbsoluteFile()
                + "/Music");
        File[] audioFiles = musicDirectory.listFiles();
        if (audioFiles != null && audioFiles.length > 0) {
            for (File singleAudioFile : audioFiles) {
                inputFile = singleAudioFile;
                Log.e("Input Filename =", inputFile.getName());
                mEncryptedFile = new File(musicDirectory, "enc_" + inputFile.getName());
                Log.e("Enc Filename =", inputFile.getName());
                if (hasFile()) {
                    Log.d(getClass().getCanonicalName(),
                            "encrypted file found, no need to recreate");
                    continue;
                }
                try {
                    Cipher encryptionCipher = Cipher.getInstance(AES_TRANSFORMATION);
                    encryptionCipher.init(Cipher.ENCRYPT_MODE, mSecretKeySpec, mIvParameterSpec);
                    new EncryptFileTask(inputFile, mEncryptedFile, encryptionCipher).execute();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

public void encryptFile(View view) {
        inputFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
                + "/oliver.mp4");

        Log.e("Input Filename =", inputFile.getName());
        mEncryptedFile = new File(inputFile.getParent(), "enc_" + inputFile.getName());
        Log.e("Enc Filename =", mEncryptedFile.getName());
        if (hasFile()) {
            Log.d(getClass().getCanonicalName(),
                    "encrypted file found, no need to recreate");
            return;
        }
        try {
            Cipher encryptionCipher = Cipher.getInstance(AES_TRANSFORMATION);
            encryptionCipher.init(Cipher.ENCRYPT_MODE, mSecretKeySpec, mIvParameterSpec);
            new EncryptFileTask(inputFile, mEncryptedFile, encryptionCipher).execute();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


public class EncryptFileTask extends AsyncTask<Void, Void, Boolean> {

    private File inputFile;
    private File mFile;
    private Cipher mCipher;

    public EncryptFileTask(File inputFile, File file, Cipher cipher) {

        this.inputFile = inputFile;
        mFile = file;
        mCipher = cipher;
    }

    private boolean downloadAndEncrypt() throws Exception {
        try {
            long startTime = System.currentTimeMillis();
            FileInputStream inputStream = new FileInputStream(inputFile);
            FileOutputStream fileOutputStream = new FileOutputStream(mFile);
            CipherOutputStream cipherOutputStream = new CipherOutputStream(fileOutputStream,
                    mCipher);

            byte buffer[] = new byte[1024 * 1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                cipherOutputStream.write(buffer, 0, bytesRead);
            }

            inputStream.close();
            cipherOutputStream.close();

            float totalTimeInSeconds = (System.currentTimeMillis() - startTime) / 1000f;
            Log.e("Encryption", "Completed for " + inputFile.getName() + " in " + totalTimeInSeconds
                    + " seconds");
            return true;
        } catch (Exception err) {
            err.printStackTrace();
            return false;
        }

//    connection.disconnect();
    }

    @Override
    protected Boolean doInBackground(Void... params) {
        try {
            return downloadAndEncrypt();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    protected void onPostExecute(Boolean aVoid) {
        Log.e(getClass().getCanonicalName(), "Encryption done");
        if (aVoid) {
            inputFile.delete();
        }
    }
}

将从活动的onCreate()调用initKey(),请提供解决此问题的建议/解决方案

0 个答案:

没有答案