我只是在几天前才开始使用Icecast,所以如果我在某处塞了东西,请告诉我。
我在冰封方面有一个奇怪的问题。每次在冰播中“结束”曲目时,在播放下一首歌曲之前,将当前播放曲目结尾的一部分(我认为是该曲目的64kbs)重复大约2至3次,但是下一首歌曲不会开始播放在开始时,但经过几秒钟。另外,我注意到播放速度(以及音高)有时也不同于原始速度。
我咨询了this post和this post that was quoted below,它们教了我<burst-on-connect>
和<burst-size>
标签的用途。它还教会了我这一点:
为布拉德加油。该帖子的评论部分提供了针对此问题的解决方案,该解决方案表示可以减少Icecast服务器的<source-timeout>
,以便其更快地关闭连接并停止任何重复。但这是假设我要关闭挂载点,而我没有,因为我使用Icecast的目的实际上是24/7广播播放器。如果我确实关闭了挂载点,则发生的情况是VLC只是关闭了,不再重复尝试连接了。除非这是错误的。我不知道。
我使用VLC收听冰广播流的回放,并使用nodeshout,它是来自libshout的一堆绑定(bind),这些绑定(bind)是为node.js构建的。我使用nodeshout将数据发送到icecast服务器上的一堆安装。将来,我计划创建一个站点来监听冰封流,这意味着它将取代VLC。
icecast.xml
<limits>
<clients>100</clients>
<sources>4</sources>
<queue-size>1008576</queue-size>
<client-timeout>30</client-timeout>
<header-timeout>15</header-timeout>
<source-timeout>30</source-timeout>
<burst-on-connect>1</burst-on-connect>
<burst-size>252144</burst-size>
</limits>
这是我的node.js服务器上的音频发送代码的摘要。nodejs
// these lines of code is a smaller part of a function, and this sets all the information. The variables name, description etc come from the arguments of the function
var nodeshout = require("nodeshout");
let shout = nodeshout.create();
shout.setHost('localhost');
shout.setPort(8000);
shout.setUser('source');
shout.setPassword(process.env.icecastPassword); //password in .env file
shout.setName(name);
shout.setDescription(description);
shout.setMount(mount);
shout.setGenre(genre);
shout.setFormat(1); // 0=ogg, 1=mp3
shout.setAudioInfo('bitrate', '128');
shout.setAudioInfo('samplerate', '44100');
shout.setAudioInfo('channels', '2');
return shout
// now meanwhile somewhere lower in the file, there is this summary of how the audio is sent to the icecast server
var nodeshout = require("nodeshout")
var {FileReadStream, ShoutStream} = require("nodeshout") //here is where the FileReadStream and ShoutStream functions come from
const filecontent = new FileReadStream(pathToSong, 65536); //if I change the 65536 to a higher value, then more bytes are being repeated at the end of the track. If I decrease this, it starts sounding buggy and off.
var streamcontent = filecontent.pipe(new ShoutStream(shoutstream))
streamcontent.on('finish', () => {
next()
console.log("Track has finished on " + stream.name + ": " + chosenTrack)
})
我也注意到奇怪的行为。在上一首歌曲重复播放几次之后,这就是服务器调用位于nodejs脚本中的streamcontent.on('finish')
事件的时间,然后才警告我音轨已完成。我尝试过的
我尝试弄乱
<source-timeout>
标记,在nodejs上发送的字节数(或不确定的位数),突发大小,还尝试完全关闭突发,但是这会导致 super 奇怪的行为。我还认为每首歌曲每次创建一个新的流都是一个坏主意,就像在传递文件数据时在
new ShoutStream(shoutstream)
中看到的那样,但是使用相同的流意味着该程序将返回错误,因为它将在它之后将下一个轨道写入到shoutstream中。曾经说它已经关闭了。如果需要更多信息以了解发生了什么情况,我可以提供。谢谢你的时间。
编辑:我想补充:您认为我应该手动控制发送到icecast的字节数,然后使用相同的流对象,而不是每次都调用一个新对象吗?
最佳答案
我发现了为什么流没有播放某些曲目而不是其他曲目。
我怎么到那里
我无法将其流切换到ogg / vorbis或ogg / opus,因此我不得不对源客户端执行某些操作。我仔细检查了所有内容是否正确,以及我的音频文件的比特率是否正确。当我使用ffprobe audio.mp3
运行ffprobe工具时,有时比特率不符合120kbps,128kbps,192、312等的典型速率,依此类推。仅举一个例子,它总是有些奇怪的值,例如129852。
然后,我下载了Checkmate mp3检查器here并检查了我的音频文件,它们均以可变比特率编码!!! VBR该死!
TLDR
我通过使用ffmpeg将所有轨道重新编码为恒定的128kbps比特率来解决问题。
快速编辑:我很确定Darkark之类的程序可能已经支持将可变比特率传输到Icecast服务器,但是使用Darkice对我来说是不切实际的,因此为什么我坚持使用nodehout。
关于node.js - Icecast:重复轨道结束以及Icecast Server的音高变化时,我的行为很奇怪,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63027707/