我一直在尝试使用Android内置的MediaPlayer类来流式传输mp3.文档会告诉我,这应该像以下一样简单:
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(URL_OF_FILE);
mp.prepare();
mp.start();
Run Code Online (Sandbox Code Playgroud)
但是我反复得到以下内容.我也尝试过不同的URL.请不要告诉我流式传输不适用于mp3.
E/PlayerDriver( 31): Command PLAYER_SET_DATA_SOURCE completed with an error or info PVMFErrNotSupported
W/PlayerDriver( 31): PVMFInfoErrorHandlingComplete
E/MediaPlayer( 198): error (1, -4)
E/MediaPlayer( 198): start called in state 0
E/MediaPlayer( 198): error (-38, 0)
E/MediaPlayer( 198): Error (1,-4)
E/MediaPlayer( 198): Error (-38,0)
Run Code Online (Sandbox Code Playgroud)
任何帮助非常感谢,谢谢S
我想记录用户网络摄像头和音频,并将其保存到服务器上的文件中.然后,这些文件可以提供给其他用户.
我没有播放问题,但是我在录制内容方面遇到了问题.
我的理解是.record()还没有编写getUserMedia 函数 - 到目前为止只提出了一个提议.
我想使用PeerConnectionAPI在我的服务器上创建一个对等连接.我知道这有点hacky,但我认为应该可以在服务器上创建一个peer并记录client-peer发送的内容.
如果可以,我应该能够将此数据保存为flv或任何其他视频格式.
我的偏好实际上是记录网络摄像头+音频客户端,以允许客户端在上传前不喜欢他们的第一次尝试时重新录制视频.这也将允许网络连接中断.我已经看到一些代码允许通过将数据发送到画布来记录网络摄像头中的各个"图像" - 这很酷,但我也需要音频.
这是我到目前为止的客户端代码:
<video autoplay></video>
<script language="javascript" type="text/javascript">
function onVideoFail(e) {
console.log('webcam fail!', e);
};
function hasGetUserMedia() {
// Note: Opera is unprefixed.
return !!(navigator.getUserMedia || navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia || navigator.msGetUserMedia);
}
if (hasGetUserMedia()) {
// Good to go!
} else {
alert('getUserMedia() is not supported in your browser');
}
window.URL = window.URL || window.webkitURL;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia || navigator.msGetUserMedia;
var video = document.querySelector('video');
var …Run Code Online (Sandbox Code Playgroud) 我正在尝试播放一个MP3传递给UIView前一个文件的文件UIView(存储在一个NSURL *fileURL变量中).
我正在初始化一个AVPlayer:
player = [AVPlayer playerWithURL:fileURL];
NSLog(@"Player created:%d",player.status);
Run Code Online (Sandbox Code Playgroud)
我想的NSLog印刷品Player created:0,意味着它尚未准备好播放.
当我点击播放时UIButton,我运行的代码是:
-(IBAction)playButtonClicked
{
NSLog(@"Clicked Play. MP3:%@",[fileURL absoluteString]);
if(([player status] == AVPlayerStatusReadyToPlay) && !isPlaying)
// if(!isPlaying)
{
[player play];
NSLog(@"Playing:%@ with %d",[fileURL absoluteString], player.status);
isPlaying = YES;
}
else if(isPlaying)
{
[player pause];
NSLog(@"Pausing:%@",[fileURL absoluteString]);
isPlaying = NO;
}
else {
NSLog(@"Error in player??");
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行它时,我总是进入Error in player??控制台.然而,如果我用一个简单的...... 替换if检查是否 …
这更像是一个概念性问题而不是直接"如何做到这一点".
通常是否可以实现类似flash的解决方案来流式传输音频(独立于我们从HTMLR和nodeJS/binaryJS中获取流数据的位置,例如webRTC或其他).如果是这样,你会怎么做?
从2010年开始,这里只发现了一个关于stackoverflow的问题.从那时起,NodeJS和HTML5已经发展壮大.
人们通常做什么: 当使用多媒体流(即视频或音频)到服务器时,在当前时间点肯定没有任何东西可以击败闪存,直到getUserMedia()完全到达- 这可能需要一段时间直到99浏览器用户的百分比将完全使用它.
将数据流式传输到服务器的一般做法是使用客户端Flash或Flex应用程序,然后连接到RT5协议驱动的介质服务器,如RED5,FMS或Wowza.例如,通过RTMP发送麦克风输入的客户端应用程序可能看起来像(简化版)
import flash.net.NetStream;
private var myMic:Microphone;
private var nc:NetConnection;
private var ns:NetStream
nc = new NetConnection();
ns = new NetStream(nc);
nc.connect(rtmp://localhost/serverApp);
myMic = Microphone.getMicrophone();
ns.attachAudio(myMic);
Run Code Online (Sandbox Code Playgroud)
与服务器应用程序一起,可以轻松地将数据流式传输到服务器.
我想做什么: 在nodeJS上运行一个app服务器(可能实现socketIO和binaryJS),捕获传入的RTMP流.就像是
//require
var rtmp = require('node-rtmp'),
var fs = require('fs');
//rtmp server address
var rtmpServer = 'rtmp://localhost';
//create a binary server listening that receives stream data
var …Run Code Online (Sandbox Code Playgroud) 我目前正在尝试将实时麦克风音频从Android设备传输到Java程序.我开始在两个Android设备之间发送实时音频,以确认我的方法是正确的.在接收设备上几乎没有任何延迟,可以完美地听到音频.接下来,我将相同的音频流发送到一个小型Java程序,我验证了数据也正确地发送到这里.现在我想要做的是编码这些数据,并以某种方式在运行Java程序的服务器上播放它.我宁愿在使用HTML5或JavaScript的网络浏览器中播放它,但我愿意接受其他方法,如VLC.
以下是发送实时麦克风音频的Android应用程序的代码
public class MainActivity extends Activity {
private Button startButton,stopButton;
public byte[] buffer;
public static DatagramSocket socket;
AudioRecord recorder;
private int sampleRate = 44100;
private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
private boolean status = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startButton = (Button) findViewById (R.id.start_button);
stopButton = (Button) findViewById (R.id.stop_button);
startButton.setOnClickListener(startListener);
stopButton.setOnClickListener(stopListener);
minBufSize += 2048;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true; …Run Code Online (Sandbox Code Playgroud) 我一直在尝试使用Node.js中的二进制流,令我惊讶的是,实际上有一个工作演示,即使用节点无线电流获取Shoutcast流并使用分块编码将其推送到HTML5元素.但它只适用于Safari!
这是我的服务器代码:
var radio = require("radio-stream");
var http = require('http');
var url = "http://67.205.85.183:7714";
var stream = radio.createReadStream(url);
var clients = [];
stream.on("connect", function() {
console.error("Radio Stream connected!");
console.error(stream.headers);
});
// When a chunk of data is received on the stream, push it to all connected clients
stream.on("data", function (chunk) {
if (clients.length > 0){
for (client in clients){
clients[client].write(chunk);
};
}
});
// When a 'metadata' event happens, usually a new song is starting.
stream.on("metadata", function(title) {
console.error(title);
}); …Run Code Online (Sandbox Code Playgroud) 我发现Android MediaPlayer准备使用不同的流进行实时流播放所花费的时间差异很大.
硬数据
我在prepareAsync()和onPrepared(MediaPlayer mp)回调之间添加了日志记录,并且每次都测试了几个流.每个流的时间非常一致(+/- 1秒),结果如下:
测试是在带有Android 2.3.4的Nexus S上进行的3G连接(~1100 Kbps).
播放非流式MP3音频文件不是问题.
以下是我如何播放流的片段:
准备MediaPlayer:
...
mediaPlayer.setDataSource(playUrl);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.prepareAsync();
...
Run Code Online (Sandbox Code Playgroud)
然后在onPrepared(MediaPlayer mp):
mediaPlayer.start();
Run Code Online (Sandbox Code Playgroud)
为什么要准备一些流而不是其他流需要这么长时间?上述数据似乎表明它可能基于已缓冲的数据量而不是缓冲的音频内容的持续时间.真的可以吗?
更新:我已经使用Android 1.6,2.2和2.3.4以及1.6,2.1,2.2,2.3.1和2.3.3的仿真器测试了物理设备上的实时流媒体.我只看到2.3.3和2.3.4的长时间延迟.旧版本在5秒内开始播放.
我正在使用一个子类,AVQueuePlayer当我添加新AVPlayerItem的流媒体URL时,应用程序会冻结大约一两秒钟.通过冻结我的意思是它不响应UI上的触摸.此外,如果我已经播放了一首歌曲,然后将另一首歌曲添加到队列中,AVQueuePlayer则会自动开始预加载该歌曲,同时它仍在播放第一首歌曲.这使得应用程序不会响应UI上的触摸两秒钟,就像添加第一首歌但歌曲仍在播放时一样.所以这意味着AVQueuePlayer在主线程中做了一些导致明显"冻结"的事情.
我insertItem:afterItem:用来添加我的AVPlayerItem.我测试并确保这是造成延迟的方法.也许它可能是在将它添加到队列AVPlayerItem时被激活的东西AVQueuePlayer.
必须指出我使用Dropbox API v1 beta通过使用此方法调用来获取流式URL:
[[self restClient] loadStreamableURLForFile:metadata.path];
Run Code Online (Sandbox Code Playgroud)
然后,当我收到流URL时,我将其发送到AVQueuePlayer如下:
[self.player insertItem:[AVPlayerItem playerItemWithURL:url] afterItem:nil];
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:我该如何避免这种情况?我应该在没有帮助的情况下自己预加载音频流AVPlayer吗?如果是这样,我该怎么做?
谢谢.
我们需要将实时音频(从医疗设备)流式传输到网络浏览器,端到端延迟不超过3-5秒(假设网络延迟为200毫秒或更短).今天我们使用浏览器插件(NPAPI)来解码,过滤(高,低,带)和回放音频流(通过Web套接字传送).
我们想要替换插件.
我正在查看各种Web Audio API演示,我们所需的大部分功能(播放,增益控制,过滤)似乎都可以在Web Audio API中使用.但是,我不清楚Web Audio API是否可用于流式传输源,因为大多数Web Audio API都使用短音和/或音频剪辑.
可以使用Web Audio API播放实时流式音频吗?
更新(2015年2月11日):
经过一些研究和本地原型设计后,我不确定是否可以使用Web Audio API进行实时音频流传输.由于Web Audio API的decodeAudioData并非真正设计用于处理随机的音频数据块(在我们的例子中通过WebSockets提供).它似乎需要整个'文件'才能正确处理它.
请参阅stackoverflow:
现在可以使用createMediaElementSource将<audio>元素连接到Web Audio API,但是根据我的经验,该<audio>元素会导致大量的端到端延迟(15-30秒)并且似乎没有任何方法将延迟减少到3-5秒以下.
我认为唯一的解决方案是将WebRTC与Web Aduio API一起使用.我希望避免使用WebRTC,因为它需要对我们的服务器端实现进行重大更改.
更新(2015年2月12日)第一部分:
我还没有完全删除<audio>标签(需要完成我的原型).一旦我排除了它,我怀疑createScriptProcessor(已弃用但仍然支持)将是我们环境的一个不错的选择,因为我可以"流"(通过WebSockets)我们的ADPCM数据到浏览器,然后(在JavaScript中)将其转换为PCM.类似于Scott的库(见下文)使用createScriptProcessor.此方法不要求数据处于适当大小的"块"和关键时序,如decodeAudioData方法.
更新(2015年2月12日)第二部分:
经过更多测试后,我删除了<audio>Web Audio API接口,因为根据源类型,压缩和浏览器,端到端延迟可能是3-30秒.这留下了createScriptProcessor方法(参见下面的Scott的帖子)或WebRTC.在与我们的决策者讨论后,我们决定采用WebRTC方法.我认为它会起作用.但它需要更改我们的服务器端代码.
我要标记第一个答案,就这样'问题'就此结束了.
谢谢收听.随意添加评论.
我想使用OpenSL ES FileDescriptor对象从音频资产中获取字节缓冲区,因此我可以将其重复排队到SimpleBufferQueue,而不是使用SL接口来播放/停止/搜索文件.
我想直接管理样本字节有三个主要原因:
好的,所以理由完成 - 这就是我尝试过的 - 我有一个Sample结构,它实质上包含一个输入和输出轨道,以及一个用于保存样本的字节数组.输入是我的FileDescriptor播放器,输出是SimpleBufferQueue对象.这是我的结构:
typedef struct Sample_ {
// buffer to hold all samples
short *buffer;
int totalSamples;
SLObjectItf fdPlayerObject;
// file descriptor player interfaces
SLPlayItf fdPlayerPlay;
SLSeekItf fdPlayerSeek;
SLMuteSoloItf fdPlayerMuteSolo;
SLVolumeItf fdPlayerVolume;
SLAndroidSimpleBufferQueueItf fdBufferQueue;
SLObjectItf outputPlayerObject;
SLPlayItf outputPlayerPlay;
// output buffer interfaces
SLAndroidSimpleBufferQueueItf outputBufferQueue;
} Sample;
Run Code Online (Sandbox Code Playgroud)
初始化文件播放器fdPlayerObject后,以及用于我的字节缓冲区的malloc-ing内存
sample->buffer = malloc(sizeof(short)*sample->totalSamples);
Run Code Online (Sandbox Code Playgroud)
我正在使用它的BufferQueue接口
// get the buffer queue interface
result = (*(sample->fdPlayerObject))->GetInterface(sample->fdPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &(sample->fdBufferQueue));
Run Code Online (Sandbox Code Playgroud)
然后我实例化一个 …