我想使用一台服务器从我的麦克风中捕获音频并发送给客户端(0 或 4)...
PD:我正在检查这个问题:Sending audio stream over TCP, UnsupportedAudioFileException但面向 One server with One Client 解决方案。 其他问题:Java - Broadcast voice over Java sockets Streaming audio from microphone with Java
我正在考虑使用 TCP(服务器/客户端模型),但服务器和 4 个客户端将接收数据(音频流),我不知道是否可以实现此替代方案(我担心港口管理)...
这里是我的初步(它仍然没有用,因为我有疑问,我在想如何解决我的顾虑)
变量:
static boolean bThreadCapture = false;
static boolean bThreadServer = false;
static ByteArrayOutputStream myByteArrayOutStream;
ExecutorService myServerPool = Executors.newFixedThreadPool(4);
static Thread myThreadServer = null;
现在我头疼
final int iServerPort = 2370;
final AudioFormat myAudioFormat = new AudioFormat(8000,8,1,false, true);
final DataLine.Info myDataLineInfo = new DataLine.Info(TargetDataLine.class, myAudioFormat);
if (!AudioSystem.isLineSupported(myDataLineInfo)) {
System.out.println("Line not supported");
System.exit(0);
}
try {
final TargetDataLine myTargetDataLine = (TargetDataLine) AudioSystem.getLine(myDataLineInfo);
myTargetDataLine.open(myAudioFormat);
myByteArrayOutStream = null;
//BEGIN definition Thread for CAPTURING AUDIO FROM MIC
Runnable runnAudioCapture = new Runnable() {
int bufferSize = (int) myAudioFormat.getSampleRate()* myAudioFormat.getFrameSize();
byte buffer[] = new byte[bufferSize];
public void run() {
myByteArrayOutStream = new ByteArrayOutputStream();
bThreadCapture = true;
while (bThreadCapture) {
try {
int count = myTargetDataLine.read(buffer, 0, buffer.length);
if (count > 0) {
myByteArrayOutStream.write(buffer, 0, count);
// HERE: I need to send the bytes of Sound to all active Threads Client (from 1 until 4)
// But, How to know what (how much and which) are active threads client?
// How to access to each Executor?
}
} catch (IllegalArgumentException | ArrayIndexOutOfBoundsException e) {
System.err.println("TargetDataLine problems: " + e);
}
}
try {
if (myByteArrayOutStream != null) myByteArrayOutStream.close();
} catch (IOException e) { }
}
};
//END definition Thread for CAPTURING AUDIO FROM MIC
//BEGIN definition Thread for ATTENDANT SERVER CLIENT (Still not defined)
myThreadServer = new Thread() {
@Override
public void run() {
try {
SrvrSocketProducer = new ServerSocket(iServerPort);
System.out.println("Server Listening on port number: "+iServerPort);
} catch (IOException e) {
System.out.println("Could not listen on port: "+iServerPort);
}
new Thread(runnAudioCapture).start(); //BEGIN AUDIO CAPTURE
while(bThreadServer) {
Socket clientSocket = null;
try {
clientSocket = SrvrSocketProducer.accept();
} catch (IOException e) {
if(!bThreadServer) {
System.out.println("Server Stopped.") ;
break;
}
throw new RuntimeException("Error accepting client connection", e);
}
myServerPool.execute(new runnWorkerListener(clientSocket,myAudioFormat));
}
myServerPool.shutdown();
bThreadCapture = false; //STOP AUDIO CAPTURE
}
};
//END definition Thread for ATTENDANT SERVER CLIENT (Still not defined)
myThreadServer.start();
} catch (LineUnavailableException ex) {
System.out.println(ex.toString());
}
问题:
(合并到runnAudioCapture代码中定位帮助)
1. HERE: I need to send the bytes of Sound to all ACTIVE Threads Client (from 1 until 4)
2. But, How to know what (how much and which) are active threads client?
3. How to access to each Executor?
现在工作线程--
class runnWorkerListener implements Runnable {
Socket innerClientSocket = null;
AudioFormat innerAdfmt = null;
public runnWorkerListener(Socket clientSocket, AudioFormat audioFormat) {
innerClientSocket = clientSocket;
innerAdfmt = audioFormat;
}
public void run() {
try {
InputStream input = innerClientSocket.getInputStream();
OutputStream output = innerClientSocket.getOutputStream();
// Now How Can I to Comunicate with runnAudioCapture?
while (RunningClientAttender /*This variable still is not defined*/) {
// I need to send (thread client here Not defined) EACH bytes from runnAudioCapture
}
output.close();
input.close();
System.out.println("Request processed: ");
} catch (IOException e) {
//report exception somewhere.
e.printStackTrace();
}
}
}
问题:
(合并到runnWorkerListener代码中定位帮助)
1. Now How Can I to Comunicate with runnAudioCapture?
2. I need to send (thread client here Not defined) EACH bytes from runnAudioCapture
我的疑问与: 一个专用于音频捕获的线程 一个线程专用于使用 Pool 接收客户端(1、2、3 或 4)并创建线程 worker (一个线程 worker 与“远程”客户端通信)
我不知道 Capturer 线程 Capturer 与每个 Worker 线程的句柄同步...
谢谢...
最佳答案
不幸的是,在 Java 中,流一次只能由一个人使用。您有一个流 myByteArrayOutStream,并且您希望在 4 个 TCP 连接之间共享它。
我建议您将音频数据写入文件。每次客户端连接时,您都会将文件的所有内容流式传输到该客户端(您可以打开文件,跳到最后,如果需要,只流式传输新内容)。为此,您需要为每个客户创建一个新线程。
如果您希望在 Java 中构建类似 Skype 音频的东西,那么这比仅使用 TCP 稍微复杂一些。 TCP 是一种从 A 到 B 获取数据的方法,可靠。对于音频,您通常希望它实时从 A 传输到 B。如果您在此过程中丢失了一个数据包,您不想返回并重新传输它,因为那样会给调用引入延迟。 TCP 的替代方案(可能更适合您的情况)是 UDP。它发送单个数据包,并且不保证它们会按顺序到达,甚至根本不保证。但它不会停下来等待丢失的数据包。
关于JAVA(发送音频流 一服务器四客户端同机),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35491848/
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru
在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo
我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
您如何在Rails中的实时服务器上进行有效调试,无论是在测试版/生产服务器上?我试过直接在服务器上修改文件,然后重启应用,但是修改好像没有生效,或者需要很长时间(缓存?)我也试过在本地做“脚本/服务器生产”,但是那很慢另一种选择是编码和部署,但效率很低。有人对他们如何有效地做到这一点有任何见解吗? 最佳答案 我会回答你的问题,即使我不同意这种热修补服务器代码的方式:)首先,你真的确定你已经重启了服务器吗?您可以通过跟踪日志文件来检查它。您更改的代码显示的View可能会被缓存。缓存页面位于tmp/cache文件夹下。您可以尝试手动删除
rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我