metadata.java
来自「java语言开发的P2P流媒体系统」· Java 代码 · 共 516 行
JAVA
516 行
/*
* P2P-Radio - Peer to peer streaming system
* Project homepage: http://p2p-radio.sourceforge.net/
* Copyright (C) 2003-2004 Michael Kaufmann <hallo@michael-kaufmann.ch>
*
* ---------------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------
*/
package p2pradio;
import p2pradio.logging.Logger;
import java.io.*;
import java.util.*;
/**
* Contains all metadata of a stream.
*
* @author Michael Kaufmann
*/
public class Metadata implements Cloneable
{
//Send these parameters from the server directly to the client
//Sent once through AcceptPacket upon initial connection
public static final String CONTENT_TYPE = "ContentType"; //$NON-NLS-1$
public static final String STATION_NAME = "StationName"; //$NON-NLS-1$
public static final String STATION_URL = "StationURL"; //$NON-NLS-1$
public static final String STATION_GENRE = "Genre"; //$NON-NLS-1$
public static final String STATION_DESCRIPTION = "Description"; //$NON-NLS-1$
public static final String HTTP_HEADERS = "HttpHeaders"; //$NON-NLS-1$
public static final String BYTERATE = "Byterate"; //$NON-NLS-1$
//The client and server keep these parameters private (not sent).
public static final String STATION_PUBLIC = "Public"; //$NON-NLS-1$
public static final String AVERAGE_BYTERATE = "AverageByterate"; //$NON-NLS-1$
public static final String SERVER = "Server"; //$NON-NLS-1$
public static final String SERVER_PROTOCOL = "ServerProtocol"; //$NON-NLS-1$
//These parameters are sent periodically through the network (p2p and multicast+)
//They are also sent in the AcceptPacket upon initial connection
public static final String SONG_TITLE = "SongTitle"; //$NON-NLS-1$
public static final String SONG_URL = "SongURL"; //$NON-NLS-1$
public static final String CONTENT_TYPE_DEFAULT = "content/unknown"; //$NON-NLS-1$
public static final String SERVER_DEFAULT = Radio.NameSlashVersion; //$NON-NLS-1$
public static final String SERVER_PROTOCOL_DEFAULT = "HTTP"; //$NON-NLS-1$
public static final String STATION_NAME_DEFAULT = ""; //$NON-NLS-1$
public static final String STATION_URL_DEFAULT = ""; //$NON-NLS-1$
public static final String STATION_GENRE_DEFAULT = ""; //$NON-NLS-1$
public static final String STATION_DESCRIPTION_DEFAULT = ""; //$NON-NLS-1$
public static final String STATION_PUBLIC_DEFAULT = "1"; //$NON-NLS-1$
public static final String SONG_TITLE_DEFAULT = ""; //$NON-NLS-1$
public static final String SONG_URL_DEFAULT = ""; //$NON-NLS-1$
public static final String HTTP_HEADERS_DEFAULT = ""; //$NON-NLS-1$
public static final String BYTERATE_DEFAULT = "0"; //$NON-NLS-1$
public static final String AVERAGE_BYTERATE_DEFAULT = "0"; //$NON-NLS-1$
protected Properties metadata;
// "Cache" f黵 die Methode toByteArray()
byte[] byteArray;
/**
* Creates a new metadata object, filled with default values.
*/
public Metadata()
{
init();
}
/**
* Creates a new metadata object that reads its metadata from a stream.
*
* @param inputStream The input stream to read the metadata from
*/
public Metadata(InputStream inputStream)
{
init();
load(inputStream);
// Schauen, ob die Byterate ein Integer-wert ist
try
{
getByterate();
getAverageByterate();
}
catch (NumberFormatException e)
{
throw new IllegalArgumentException(Messages.getString("Metadata.INVALID_BYTERATE")); //$NON-NLS-1$
}
}
public void load(InputStream inputStream)
{
try {
metadata.load(inputStream);
}
catch (IOException e)
{
throw new IllegalArgumentException(Messages.getString("Metadata.COULD_NOT_READ_METADATA")); //$NON-NLS-1$
}
}
protected void init()
{
metadata = new Properties();
metadata.setProperty(CONTENT_TYPE, CONTENT_TYPE_DEFAULT);
metadata.setProperty(SERVER, SERVER_DEFAULT);
metadata.setProperty(SERVER_PROTOCOL, SERVER_PROTOCOL_DEFAULT);
metadata.setProperty(STATION_NAME, STATION_NAME_DEFAULT);
metadata.setProperty(STATION_URL, STATION_URL_DEFAULT);
metadata.setProperty(STATION_GENRE, STATION_GENRE_DEFAULT);
metadata.setProperty(STATION_DESCRIPTION, STATION_DESCRIPTION_DEFAULT);
metadata.setProperty(STATION_PUBLIC, STATION_PUBLIC_DEFAULT);
metadata.setProperty(SONG_TITLE, SONG_TITLE_DEFAULT);
metadata.setProperty(SONG_URL, SONG_URL_DEFAULT);
metadata.setProperty(HTTP_HEADERS, HTTP_HEADERS_DEFAULT);
metadata.setProperty(BYTERATE, BYTERATE_DEFAULT);
metadata.setProperty(AVERAGE_BYTERATE, AVERAGE_BYTERATE_DEFAULT);
}
public synchronized void setContentType(String contentType)
{
byteArray = null;
metadata.setProperty(CONTENT_TYPE, contentType);
}
public synchronized String getContentType()
{
return metadata.getProperty(CONTENT_TYPE);
}
public synchronized void setServer(String server)
{
byteArray = null;
metadata.setProperty(SERVER, server + " & " + Radio.NameSlashVersion); //$NON-NLS-1$
}
public synchronized String getServer()
{
return metadata.getProperty(SERVER);
}
public synchronized void setServerProtocol(String serverProtocol)
{
byteArray = null;
metadata.setProperty(SERVER_PROTOCOL, serverProtocol);
}
public synchronized String getServerProtocol()
{
return metadata.getProperty(SERVER_PROTOCOL);
}
public synchronized void setStationName(String stationName)
{
byteArray = null;
metadata.setProperty(STATION_NAME, stationName);
handleSameStationNameAndDescription();
}
public synchronized String getStationName()
{
return metadata.getProperty(STATION_NAME);
}
public synchronized void setStationURL(String stationURL)
{
byteArray = null;
metadata.setProperty(STATION_URL, stationURL);
handleSameStationAndSongURL();
}
public synchronized String getStationURL()
{
return metadata.getProperty(STATION_URL);
}
public synchronized void setGenre(String stationGenre)
{
byteArray = null;
metadata.setProperty(STATION_GENRE, stationGenre);
}
public synchronized String getGenre()
{
return metadata.getProperty(STATION_GENRE);
}
public synchronized void setDescription(String stationDescription)
{
byteArray = null;
metadata.setProperty(STATION_DESCRIPTION, stationDescription);
handleSameStationNameAndDescription();
}
public synchronized String getDescription()
{
return metadata.getProperty(STATION_DESCRIPTION);
}
public synchronized void setPublic(boolean isPublic)
{
byteArray = null;
if (isPublic)
{
metadata.setProperty(STATION_PUBLIC, "1"); //$NON-NLS-1$
}
else
{
metadata.setProperty(STATION_PUBLIC, "0"); //$NON-NLS-1$
}
}
public boolean isPublic()
{
return metadata.getProperty(STATION_PUBLIC).equals("1"); //$NON-NLS-1$
}
public synchronized void setSongTitle(String songTitle)
{
byteArray = null;
metadata.setProperty(SONG_TITLE, songTitle);
}
public synchronized String getSongTitle()
{
return metadata.getProperty(SONG_TITLE);
}
public synchronized void setSongURL(String songURL)
{
byteArray = null;
metadata.setProperty(SONG_URL, songURL);
handleSameStationAndSongURL();
}
public synchronized String getSongURL()
{
return metadata.getProperty(SONG_URL);
}
public synchronized void setHttpHeaders(String httpHeaders)
{
byteArray = null;
metadata.setProperty(HTTP_HEADERS, httpHeaders);
}
public synchronized String getHttpHeaders()
{
return metadata.getProperty(HTTP_HEADERS);
}
public synchronized void setByterate(int byteRate)
{
if (byteRate < 0)
{
throw new IllegalArgumentException();
}
byteArray = null;
metadata.setProperty(BYTERATE, Integer.toString(byteRate));
}
public synchronized int getByterate() throws NumberFormatException
{
return Integer.parseInt(metadata.getProperty(BYTERATE));
}
public synchronized void setAverageByterate(int averageByteRate)
{
if (averageByteRate < 0)
{
throw new IllegalArgumentException();
}
byteArray = null;
metadata.setProperty(AVERAGE_BYTERATE, Integer.toString(averageByteRate));
}
public synchronized int getAverageByterate() throws NumberFormatException
{
return Integer.parseInt(metadata.getProperty(AVERAGE_BYTERATE));
}
public synchronized boolean isICYStream()
{
return getServerProtocol().toUpperCase().equals("ICY"); //$NON-NLS-1$
}
/**
* Adds a user-defined key/value-pair to the metadata.
*/
/*
private synchronized void setProperty(String key, String value)
{
byteArray = null;
metadata.setProperty(key, value);
}
*/
/**
* Returns the value of the specified metadata key.
*/
/*
private synchronized String getProperty(String key)
{
return metadata.getProperty(key);
}
*/
/**
* Returns an enumeration of all metadata keys.
*/
/*public synchronized Enumeration propertyNames()
{
return metadata.propertyNames();
}*/
public synchronized String toHttpHeaders(String prefix, boolean includeMetaInt)
{
String headers = null; //$NON-NLS-1$
boolean isICY = prefix.toLowerCase().equals("icy-"); //$NON-NLS-1$
if (isICY)
{
headers = getHeader(headers, prefix, "notice1", "<BR>This stream requires a media player like Winamp, XMMS or Zinf<BR>"); //$NON-NLS-1$ //$NON-NLS-2$
headers = getHeader(headers, prefix, "notice2", getServer() + "<BR>"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
headers = getHeader(headers, prefix, "name", getStationName()); //$NON-NLS-1$
headers = getHeader(headers, prefix, "url", getStationURL()); //$NON-NLS-1$
headers = getHeader(headers, prefix, "genre", getGenre()); //$NON-NLS-1$
headers = getHeader(headers, prefix, "description", getDescription()); //$NON-NLS-1$
String publicString;
String privateString;
if (isPublic())
{
publicString = "1"; //$NON-NLS-1$
privateString = "0"; //$NON-NLS-1$
}
else
{
publicString = "0"; //$NON-NLS-1$
privateString ="1"; //$NON-NLS-1$
}
if (isICY)
{
headers = getHeader(headers, prefix, "pub", publicString); //$NON-NLS-1$
}
else
{
headers = getHeader(headers, prefix, "public", publicString); //$NON-NLS-1$
headers = getHeader(headers, prefix, "private", privateString); //$NON-NLS-1$
}
if (includeMetaInt)
{
headers = getHeader(headers, prefix, "metaint", Integer.toString(p2pradio.players.HttpPlayerServer.ICY_METADATA_INTERVAL)); //$NON-NLS-1$
}
if (getByterate() != 0)
{
if (isICY)
{
headers = getHeader(headers, prefix, "br", Integer.toString(getByterate() / 125)); //$NON-NLS-1$
}
else
{
headers = getHeader(headers, prefix, "bitrate", Integer.toString(getByterate() / 125)); //$NON-NLS-1$
}
}
return headers;
}
private String getHeader(String headers, String prefix, String key, String value)
{
if (value.length() != 0)
{
String newHeader = prefix + key + ": " + value; //$NON-NLS-1$
if (headers == null)
{
return newHeader;
}
else
{
return headers + "\r\n" + newHeader; //$NON-NLS-1$
}
}
else
{
return headers;
}
}
/**
* Writes all key/value-pairs of this metadata object into a byte array.
* It can be read later with {@link #Metadata(InputStream)} using a {@link java.io.ByteArrayInputStream}.
*/
public synchronized byte[] toByteArray()
{
if (byteArray == null)
{
// Metadaten in einen ByteArrayOutputStream speichern
ByteArrayOutputStream metadataStream = new ByteArrayOutputStream();
Properties urltitle = new Properties();
urltitle.setProperty(SONG_TITLE, getSongTitle());
urltitle.setProperty(SONG_URL, getSongURL());
try
{
urltitle.store(metadataStream, "Metadata"); //$NON-NLS-1$
}
catch (IOException e)
{
// Sollte eigentlich nicht vorkommen
Logger.severe("Metadata", "INTERNAL_ERROR", e); //$NON-NLS-1$ //$NON-NLS-2$
}
// In ein Byte-Array umwandeln
byteArray = metadataStream.toByteArray();
}
return byteArray;
}
public String toString()
{
return metadata.toString();
}
/**
* Checks if two metadata objects contain identical metadata.
*/
public boolean equals(Object other)
{
return metadata.equals(((Metadata)other).metadata);
}
/**
* Creates a clone with identical metadata.
*/
public Object clone()
{
Object object = null;
try
{
object = super.clone();
}
catch (CloneNotSupportedException e)
{
}
Metadata metadataObject = (Metadata)object;
metadataObject.metadata = (Properties)metadata.clone();
return metadataObject;
}
public void setProperties(Properties metadata)
{
this.metadata = metadata;
}
public Properties getProperties()
{
return metadata;
}
private synchronized void handleSameStationAndSongURL()
{
// Es gibt einige Shoutcast-Sender, die als Song-URL
// einfach die Sender-URL angeben. In diesem Fall
// die Song-URL einfach ignorieren
//
// Achtung: Die Song-URL nur setzen, falls sie nicht schon die Default-URL ist,
// zum Beispiel eine leere Zeichenfolge (Stack-躡erlauf!)
if (getStationURL().equals(getSongURL()) && !getSongURL().equals(SONG_URL_DEFAULT))
{
setSongURL(SONG_URL_DEFAULT);
}
}
private synchronized void handleSameStationNameAndDescription()
{
// Oddsock DSP macht keinen Unterschied zwischen dem Sendernamen
// und der Beschreibung. Falls beide gleich sind die Beschreibung
// entfernen
if (getStationName().equals(getDescription()) && !getDescription().equals(STATION_DESCRIPTION_DEFAULT))
{
setDescription(STATION_DESCRIPTION_DEFAULT);
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?