httpsource.java
来自「java语言开发的P2P流媒体系统」· Java 代码 · 共 988 行 · 第 1/2 页
JAVA
988 行
{
String newHeader = key + ": " + value; //$NON-NLS-1$
if (additionalHTTPHeaders == null)
{
additionalHTTPHeaders = newHeader;
}
else
{
additionalHTTPHeaders = additionalHTTPHeaders + "\r\n" + newHeader; //$NON-NLS-1$
}
}
}
}
// Zus鋞zliche HTTP-Header setzen, falls es welche gibt
if (additionalHTTPHeaders != null)
{
metadata.setHttpHeaders(additionalHTTPHeaders);
}
if (isICYStream && !metaIntFound)
{
// Wichtige Metadaten nicht gefunden
return false;
}
if (PlaylistParser.isPlaylistMIMEType(metadata.getContentType())) //$NON-NLS-1$
{
// Es ist eine Playlist!
// Diese muss ausgelesen werden
return false;
}
// Auch Icecast-Str鰉e als Shoutcast-Str鰉e behandeln
isICYStream = metaIntFound;
if (isICYStream)
{
metadata.setServerProtocol("ICY"); //$NON-NLS-1$
}
else
{
metadata.setServerProtocol("HTTP"); //$NON-NLS-1$
}
if (!stationNameFound)
{
// URL als Namen setzen
metadata.setStationName(url.toString());
}
if (contentTypeFound)
{
// Un黚liche Content-Types ersetzen
String contentType = metadata.getContentType().toLowerCase();
if (contentType.equals("video/x-nsv")) //$NON-NLS-1$
{
metadata.setContentType("video/nsv"); //$NON-NLS-1$
}
else if (contentType.equals("application/x-ogg") || contentType.equals("audio/x-vorbis")) //$NON-NLS-1$ //$NON-NLS-2$
{
metadata.setContentType("application/ogg"); //$NON-NLS-1$
}
}
else
{
// Standard: MP3-Strom
metadata.setContentType("audio/mpeg"); //$NON-NLS-1$
}
// Die Metadaten sind komplett
// System.out.println(metadata);
// Socket usw. setzen
this.socket = socket;
this.inputStream = inputStream;
this.outputStream = outputStream;
couldConnect = true;
Logger.info("HttpSource", "HttpSource.STREAM_FOUND", url); //$NON-NLS-1$ //$NON-NLS-2$
if (metadata.getContentType().equals("application/ogg"))
PacketFactory.STREAM_PACKET_MAX_SIZE = PacketFactory.STREAM_PACKET_MAX_SIZE_TCP_OGG;
return true;
}
else
{
// Es hat nicht geklappt...
return false;
}
}
catch (Exception e)
{
Logger.info("HttpSource", "HttpSource.COULD_NOT_CONNECT_TO_URL", url); //$NON-NLS-1$ //$NON-NLS-2$
return false;
}
finally
{
if (!couldConnect)
{
// Alle Ressourcen wieder freigeben
if (writer != null)
{
try
{
writer.close();
}
catch (IOException e)
{
}
}
if (inputStream != null)
{
try
{
inputStream.close();
}
catch (IOException e)
{
}
}
if (outputStream != null)
{
try
{
outputStream.close();
}
catch (IOException e)
{
}
}
if (socket != null)
{
try
{
socket.close();
}
catch (IOException e)
{
}
}
}
}
}
private void serve()
{
buffer.setMetadata(metadata);
try
{
if (metadata.getContentType().toLowerCase().equals("application/ogg")) //$NON-NLS-1$
{
serveOgg();
}
else
{
serveGeneric();
}
}
catch (SocketTimeoutException e)
{
Logger.warning("HttpSource", "HttpSource.SOCKET_TIMEOUT"); //$NON-NLS-1$ //$NON-NLS-2$
}
catch (EOFException e)
{
Logger.warning("HttpSource", "HttpSource.STREAM_ENDED"); //$NON-NLS-1$ //$NON-NLS-2$)
}
catch (IOException e)
{
Logger.warning("HttpSource", "IO_ERROR", e); //$NON-NLS-1$ //$NON-NLS-2$
}
finally
{
isConnected = false;
if (inputStream != null)
{
try
{
inputStream.close();
}
catch (IOException e)
{
}
}
if (outputStream != null)
{
try
{
outputStream.close();
}
catch (IOException e)
{
}
}
if (socket != null)
{
try
{
socket.close();
}
catch (IOException e)
{
}
}
}
}
private void serveGeneric() throws IOException
{
// Puffer f黵 die gelesenen Bytes
byte[] readBytes = new byte[READ_BUFFER_SIZE];
// Puffer f黵 die Shoutcast-Metadaten
byte[] shoutcastMetadata = new byte[4080];
//long nextDataSendTime = System.currentTimeMillis() + DATA_COLLECTION_INTERVAL;
/*
long time = System.currentTimeMillis();
int total = 0;
*/
// Soviele Datenbytes m黶sen noch gelesen werden,
// bis Shoutcast-Metadaten kommen
int dataBytesLeft = metadataInterval;
// (Das Timeout auch w鋒rend der
// Datenlieferungsphase beibehalten)
while(true)
{
if (isICYStream && (dataBytesLeft == 0))
{
// Jetzt m黶sen die Metadaten gelesen werden
int metadataLengthByte = inputStream.read();
if (metadataLengthByte == -1)
{
throw new EOFException();
}
int metadataLength = metadataLengthByte * 16;
if (metadataLength != 0)
{
// Die Metadaten komplett lesen
inputStream.readFully(shoutcastMetadata, 0, metadataLength);
// Die Metadaten konvertieren
ShoutcastMetadata.shoutcastToMetadata(shoutcastMetadata, metadataLength, metadata);
// Die neuen Metadaten sofort verschicken
buffer.setMetadataSong(metadata);
}
// Jetzt kommen wieder Datenbytes
dataBytesLeft = metadataInterval;
}
// Datenbytes lesen
int readLength;
if (isICYStream)
{
readLength = Math.min(readBytes.length, dataBytesLeft);
}
else
{
readLength = readBytes.length;
}
int count = inputStream.read(readBytes, 0, readLength);
// total += count;
if (count == -1)
{
// Der Strom ist zu Ende
throw new EOFException();
}
if (isICYStream)
{
// Restliche Datenbytes berechnen
dataBytesLeft -= count;
}
// Daten weiterschicken
buffer.sendData(readBytes, count);
// System.out.println(System.currentTimeMillis());
// System.out.println(count);
}
}
private void serveOgg() throws IOException
{
try
{
OggPage oggPage;
while(true)
{
oggPage = new OggPage(inputStream);
if (oggPage.isBeginOfLogicalBitstream())
{
byte[] oggHeader = OggStream.readVorbisHeader(oggPage, inputStream, metadata);
buffer.setHeader(oggHeader);
buffer.setMetadataSong(metadata);
}
else
{
buffer.sendData(oggPage.getPageData());
}
}
}
catch (OggException e)
{
Logger.warning("HttpSource", "HttpSource.OGG_ERROR", e); //$NON-NLS-1$ //$NON-NLS-2$
}
}
/**
* Tries to connect to one of the Shoutcast/Icecast servers.
*
* @return <code>true</code>, if a connection to a Shoutcast/Icecast server
* could be established, or <code>false</code>otherwise.
*/
public boolean connect()
{
isConnected = false;
// Versuchen, eine Verbindung zu einem Shoutcast-Server herzustellen
if (firstTry != null)
{
isConnected = connect(firstTry, 0);
if (isConnected)
{
// firstTry in ein secondTry 黚erf黨ren
// (Jetzt weiss man, dass es ein Strom ist)
URL[] urls = new URL[1];
urls[0] = firstTry;
secondTry = urls;
}
if (!isConnected && !isICYStream)
{
secondTry = PlaylistParser.parse(firstTry);
}
// Das n鋍hste mal mit secondTry versuchen
firstTry = null;
}
if (!isConnected && (secondTry != null))
{
for (int i=0; i < secondTry.length; i++)
{
isConnected = connect(secondTry[i], 0);
if (isConnected)
{
break;
}
}
}
return isConnected;
}
public void run()
{
Logger.finer("HttpSource", "HttpSource.THREAD_RUNNING"); //$NON-NLS-1$ //$NON-NLS-2$
try
{
boolean wasConnected = false;
long lastServeTime = 0;
do
{
if (!isConnected)
{
connect();
}
if (isConnected)
{
wasConnected = true;
}
if (isConnected)
{
lastServeTime = System.currentTimeMillis();
serve();
if (System.currentTimeMillis() - lastServeTime < MINIMAL_SERVE_TIME)
{
// Der Server hat nicht lang genug durchgehalten
// Jetzt ein bisschen warten
Logger.info("HttpSource", "HttpSource.RECONNECT_IN_ONE_MINUTE"); //$NON-NLS-1$ //$NON-NLS-2$
// Eine Minute warten und nochmals probieren
Thread.sleep(RECONNECT_WAIT_TIME);
}
}
else
{
if (!wasConnected)
{
// Thread beenden
Logger.info("HttpSource", "HttpSource.COULD_NOT_CONNECT_TO_SERVER"); //$NON-NLS-1$ //$NON-NLS-2$
return;
}
Logger.info("HttpSource", "HttpSource.COULD_NOT_CONNECT_TO_SERVER"); //$NON-NLS-1$ //$NON-NLS-2$
Logger.info("HttpSource", "HttpSource.RECONNECT_IN_ONE_MINUTE"); //$NON-NLS-1$ //$NON-NLS-2$
// Eine Minute warten und nochmals probieren
Thread.sleep(RECONNECT_WAIT_TIME);
}
} while (true);
}
catch (Exception e)
{
Logger.severe("HttpSource", "INTERNAL_ERROR", e); //$NON-NLS-1$ //$NON-NLS-2$
}
}
// Beispiele f黵 die erste Zeile einer Antwort:
// "HTTP/1.0 302 Found"
// "ICY 200 OK"
private String getProtocol(String line)
{
int spacePos = line.indexOf(" "); //$NON-NLS-1$
if (spacePos == -1)
{
return ""; //$NON-NLS-1$
}
int slashPos = line.indexOf("/"); //$NON-NLS-1$
if (slashPos != -1)
{
return line.substring(0, slashPos);
}
else
{
return line.substring(0, spacePos);
}
}
private int getStatusCode(String line)
{
int spacePos = line.indexOf(" "); //$NON-NLS-1$
if (spacePos == -1)
{
return -1;
}
int secondSpacePos = line.indexOf(" ", spacePos+1); //$NON-NLS-1$
if (secondSpacePos == -1)
{
secondSpacePos = line.length();
}
try
{
String number = line.substring(spacePos+1, secondSpacePos);
number = number.trim();
return Integer.parseInt(number);
}
catch (NumberFormatException e)
{
return -1;
}
}
public void setBroadcastBuffer(BroadcastBuffer buffer)
{
this.buffer = buffer;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?