0

SD カードから暗号化された mp4 ビデオ ファイルを再生しています。このために私がすること.....

ステップ 1. SD カードから内部メモリにファイルをコピーし、再生できるように、そのファイルを誰でも読み書きできる形式で書き込みます。

STEP 2.一時フォルダーでそのファイルを復号化します

STEP 3.これを再生します。ファイルは問題なく再生されます

問題は、ファイルが約 25 MB と大きく、このプロセス (コピーと復号化) に約 2 分かかるため、このプロセスに時間がかかることです。

いくつか読んだ後、この問題の解決策を見つけました libmedia ライブラリを使用することで時間を短縮できますが、 libmedia ライブラリを使用してこれを再生すると、ログにエラーが発生するという問題に直面しています cat

10-10 06:33:42.908: E/MediaPlayer(9249): error (1, -2147483648)

アクティビティ画面で、ダイアログに「ビデオを再生できません」というメッセージが表示されました

libmedia ライブラリ リンクはhttp://libeasy.alwaysdata.net/です。

あなたの貴重な提案と助けに感謝します

私の活動コードは

package com.example.playvideo2;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

import fr.maxcom.http.LocalSingleHttpServer;
import fr.maxcom.libmedia.Licensing;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.view.Menu;
import android.widget.MediaController;
import android.widget.VideoView;


public class MainActivity extends Activity implements OnCompletionListener 
{
    LocalSingleHttpServer mServer;
    VideoView mVideoView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.video_view);

        Licensing.allow(this);
        playENCVideo(Environment.getExternalStorageDirectory()
                + "/encVideo.mp4");
    }

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

public void playENCVideo(String path) {

    try {
        Cipher decipher = null;

        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        SecretKey skey = kgen.generateKey();

        decipher = Cipher.getInstance("AES");

        decipher.init(Cipher.DECRYPT_MODE, skey);

        mServer = new LocalSingleHttpServer();

        mServer.setCipher(decipher);
        mServer.start();

        path = mServer.getURL(path);

        mVideoView = (VideoView) findViewById(R.id.videoView1);
        mVideoView.setVideoPath(path);

        // mVideoView.setMediaController(new MediaController(this));
        // mVideoView.requestFocus();
        mVideoView.start();
    } catch (InvalidKeyException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

@Override
public void onCompletion(MediaPlayer mp) {
    // MediaPlayer.OnCompletionListener interface
    mServer.stop();

}

}

私のマニフェストファイルは

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.playvideo2"
    android:versionCode="1"
    android:versionName="1.0" 
    >

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="18" />

<uses-permission android:name="android.permission.INTERNET" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.example.playvideo2.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <meta-data
        android:name="fr.maxcom.libmedia.apiKey"
        android:value="qV1T3Zf+IyCpb1jomsomS3NUXBk7LdDaV31DcwmVIoMpvWWK8xAQIl1RUVWQegSt2jJbwH+cleik7YCH2/chP1JWdhpSfgMaNRl3fDMOez8mGn98Jhp7KyAffjc5RA==" />
</application>

</manifest>

これは、暗号化と復号化に使用したコードです

        FileInputStream fis = new FileInputStream(new File("D:/QLurnVideo/inputVideo.mp4"));
        File outfile = new File("D:/QLurnVideo/encVideo.mp4");
        int read;
        if(!outfile.exists())
            outfile.createNewFile();
        File decfile = new File("D:/QLurnVideo/decVideo.mp4");
        if(!decfile.exists())
            decfile.createNewFile();
        FileOutputStream fos = new FileOutputStream(outfile);
        FileInputStream encfis = new FileInputStream(outfile);
        FileOutputStream decfos = new FileOutputStream(decfile);
        Cipher encipher = Cipher.getInstance("AES");
        Cipher decipher = Cipher.getInstance("AES");
        KeyGenerator kgen = KeyGenerator.getInstance("AES");

        SecretKey skey = kgen.generateKey();
        //Lgo
        encipher.init(Cipher.ENCRYPT_MODE, skey);
        CipherInputStream cis = new CipherInputStream(fis, encipher);
        decipher.init(Cipher.DECRYPT_MODE, skey);
        CipherOutputStream cos = new CipherOutputStream(decfos,decipher);
        while((read = cis.read())!=-1)
                {
                    fos.write((char)read);
                    fos.flush();
                }   
        fos.close();
        while((read=encfis.read())!=-1)
        {
            cos.write(read);
            cos.flush();
        }
cos.close();
4

3 に答える 3

4

ビデオを文字ごとに暗号化しています。これは、このようなバッファを使用して行ごとに行う方がはるかに時間がかかります..

byte[] buff=new byte[1024];
while((read = cis.read(buff))!=-1)
            {
                fos.write(buff,0,read);
                fos.flush();
            }   
    fos.close();
    while((read=encfis.read(buff))!=-1)
    {
        cos.write(buff,0,read);
        cos.flush();
    }
cos.close();
于 2013-10-25T05:16:56.243 に答える
2

あなたの問題は主に、暗号化コードと playENCVideo() で同じ SecretKey を使用しないという事実によるものです。これは、generateKey() が呼び出しごとに異なるランダム項目を返すためです。

KeyGenerator ではなく SecretKeySpec を使用して、2 つのコード間の一貫性を維持してください。

次に、できればブロック暗号ではなく、ARC4 などのストリーム暗号を使用してください。AES のデフォルトは、ブロック暗号である「AES/ECB」です。

Libmedia はバージョン 1.0.1 からブロック暗号を使用できますが、コンテキスト内のストリーム暗号と比較して、メリットはなく、煩わしいだけです。

例:

Cipher c = Cipher.getInstance("ARC4");
c.init(Cipher.DECRYPT_MODE, new SecretKeySpec("BrianIsInTheKitchen".getBytes(), "ARC4"));
于 2013-12-04T17:56:17.207 に答える
0

暗号化と復号化に異なるキーを使用しています。同じキーを使用すると機能します。暗号化キーを playENCVideo 関数に渡し、それを使用するだけです。

于 2016-07-15T07:17:14.743 に答える