- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我们必须通过 UDP 构建加密/解密的语音聊天。聊天无需加密即可工作,但当我添加 AES 代码进行加密时,我听到非常大的噪音,这是连续的周期性蜂鸣信号,但同时我也听到解密的对话,这很好。我需要消除这种噪音。
我们将非常感谢您的帮助。谢谢
正在发送
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import javax.sound.sampled.*;
public class MicPlayer {
private static final String IP_TO_STREAM_TO = "localhost" ;
private static final int PORT_TO_STREAM_TO = 1234 ;
/** Creates a new instance of MicPlayer */
public MicPlayer() {
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Mixer.Info minfo[] = AudioSystem.getMixerInfo() ;
for( int i = 0 ; i < minfo.length ; i++ )
{
System.out.println( minfo[i] ) ;
}
if (AudioSystem.isLineSupported(Port.Info.MICROPHONE)) {
try {
DataLine.Info dataLineInfo = new DataLine.Info( TargetDataLine.class , getAudioFormat() ) ;
TargetDataLine targetDataLine = (TargetDataLine)AudioSystem.getLine( dataLineInfo ) ;
targetDataLine.open( getAudioFormat() );
targetDataLine.start();
byte tempBuffer[] = new byte[8192] ;
while( true )
{
targetDataLine.read( tempBuffer , 0 , tempBuffer.length );
byte[] encrypt = AES.encrypt(tempBuffer);
sendThruUDP(encrypt) ;
}
}
catch(Exception e )
{
System.out.println(" not correct " ) ;
System.exit(0) ;
}
}
}
public static AudioFormat getAudioFormat(){
float sampleRate = 8000.0F;
//8000,11025,16000,22050,44100
int sampleSizeInBits = 16;
//8,16
int channels = 1;
//1,2
boolean signed = true;
//true,false
boolean bigEndian = false;
//true,false
return new AudioFormat( sampleRate, sampleSizeInBits, channels, signed, bigEndian );
}
public static void sendThruUDP( byte soundpacket[] )
{
try
{
DatagramSocket sock = new DatagramSocket() ;
sock.send( new DatagramPacket( soundpacket , soundpacket.length , InetAddress.getByName( IP_TO_STREAM_TO ) , PORT_TO_STREAM_TO ) ) ;
sock.close() ;
}
catch( Exception e )
{
e.printStackTrace() ;
System.out.println(" Unable to send soundpacket using UDP " ) ;
}
}
}
接收
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
public class RadioReceiver extends Thread {
private static final String IP_TO_STREAM_TO = "localhost" ;
private static final int PORT_TO_STREAM_TO = 1234;
/** Creates a new instance of RadioReceiver */
public RadioReceiver() {
}
public void run()
{
byte b[] = null ;
while( true )
{
b = receiveThruUDP() ;
toSpeaker( b ) ;
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
RadioReceiver r = new RadioReceiver() ;
r.start() ;
}
public static byte[] receiveThruUDP()
{
try
{
DatagramSocket sock = new DatagramSocket(PORT_TO_STREAM_TO) ;
byte soundpacket[] = new byte[8192] ;
DatagramPacket datagram = new DatagramPacket( soundpacket , soundpacket.length , InetAddress.getByName( IP_TO_STREAM_TO ) , PORT_TO_STREAM_TO ) ;
sock.receive( datagram ) ;
sock.close() ;
return AES.decrypt(datagram.getData()); // soundpacket ;
}
catch( Exception e )
{
System.out.println(" Unable to send soundpacket using UDP " ) ;
return null ;
}
}
public static void toSpeaker( byte soundbytes[] )
{
try{
DataLine.Info dataLineInfo = new DataLine.Info( SourceDataLine.class , getAudioFormat() ) ;
SourceDataLine sourceDataLine = (SourceDataLine)AudioSystem.getLine( dataLineInfo );
sourceDataLine.open( getAudioFormat() ) ;
sourceDataLine.start();
sourceDataLine.write( soundbytes , 0, soundbytes.length );
sourceDataLine.drain() ;
sourceDataLine.close() ;
}
catch(Exception e )
{
System.out.println("not working in speakers " ) ;
}
}
public static AudioFormat getAudioFormat()
{
float sampleRate = 44100.0F;
//8000,11025,16000,22050,44100
int sampleSizeInBits = 16;
//8,16
int channels = 1;
//1,2
boolean signed = true;
//true,false
boolean bigEndian = false;
//true,false
return new AudioFormat( sampleRate, sampleSizeInBits, channels, signed, bigEndian );
}
}
AES
import java.security.MessageDigest;
import java.util.Arrays;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AES {
static String IV = "AAAAAAAAAAAAAAAA";
static String encryptionKey = "0123456789abcdef";
public static byte[] encrypt(byte[] inputcum) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE");
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8")));
return cipher.doFinal(inputcum);
}
public static byte[] decrypt(byte[] cipherSound) throws Exception{
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE");
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
cipher.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8")));
return cipher.doFinal(cipherSound);
}
}
最佳答案
该问题与 UDP 或加密无关。每次调用 TargetDataLine.read(byte[])
仅填充数组的一部分,其余部分则由之前调用的剩余部分填充,但每次都会加密并发送整个数组。
调用TargetDataLine.read(byte[])行为类似于 InputStream.read(byte[]) - 它返回传输到字节数组中的实际字节数。不能忽略该值。
对于最低工作流程,应按照以下准则修改代码:
发送时:
while( true ) {
int read = targetDataLine.read( tempBuffer , 0 , tempBuffer.length );
byte[] encrypt = AES.encrypt(tempBuffer, 0, read);
sendThruUDP(encrypt) ;
}
加密时(请注意,填充更改为 PKCS5Padding
以允许输入长度不是 AES block 大小的倍数):
public static byte[] encrypt(byte[] plainData, int offset, int length) throws Exception
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "SunJCE");
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8")));
return cipher.doFinal(plainData, offset, length);
}
应修改 decrypt()
方法以使用相同的填充。
其他最明显的改进:
Cipher
实例,然后使用 key 和新的 IV 重新初始化它。这将节省一些 CPU 和内存。关于java - Java 中通过 UDP 加密语音聊天的噪音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23783457/
我有一个说一些短语的音板应用程序,但是现在我希望能够从男声/女声中改变出来,问题是我不知道该怎么做。任何帮助,将不胜感激。 我正在使用AVFoundation/AVAudioPlayer播放声音。 谢
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 4 年前。
因为我想在后台录制音频,所以我使用了服务..但是我无法在服务中录制音频。 我在 Activity 中尝试了相同的代码,它对我有用。但是如何在输入语音/语音时在后台进行录音,这意味着如果有语音输入就应该
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 6 年前。
我有一个音频流,我会从中提取单词(语音)。因此,例如使用 audio.wav 我会得到 001.wav、002.wav、003.wav 等,其中每个 XXX.wav 是一个词。 我正在寻找一个库或程序
不幸的是,我只能说四种语言,那么如果我知道文本的语言,我如何知道我必须使用哪种 OS X 语音?我在Apple的文档中找不到任何有关它的信息。至少有一张有语音/语言的 table 吗? 最佳答案 您可
有没有办法从命令行使用 MS Speech 实用程序?我可以在 Mac 上完成,但在 Windows XP 上找不到任何引用。 最佳答案 我在这个主题上的 2 美分,命令行单行: 在 Win 上使用
所以我开始了我的不和谐机器人的音乐部分。现在,正如我在上一个问题中所做的那样,这里只是音乐命令的片段:Pastebin #1 在显示 if (msg.member.voiceConnection ==
有谁知道有什么好的 API 或库可以听(语音)文本。我尝试听三种语言的(语音)文本,我想知道最好从哪里开始以及如何开始。我可以对所有三种语言使用通用语音吗?我将使用 eclipse 和 java 作为
首先,我只是一个爱好者,如果这是一个愚蠢的问题或者我太天真了,我很抱歉。 (这也意味着我买不起昂贵的库) 情况是这样的:我正在使用 C#.NET 构建一个简单的语音聊天应用程序(类似于 Ventril
我正在制作一个模块,可以生成和传输语音 IP 数据包。我知道我必须为服务类型字段设置一些值。这个值是多少? 最佳答案 该值应该是x。 关于c - 语音 ip 的服务类型字段集,我们在Stack Ove
有人能帮帮我吗?我使用 SAPI 语音文本,但我不能设置女声,这是代码,它用男声说话,但我想改变它,我想要女声 #include "stdafx.h" using namespace std; voi
我正在寻找一种方法来为一个项目在 Java 中识别预注册的语音命令,但我还没有想出一个好的方法,我研究了快速傅里叶 和处理 wave 文件 的不同方法,但我无法决定我应该如何实现它。 这个想法很简单,
我在 android 的语音识别 API 工作。 我是 Speech Recognition Api 的新手,我的要求是西类牙语语音,并从 Android 的语音识别 API 中获得西类牙语的最佳匹配
我在 Java 中使用一组名为(MaryTTS[实际上还有更多])的库来将 text to speech 转换为该目的,使用以下代码: public class TextToSpeech {
我正在尝试使用webRTC和php作为服务器端来实现单向语音传输。 查看samples ,我无法理解webRTC机制。 在我看来,流程应该是这样的: 调用者和接收者在服务器上注册 接收者监听来电 调用
我的名字是 Joey,我想知道是否有一种在 C++ 中使用语音的方法,如果有人可以给我指出引用资料和书籍,非常感谢...... 最佳答案 你应该看看 Windows Text-To-Speech AP
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 8 年前。 Improve this qu
我正在使用 Java 语音识别 API - Jarvis,位于 https://github.com/lkuza2/java-speech-api 但是,当我运行应用程序时,出现错误:服务器返回 HT
我们正在做一个需要讲阿拉伯语的项目,我们找到了一个开源工具,Mbrola project , 可以做到这一点。 但是,我还需要一些方法将阿拉伯语文本转换为 SAMPA 语音。那么有人可以帮助我将阿拉伯
我是一名优秀的程序员,十分优秀!