简体   繁体   中英

How to decrypt audio file in the form of stream in Flutter/Dart?

Project Requirement: Music player app which will download audio files, encrypt and save them. The audio files should be playable in the app only. No other app should be able to play the files. Nor the user should be able to copy the files.

Approach: I don't want the entire decryted audio file to exist at any moment. So I want to encrypt the audio file as soon as it is downloaded. Then when the file is to be played, I want it to be decrypted chunk-by-chunk and played. I believe this can be achieved by using stream. As far as I searched, a package named "just_audio" can play the audio from stream source.

Problem: I cannot find any encryption package for Flutter/Dart which will output the decrypted data in the form of a stream. This is the first time I am trying to implement encryption/decryption, so my knowledge is very poor in this regard.

Notes:

  1. The encryption does not need to be heavy. A typical user not being able to copy the files and play them elsewhere would suffice.
  2. Audio files are going to be large, some of them even hours in length.
  3. I need all the usual functions of a music player (eg albums, playlists, progress bars with seeking function, etc.)

Options:

  1. It will be best if there is a package which can do what I need, off the shelf.
  2. To find a basic package and then modifying it into doing what is needed.
  3. Some radically different solution, which takes entirely different path but provides all the solutions.

Firstly, to encrypt or decrypt data, have a look at https:\/\/pub.dev\/packages\/cryptography<\/a> or https:\/\/pub.dev\/packages\/encrypt<\/a> or something like that.

Instead, divide whole audio (say 1hour) into chunks (say 1minute), and upload\/encrypt\/decrypt\/download each chunk separately and as a whole without using streams. If your chunk is small enough, download\/decrypt a chunk will be fast and you do not stuck the UI. If the decrypting is still too slow, have a look at isolates<\/em> , which are "threads" in Flutter. Run decrypt in a separate isolate then your UI will be smooth.

For albums\/playlists, you may modify any normal audio players in flutter to implement that, or directly implement by your own. it is more like just some UI things, no special things, and anyone familiar with Flutter can write it, no worry.

if you're open to a 3rd package, don't reinvent the wheel..

try this here https://morioh.com/p/34a06006b299 with various CipherStream Options

If you can forego stream encryption and do it after you have the file then try this package , Credit: I used the sample from this answer by Hoaea Varghese

With AES all you need is the path to the file, and you can encrypt files or albums with something as simple as

encrypted_file_path = EncryptData.encrypt_file('your/file/path');

With the code below

import 'dart:io';
import 'package:aes_crypt/aes_crypt.dart';

class EncryptData {
  static String encrypt_file(String path) {
    AesCrypt crypt = AesCrypt();
    crypt.setOverwriteMode(AesCryptOwMode.on);
    crypt.setPassword('my cool password');
    String encFilepath;
    try {
      encFilepath = crypt.encryptFileSync(path);
      print('The encryption has been completed successfully.');
      print('Encrypted file: $encFilepath');
    } catch (e) {
      if (e.type == AesCryptExceptionType.destFileExists) {
        print('The encryption has been completed unsuccessfully.');
        print(e.message);
      }
      else{
        return 'ERROR';
      }
    }
    return encFilepath;
  }

  static String decrypt_file(String path) {
    AesCrypt crypt = AesCrypt();
    crypt.setOverwriteMode(AesCryptOwMode.on);
    crypt.setPassword('my cool password');
    String decFilepath;
    try {
      decFilepath = crypt.decryptFileSync(path);
      print('The decryption has been completed successfully.');
      print('Decrypted file 1: $decFilepath');
      print('File content: ' + File(decFilepath).path);
    } catch (e) {
      if (e.type == AesCryptExceptionType.destFileExists) {
        print('The decryption has been completed unsuccessfully.');
        print(e.message);
      }
      else{
        return 'ERROR';
      }
    }
    return decFilepath;
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM