我们使用的Icecast流媒体服务器jPlayer我们的网站上,也用在我们的移动应用程序。我试图给<intro>
添加到配置的Icecast,但是当我做,它呈现在移动设备上的问题。只要手机有中断造成的暂时断开,就像是在一个呼叫,流重复你开始听,当你第一次连接到流时,再介绍起课程之后。举例来说,如果我开始流倾听一个节目或歌曲,有电话打进来和目的,介绍扮演的重新连接和流从我最初开始听起。
我曾与队列的Icecast和突发设置上下,没有发挥可言,并尝试不同的格式,相同的结果。我也有一对夫妇其他流媒体相关帖子的对话,并已告知看来问题出在客户端缓存和球员,这是我没有成立。我看了看我们的流player.js,它是jPlayer 2.9.2与在行3507年底下面上涨:
;(function() {
var DOMParser, find, parse;
DOMParser = (typeof window !== "undefined" && window !== null ? window.DOMParser : void 0) || (typeof require === "function" ? require('xmldom').DOMParser : void 0) || function() {};
find = function(node, list) {
var attributes, childNode, childNodeName, childNodes, i, match, x, _i, _j, _ref, _ref1;
if (node.hasChildNodes()) {
childNodes = node.childNodes;
for (i = _i = 0, _ref = childNodes.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
childNode = childNodes[i];
childNodeName = childNode.nodeName;
if (/REF/i.test(childNodeName)) {
attributes = childNode.attributes;
for (x = _j = 0, _ref1 = attributes.length; 0 <= _ref1 ? _j < _ref1 : _j > _ref1; x = 0 <= _ref1 ? ++_j : --_j) {
match = attributes[x].nodeName.match(/HREF/i);
if (match) {
list.push({
file: childNode.getAttribute(match[0]).trim()
});
break;
}
}
} else if (childNodeName !== '#text') {
find(childNode, list);
}
}
}
return null;
};
parse = function(playlist) {
var doc, ret;
ret = [];
doc = (new DOMParser()).parseFromString(playlist, 'text/xml').documentElement;
if (!doc) {
return ret;
}
find(doc, ret);
return ret;
};
(typeof module !== "undefined" && module !== null ? module.exports : window).ASX = {
name: 'asx',
parse: parse
};
}).call(this);
(function() {
var COMMENT_RE, EXTENDED, comments, empty, extended, parse, simple;
EXTENDED = '#EXTM3U';
COMMENT_RE = /:(?:(-?\d+),(.+)\s*-\s*(.+)|(.+))\n(.+)/;
extended = function(line) {
var match;
match = line.match(COMMENT_RE);
if (match && match.length === 6) {
return {
length: match[1] || 0,
artist: match[2] || '',
title: match[4] || match[3],
file: match[5].trim()
};
}
};
simple = function(string) {
return {
file: string.trim()
};
};
empty = function(line) {
return !!line.trim().length;
};
comments = function(line) {
return line[0] !== '#';
};
parse = function(playlist) {
var firstNewline;
playlist = playlist.replace(/\r/g, '');
firstNewline = playlist.search('\n');
if (playlist.substr(0, firstNewline) === EXTENDED) {
return playlist.substr(firstNewline).split('\n#').filter(empty).map(extended);
} else {
return playlist.split('\n').filter(empty).filter(comments).map(simple);
}
};
(typeof module !== "undefined" && module !== null ? module.exports : window).M3U = {
name: 'm3u',
parse: parse
};
}).call(this);
(function() {
var LISTING_RE, parse;
LISTING_RE = /(file|title|length)(\d+)=(.+)\r?/i;
parse = function(playlist) {
var index, key, line, match, tracks, value, _, _i, _len, _ref;
tracks = [];
_ref = playlist.trim().split('\n');
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
line = _ref[_i];
match = line.match(LISTING_RE);
if (match && match.length === 4) {
_ = match[0], key = match[1], index = match[2], value = match[3];
if (!tracks[index]) {
tracks[index] = {};
}
tracks[index][key.toLowerCase()] = value;
}
}
return tracks.filter(function(track) {
return track != null;
});
};
(typeof module !== "undefined" && module !== null ? module.exports : window).PLS = {
name: 'pls',
parse: parse
};
}).call(this);
;(function() {
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
window.PlayerUI = (function() {
function PlayerUI(container) {
var _this = this;
this.container = container;
this.onStateButtonClicked = __bind(this.onStateButtonClicked, this);
this.duration = null;
this.state = 'loading';
this.player = $('<div></div>');
this.container.append(this.player);
this.player.jPlayer({
ready: function() {
return _this.state = 'paused';
}
});
this.volume = this.container.find('.volume-slider input').rangeslider({
polyfill: false,
onSlide: function(position, value) {
return _this.player.jPlayer('volume', value / 100.0);
},
onSlideEnd: function(position, value) {
return _this.player.jPlayer('volume', value / 100.0);
}
});
this.hookEvents();
}
PlayerUI.prototype.hookEvents = function() {
var _this = this;
this.container.find('.state-button a').click(this.onStateButtonClicked);
this.player.on($.jPlayer.event.play, function() {
return _this.setState('playing');
});
this.player.on($.jPlayer.event.pause, function() {
return _this.setState('paused');
});
this.player.on($.jPlayer.event.durationchange, function(e) {
return _this.container.trigger('player.setProgressMax', {
maxValue: e.jPlayer.status.duration
});
});
this.player.on($.jPlayer.event.timeupdate, function(e) {
return _this.container.trigger('player.updateProgress', {
value: e.jPlayer.status.currentTime
});
});
return this.player.on($.jPlayer.event.ended, function(e) {
return _this.container.trigger('player.trackEnded');
});
};
PlayerUI.prototype.setState = function(state) {
this.state = state;
return this.container.find('.state-button a').removeClass().addClass("state-" + state);
};
PlayerUI.prototype.onStateButtonClicked = function(event) {
event.preventDefault();
switch (this.state) {
case 'playing':
return this.pause();
case 'paused':
return this.play();
default:
return this.noop();
}
};
PlayerUI.prototype.setMedia = function(media) {
this.pause();
return this.player.jPlayer('setMedia', media);
};
PlayerUI.prototype.setProgress = function(pct) {
return this.player.jPlayer('playHead', pct);
};
PlayerUI.prototype.play = function() {
this.setState('playing');
return this.player.jPlayer('play');
};
PlayerUI.prototype.pause = function() {
this.setState('paused');
return this.player.jPlayer('pause');
};
PlayerUI.prototype.noop = function() {
return null;
};
return PlayerUI;
})();
}).call(this);
;(function() {
window.PlaylistUI = (function() {
function PlaylistUI(container) {
var _this = this;
this.container = container;
this.container.hide();
$(window).on('playlistloader.finished', function(evt, data) {
return _this.setPlaylist(PlaylistLoader.coalescePlaylists(data.playlists));
});
}
PlaylistUI.prototype.loadM3UList = function(m3uList) {
return new PlaylistLoader(m3uList);
};
PlaylistUI.prototype.setPlaylist = function(playlistData) {
if (typeof playlistData.data !== 'undefined') {
this.name = playlistData.name;
playlistData = playlistData.data;
}
this.playlist = playlistData;
this.container.hide();
this.unhookEvents();
this.renderPlaylist();
this.container.show();
this.hookEvents();
return this.container.trigger('playlistui.ready', {
ui: this,
autoplay: false //this.getAutoplay()
});
};
PlaylistUI.prototype.unhookEvents = function() {
return this.container.find('.playlist-item').off('click.playlistUI', 'a');
};
PlaylistUI.prototype.hookEvents = function() {
var _this = this;
return this.container.find('.playlist-item').on('click.playlistUI', 'a', function(evt) {
var idx, item;
evt.preventDefault();
idx = $(evt.target).parent('.playlist-item').data('idx');
item = _this.getItemByIdx(idx);
return _this.select(item);
});
};
PlaylistUI.prototype.renderPlaylist = function() {
var idx, item, playlist, _i, _len, _ref, _results;
playlist = this.container.find('.playlist');
playlist.empty();
_ref = this.playlist;
_results = [];
for (idx = _i = 0, _len = _ref.length; _i < _len; idx = ++_i) {
item = _ref[idx];
_results.push(playlist.append(this.rowTemplate(item, idx)));
}
return _results;
};
PlaylistUI.prototype.rowTemplate = function(item, idx) {
return $("<li class=\"playlist-item\" data-idx=\"" + idx + "\"><a href=\"" + item.file + "\">" + item.title + "</a></li>");
};
PlaylistUI.prototype.getAutoplay = function() {
var item, _i, _len, _ref;
_ref = this.playlist;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
item = _ref[_i];
if (item.autoplay) {
return item;
}
}
return null;
};
PlaylistUI.prototype.getItemByIdx = function(idx) {
return this.playlist[idx];
};
PlaylistUI.prototype.getRowForItem = function(item) {
var compare, found, idx, _i, _len, _ref;
_ref = this.playlist;
for (idx = _i = 0, _len = _ref.length; _i < _len; idx = ++_i) {
compare = _ref[idx];
if (compare === item) {
found = this.container.find(".playlist-item[data-idx=" + idx + "]");
return found;
}
}
return null;
};
PlaylistUI.prototype.getIndexForItem = function(item) {
var compare, idx, _i, _len, _ref;
_ref = this.playlist;
for (idx = _i = 0, _len = _ref.length; _i < _len; idx = ++_i) {
compare = _ref[idx];
if (item === compare) {
return idx;
}
}
return null;
};
PlaylistUI.prototype.findNext = function() {
var currentIndex, nextIndex;
currentIndex = this.getIndexForItem(this.current);
if (currentIndex === null) {
return null;
}
nextIndex = currentIndex + 1;
if (nextIndex >= this.playlist.length) {
return null;
}
return this.playlist[nextIndex];
};
PlaylistUI.prototype.select = function(item) {
if (item) {
this.current = item;
this.getRowForItem(item).addClass('selected').siblings().removeClass('selected');
return this.container.trigger('playlistui.select', {
ui: this,
item: item
});
}
};
PlaylistUI.prototype.selectFirst = function() {
return this.select(this.playlist[0]);
};
PlaylistUI.prototype.selectNext = function() {
var nextItem;
nextItem = this.findNext();
if (nextItem === null) {
return false;
}
this.select(nextItem);
return true;
};
return PlaylistUI;
})();
}).call(this);
;(function() {
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
window.PlaylistLoader = (function() {
function PlaylistLoader(playlists) {
this.playlists = playlists;
this.loadedItem = __bind(this.loadedItem, this);
this.loadPlaylists();
}
PlaylistLoader.prototype.loadPlaylists = function() {
var idx, item, _i, _len, _ref, _results,
_this = this;
this.loadCount = 0;
this.data = new Array(this.playlists.length);
_ref = this.playlists;
_results = [];
for (idx = _i = 0, _len = _ref.length; _i < _len; idx = ++_i) {
item = _ref[idx];
_results.push((function() {
var tmp;
tmp = idx;
return jQuery.ajax({
url: item
}).done(function(data) {
return _this.loadedItem(tmp, data);
});
})());
}
return _results;
};
PlaylistLoader.prototype.loadedItem = function(idx, data) {
var playlist;
playlist = M3U.parse(data);
this.data[idx] = playlist;
$(window).trigger('playlistloader.loadeditem', {
index: idx,
playlist: playlist
});
this.loadCount++;
if (this.loadCount === this.playlists.length) {
return this.finishedLoading();
}
};
PlaylistLoader.prototype.finishedLoading = function() {
return $(window).trigger('playlistloader.finished', {
playlists: this.data
});
};
PlaylistLoader.coalescePlaylists = function(playlistsLoaded) {
var fileEntry, output, playlist, _i, _j, _len, _len1;
output = [];
for (_i = 0, _len = playlistsLoaded.length; _i < _len; _i++) {
playlist = playlistsLoaded[_i];
for (_j = 0, _len1 = playlist.length; _j < _len1; _j++) {
fileEntry = playlist[_j];
output.push(fileEntry);
}
}
return output;
};
return PlaylistLoader;
})();
}).call(this);
;(function() {
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
window.StreamUI = (function() {
function StreamUI(selector, streamPlaylists) {
this.selector = selector;
this.streamPlaylists = streamPlaylists;
this.playlistSelect = __bind(this.playlistSelect, this);
this.playlistReady = __bind(this.playlistReady, this);
this.container = jQuery(this.selector);
this.playlist = new PlaylistUI(this.container.find('.playlist-ui'));
this.player = new PlayerUI(this.container.find('.player-ui'));
this.hookEvents();
this.playlist.loadM3UList(this.streamPlaylists);
}
StreamUI.prototype.hookEvents = function() {
var playlistUI;
playlistUI = this.container.find('.playlist-ui');
playlistUI.on('playlistui.ready', this.playlistReady);
return playlistUI.on('playlistui.select', this.playlistSelect);
};
StreamUI.prototype.playlistReady = function(evt, eventinfo) {
if (eventinfo.autoplay !== null) {
return eventinfo.ui.select(eventinfo.autoplay);
} else {
return eventinfo.ui.selectFirst();
}
};
StreamUI.prototype.playlistSelect = function(evt, eventinfo) {
this.player.setMedia({
mp3: eventinfo.item.file
});
return this.player.play();
};
return StreamUI;
})();
}).call(this);
虽然我主要与大多数的Perl和PHP,我的编程经验一个Linux开发人员和做jQuery的了解相当不错,跟我的网络的发展,我肯定是一个新手,当谈到jPlayer甚至音频流。我希望有人能发现在兴田代码上面的东西可能有助于增加一个介绍我们的Icecast 2.4.4流时,我们有问题?
我们的流可在下面的网址,我的介绍就在此刻我们HD4流。
这个问题很容易通过启动流,听一点,直到这首歌改变复制,打电话给手机让它中断数据流,然后挂断电话。这将导致第一首歌听的介绍后,再次被打。
我相信,编解码器是一个比赛,我确实有越来越的介绍工作,直到我格式为MP3 128Kbps的比特率44.1KHz的采样和2声道立体声的问题。这里是介绍文件的信息:
user@stream:~$ mediainfo /usr/share/icecast2/web/high_quality.mp3
General
Complete name : /usr/share/icecast2/web/high_quality.mp3
Format : MPEG Audio
File size : 138 KiB
Duration : 8s 777ms
Overall bit rate mode : Constant
Overall bit rate : 128 Kbps
Writing library : LAME3.99r
Audio
Format : MPEG Audio
Format version : Version 1
Format profile : Layer 3
Mode : Joint stereo
Mode extension : MS Stereo
Duration : 8s 803ms
Bit rate mode : Constant
Bit rate : 128 Kbps
Channel(s) : 2 channels
Sampling rate : 44.1 KHz
Compression mode : Lossy
Stream size : 137 KiB (100%)
Writing library : LAME3.99r
Encoding settings : -m j -V 4 -q 3 -lowpass 17 -b 128
听起来像在底层浏览器缓存踢和部队保持在内存中的东西重播。浏览器是在某些情况下“真棒”这样的,然后会走出自己的方式来忽略无缓存指令和其他的东西。
确保浏览器不会尝试播放缓存有心计的一个方法是添加一个“缓存克星”。本质上,查询字符串(/流富=酒吧?),这使得浏览器引擎认为它是动态生成的内容,去其缓存;比照https://www.keycdn.com/support/what-is-cache-busting。
这时你的Icecast服务器似乎并没有回答任何请求。因此,我不能看着你身边的细节。