下载时加密音频 mp3 文件,在 android 中播放时解密

Encrypt audio mp3 file while downloading and decrypt it while playing in android

我有一个 android 应用程序可以下载和播放 mp3 文件。但我想在下载时加密音频文件,然后解密播放。我已经在互联网上到处检查但没有找到任何解决方案。谁能帮我如何在下载时加密音频文件然后在播放时解密 这是我下载文件的代码

     private void download() {
    if (Constant.arrayList_play.size() > 0) {

        File root = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Myapp/cache");
        if (!root.exists()) {
            root.mkdirs();
        }

        File file = new File(root, Constant.arrayList_play.get(viewpager.getCurrentItem()).getMp3Name() + ".mp3");

        if (!file.exists()) {

            String url = Constant.arrayList_play.get(viewpager.getCurrentItem()).getMp3Url();
            DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
            request.setDescription(getResources().getString(R.string.downloading) + " - " + Constant.arrayList_play.get(viewpager.getCurrentItem()).getMp3Name());
            request.setTitle(Constant.arrayList_play.get(viewpager.getCurrentItem()).getMp3Name());
            request.allowScanningByMediaScanner();
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
            request.setDestinationUri(Uri.parse("file://" + Environment.getExternalStorageDirectory().getAbsolutePath() + "/Myapp/cache/" + Constant.arrayList_play.get(viewpager.getCurrentItem()).getMp3Name() + ".mp3"));
            DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
            manager.enqueue(request);

            new AsyncTask<String, String, String>() {
                @Override
                protected String doInBackground(String... strings) {
                    String json = JsonUtils.getJSONString(Constant.URL_DOWNLOAD_COUNT + Constant.arrayList_play.get(viewpager.getCurrentItem()).getId());
                    Log.e("aaa - ", json);
                    return null;
                }
            }.execute();
            Toast.makeText(MainActivity.this, getResources().getString(R.string.downloading), Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(MainActivity.this, getResources().getString(R.string.already_download), Toast.LENGTH_SHORT).show();
        }
    } else {
        Toast.makeText(MainActivity.this, getResources().getString(R.string.no_song_selected), Toast.LENGTH_SHORT).show();
    }
}

那么你能帮我一个代码吗?

我已经找到了我的问题的解决方案,并且已经在我的应用程序中使用了很多天,没有任何问题,所以我认为最好回答我自己的问题,因为许多用户在评论中要求解决方案。所以只需遵循以下代码-

  //Downloading and encrypting the audio

  AesCipherDataSink encryptingDataSink = new AesCipherDataSink(
      Util.getUtf8Bytes("4J95qN8RxBP8hTpk"),
      new DataSink() {
       private FileOutputStream fileOutputStream;

       @Override
       public void open(DataSpec dataSpec) throws IOException {
               fileOutputStream = new FileOutputStream(file);
        }

       @Override
       public void write(byte[] buffer, int offset, int length) throws IOException {
          fileOutputStream.write(buffer, offset, length);
        }

       @Override
       public void close() throws IOException {
             fileOutputStream.close();
         }
        });

   // Push the data through the sink, and close everything.
   encryptingDataSink.open(new DataSpec(Uri.fromFile(file)));
   URL downloadURL = new URL(strings[0]);
   HttpURLConnection connection = (HttpURLConnection) downloadURL.openConnection();
   connection.setChunkedStreamingMode(0);
   connection.setDoInput(true);
   connection.connect();
   if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
      return "Server error";
   }

   InputStream inputStream = connection.getInputStream();
   byte[] buffer = new byte[1024];
   int newLength;
   while ((newLength = inputStream.read(buffer)) > 0) {
        encryptingDataSink.write(buffer, 0, newLength);
    }
   encryptingDataSink.close();
   inputStream.close();



   //decrypting and playing the audio
   DataSource.Factory factory =
                new CustomDataSourceFactory(
                        context,
                        new OkHttpDataSourceFactory(new OkHttpClient(), Util.getUserAgent(context,
                              context.getResources().getString(R.string.app_name)))
                );

    MediaSource videoSource =
                new ProgressiveMediaSource.Factory(factory)
                        .createMediaSource(Uri.parse(tempFile.getAbsolutePath()));
    exoPlayer.addMediaSource(videoSource);

    
   //CustomDataSourceFactoryClass

    public class CustomDataSourceFactory implements DataSource.Factory {

      private final Context context;
      private final DataSource.Factory baseDataSourceFactory;


      public CustomDataSourceFactory(Context context, DataSource.Factory baseDataSourceFactory) {
        this.context = context.getApplicationContext();
        this.baseDataSourceFactory = baseDataSourceFactory;
       }

       @Override
        public DataSource createDataSource() {
         return new CryptedDefaultDataSource(context, baseDataSourceFactory.createDataSource());
         }
      }

   //CryptedDafaultDataSource
    public class CryptedDefaultDataSource implements DataSource {

      private final List<TransferListener> transferListeners;
      private final DataSource baseDataSource;
      private @Nullable
      DataSource fileDataSource,aesCipherDataSource,dataSource;
      private Context context;

      CryptedDefaultDataSource(Context context, DataSource baseDataSource) {
         this.context=context;
         this.baseDataSource = Assertions.checkNotNull(baseDataSource);
         transferListeners = new ArrayList<>();
      }

      @Override
      public void addTransferListener(TransferListener transferListener) {
       baseDataSource.addTransferListener(transferListener);
       transferListeners.add(transferListener);
       maybeAddListenerToDataSource(fileDataSource, transferListener);
       maybeAddListenerToDataSource(aesCipherDataSource, transferListener);
      }

     @Override
     public long open(DataSpec dataSpec) throws IOException {
        Assertions.checkState(dataSource == null);
        if (Util.isLocalFileUri(dataSpec.uri)) {
          dataSource = getCryptedDataSource(getFileDataSource());
        } else {
          dataSource = getCryptedDataSource(baseDataSource);
        }
       return dataSource.open(dataSpec);
      }

     @Override
      public int read(byte[] buffer, int offset, int readLength) throws IOException {
         return Assertions.checkNotNull(dataSource).read(buffer, offset, readLength);
       }

      @Nullable
      @Override
       public Uri getUri() {
        return dataSource == null ? null : dataSource.getUri();
      }

      @Override
      public Map<String, List<String>> getResponseHeaders() {
          return dataSource == null
            ? DataSource.super.getResponseHeaders()
            : dataSource.getResponseHeaders();
       }

     @Override
     public void close() throws IOException {
       if (dataSource != null) {
        try {
            dataSource.close();
        } finally {
            dataSource = null;
        }
      }
     }

    private DataSource getFileDataSource() {
      if (fileDataSource == null) {
         fileDataSource = new FileDataSource();
         addListenersToDataSource(fileDataSource);
       }
       return fileDataSource;
     }

    private DataSource getCryptedDataSource(DataSource upstreamDataSource) {
      if (aesCipherDataSource == null) {
        aesCipherDataSource = new AesCipherDataSource("4J95qN8RxBP8hTpk".getBytes(),upstreamDataSource);
        addListenersToDataSource(aesCipherDataSource);
      }
      return aesCipherDataSource;
     }

   private void addListenersToDataSource(DataSource dataSource) {
     for (int i = 0; i < transferListeners.size(); i++) {
        dataSource.addTransferListener(transferListeners.get(i));
     }
   }

     private void maybeAddListenerToDataSource(
        @Nullable DataSource dataSource, TransferListener listener) {
      if (dataSource != null) {
        dataSource.addTransferListener(listener);
      }
     }
   }