Professional Documents
Culture Documents
Project Report
On
POMP
1/2
rd
Year of
Yrs.)
2007
Guided By:
Mr.Vivek Srivastava
Submitted By:
Achint Verma
RECOMMENDATION
The project work entitled POMP submitted by Achint Verma is a
satisfactory account of the bona-fide work under my supervision is
recommended towards the end of his VIth semester of M.Tech (5
1/2
yrs)
2007.
Guided By
Mr. Vivek Srivastava
Certificate
This dissertation entitled POMP submitted by
Achint Verma is approved for the partial
fulfilment account of VIth semester of Master of
1/2
Technology(5 years.
Internal Examiner
External Examiner
HOD
CONTENTS
PRELIMINARIES
Recommendation
Certificate
Acknowledgement
1. Abstract
2. Introduction
3. Present Scenario
4. Methodology
5. Problem Definition
6. Feasibility Study
7. Business Model
8. Requirement analysis
9. Initial Study
i. Time Based Data
ii. Media presentation
iii. JMF Architecture
iv. Presentation
v. Time Model
vi. Data Model
vii. Controls
viii. Event Model
5
6
7
8
9
9
10
13
15
15
15
18
19
22
23
24
25
27
27
28
29
30
31
32
33
34
13. Implementation
i. Main Interface
ii. Playlist Mnager
iii. Tag Editor
14. Testing
15. Installation
16. Limitations
17. Conclusion
18. Source Code
38
38
39
40
41
42
44
44
46
Abstract
Module 1: To provide a media player interface on Bluetooth enabled mobile
device. In this module there will be a media player to play songs on a desktop and its
instance interface on mobile device from where we can control playback remotely.
Module 2: Streaming with above media player. Streaming of any song will be
done by media player when it gets a request from its counterpart player on mobile device
to do so. With this a person can listen to any song from media player library by streaming
done with Bluetooth protocol .
Aim :
1. To learn interaction between a desktop and a Bluetooth enabled mobile
device.
2. To provide a virtual command prompt on mobile device to perform various
tasks remotely.
3. To provide new user experience for music freaks so that they can take
advantage of their giant music library (thats on PC) from anywhere within
range of class B Bluetooth (30 feet).
4. To learn about all the technical restrictions that a developer can face while
learning mobile development using JAVA.
Introduction
Recently, MP3 become popular in this generation. Most of the software
companies develop so many types of player which support MP3 file (e.g.
Winamp, Window Media Player, Real, RealOne, etc). But there is not all of the
software which are suitable for all different users.
Pomp is basically a facility for music lovers to control playback of mp3 player right from
there Bluetooth enabled phone. Without a phone , it can work as a standalone mp3-player
on system. This mp3 player has inbuilt ID3 tag editor.
To achieve this we have chosen java as the implementing language because java is
platform independent so what will get can be run on any platform.following javas Write
once run everywhere title.
Objectives
The main purpose of POMP is to produce an audio (MP3) player that can be
suitable for different level user. The goals of POMP are:
z
z
z
z
General Requirements
The following general requirements were laid out for our project named POMP:
Users can add new songs to the playlist or manage their playlist
120 codec in it. Similarily after coming vlc media player, which is open source, scenario
completely changed. Everything I discussed above is present in VLC media payer.
Methodology
I followed SDLC (System Development Life Cycle) for project development phases.
Systems Development Life Cycle (SDLC) or sometimes just (SLC) is defined by the
U.S. Department of Justice (DoJ) as a software development process, although it is also a
distinct process independent of software or other Information Technology considerations.
It is used by a systems analyst to develop an information system, including requirements,
validation, training, and user ownership through investigation, analysis, design,
implementation, and maintenance.
1. Terms Of Reference the management will decide what capabilities and
objectives they wish the new system to incorporate;
2. Feasibility Study asks whether the managements' concept of their desired new
system is actually an achievable, realistic goal, in-terms of money, time and end
result difference to the original system. Often, it may be decided to simply update
an existing system, rather than to completely replace one;
3. Fact Finding and Recording how is the current system used? Often
questionnaires are used here, but also just monitoring (watching) the staff to see
how they work is better, as people will often be reluctant to be entirely honest
through embarrassment about the parts of the existing system they have trouble
with and find difficult if merely asked;
4. Analysis free from any cost or unrealistic constraints, this stage lets minds run
wild as 'wonder systems' can be thought-up, though all must incorporate
everything asked for by the management in the Terms Of Reference section;
5. Design designers will produce one or more 'models' of what they see a system
eventually looking like, with ideas from the analysis section either used or
discarded. A document will be produced with a description of the system, but
nothing is specific they might say 'touchscreen' or 'GUI operating system', but
not mention any specific brands;
6. System Specification having generically decided on which software packages
to use and hardware to incorporate, you now have to be very specific, choosing
exact models, brands and suppliers for each software application and hardware
device;
7. Implementation and Review set-up and install the new system (including
writing any custom (bespoke) code required), train staff to use it and then monitor
how it operates for initial problems, and then regularly maintain thereafter.
During this stage, any old system that was in-use will usually be discarded once
the new one has proved it is reliable and as usable.
Problem Definition
First of all major problems I was facing at the start of analysis was being very unfamiliar
with the new technologies like JMF and Bluetooth.
In summarized form here are the problems involved with this project.
1. Learning a new API, JMF (Java Media Framework).
2. Learning JSR82, JSR135 packages of java mobile technology.
3. Its difficult to make a system which works on two different architectures, as we
area dealing with a computer plus a mobile device, making all modules work
together successfully is difficult task.
4. To analyze and test whether some of the objectives defined in our required system
can be achieved. As they are not done before or their reference is not available.
Feasibility Study
A feasibility study could be used to test a new working system, which could be used
because:
Within a feasibility study, six areas must be reviewed, including those of Economics,
Technical, Schedule, Organizational, Cultural, and Legal.
responsibility of both sides in case there are two parties involved in performing any
project.
** This project has no economical value as its being made for open
source contribution and for sol purpose of learning.
Business Model
10
The term business model describes a broad range of informal and formal models that are
used by enterprises to represent various aspects of business, such as operational
processes, organizational structures, and financial forecasts. Although the term can be
traced to the 1950s, it achieved mainstream usage only in the 1990s. Many informal
definitions of the term can be found in popular business literature, such as the following:
**The business model of this system can not be defined as its an open source project
and intended for learning only.
Software Context
Nowadays, computers become more and more popular. Incalculable of
people use computer as their working tool or playing partner. The one who
accessing computer is not a must a computer expert. There is a huge number of
novice begin to use computer everyday. However, some software in the market
is too difficult to the novice. Tricky Player is able to provide a suitable interface to
both novice and normal user. So it must have its own competitive power.
Major constraints
Time
Some of the idea can not be confirmed due to the time, for example, we
want to add the lyric display as one of our function but we dont have so much
time to investigate how to load the lyric from the song. Also, we want to develop
the player to support more file type (e.g. midi, wav, mpeg, rm etc.) but we dont
have enough time to improve the software.
11
High competition
Many software with the same functions present in the real world. The
competition becomes high due to the presented software. Also, most of the
software have many advanced functions on playing audio files, that why the
competition become higher and higher.
Knowledge
Since we dont have any knowledge on multimedia, this may be a barrier
for us to handle the player. So we need to read more books about multimedia in
order to build up our knowledge on this aspect. So we dont have enough time to
make the player more powerful.
12
Requirement Analysis
and software engineering, requirements analysis encompasses those tasks that go into
determining the requirements of a new or altered system, taking account of the possibly
conflicting requirements of the various stakeholders, such as users. Requirements
analysis is critical to the success of a project.
Systematic requirements analysis is also known as requirements engineering. It is
sometimes referred to loosely by names such as requirements gathering, requirements
capture, or requirements specification. The term "requirements analysis" can also be
applied specifically to the analysis proper (as opposed to elicitation or documentation of
the requirements, for instance).
Hardware Requirements
1. A Bluetooth enabled mobile phone with CLDC 1.1 and JSR82 configuration.
2. A typical Bluetooth USB dongle.
3. a computer with minimum following requirements.
Minimum
Recommended
Processor
233 MHz
Memory
64 MB RAM
1.5 GB
1.5 GB or higher
Devices
Others
13
Software Requirements
Operating System : Platform Independent but recommended that it should be windows
XP or KDE 3 (when using linux).
Java Runtime environment (JRE) : a software bundle from Sun Microsystems that
allows a computer system to run a Java application. Java applications are in widespread
use and necessary to view many Internet pages.
The software bundle consists of the Java Virtual Machine and programming interface
(API). The API provides a set of standard class libraries. The virtual machine and API
have to be consistent with each other and are therefore bundled together as the JRE. This
can be considered a virtual computer in which the virtual machine is the processor and
the API is the user interface.
Development Tools and Packages
1.
2.
3.
4.
5.
14
Initial Study
Time Based Data
Any data that changes meaningfully with respect to time can be characterized as timebased media. Audio clips, MIDI sequences, movie clips, and animations are common
forms of time-based media. Such media data can be obtained from a variety of sources,
such as local or network les, cameras, microphones, and live broadcasts.This chapter
describes the key characteristics of time-based media and describes the use of timebased media in terms of a fundamental data processing model:
Media Presentation
Most time-based media is audio or video data that can be presented through output
devices such as speakers and monitors. Such devices are the most common destination
for media data output. Media streams can also be sent to other destinationsfor
example, saved to a le or transmitted across the network. An output destination for
media data is sometimes referred to as a data sink.
Presentation Controls
While a media stream is being presented, VCR-style presentation controls are often
provided to enable the user to control playback. For example, a control panel for a movie
player might offer buttons for stopping, starting, fast-forwarding, and rewinding the
movie.
Latency
In many cases, particularly when presenting a media stream that resides on the network,
the presentation of the media stream cannot begin immediately. The time it takes before
presentation can begin is referred to as the start latency. Users might experience this as
a delay between the time that they click the start button and the time when playback
actually starts. Multimedia presentations often combine several types of time-based
media into a synchronized presentation. For example, background music might be
played during an image slide-show, or animated text might be synchronized with an
audio or video clip. When the presentation of multiple media streams is synchronized, it
is essential to take into account the start latency of each streamotherwise the playback
of the different streams might actually begin at different times.
15
Presentation Quality
The quality of the presentation of a media stream depends on several factors, including:
The compression scheme used
The processing capability of the playback system
The bandwidth available (for media streams acquired over the network) Traditionally,
the higher the quality, the larger the file size and the greater the processing power and
bandwidth required. Bandwidth is usually represented as the number of bits that are
transmitted in a certain period of time and the bit rate. To achieve high-quality video
presentations, the number of frames displayed in each period of time (the frame rate)
should be as high as possible. Usually movies at a frame rate of 30 frames-per-second
are considered indistinguishable from regular TV broadcasts or video tapes.
Media Processing
In most instances, the data in a media stream is manipulated before it is presented to
the user. Generally, a series of processing operations occur before presentation:
1. If the stream is multiplexed, the individual tracks are extracted.
2. If the individual tracks are compressed, they are decoded.
3. If necessary, the tracks are converted to a different format.
4. Effect filters are applied to the decoded tracks (if desired).
The tracks are then delivered to the appropriate output device. If the media stream is to
be stored instead of rendered to an output device, the processing stages might differ
slightly. For example, if you wanted to capture audio and video from a video camera,
process the data, and save it to a file:
1. The audio and video tracks would be captured.
2. Effect filters would be applied to the raw tracks (if desired).
3. The individual tracks would be encoded.
4. The compressed tracks would be multiplexed into a single media stream.
5. The multiplexed media stream would then be saved to a file.
Demultiplexers and Multiplexers
A demultiplexer extracts individual tracks of media data from a multiplexed media
stream. A mutliplexer performs the opposite function, it takes individual tracks of media
data and merges them into a single multiplexed media stream.
Codecs
A codec performs media-data compression and decompression. When a track is
encoded, it is converted to a compressed format suitable for storage or transmission;
when it is decoded it is converted to a non-compressed (raw) format suitable for
presentation. Each codec has certain input formats that it can handle and certain output
formats that it can generate. In some situations, a series of codecs might be used to
convert from one format to another.
Effect Filters
An effect Filter modifies the track data in some way, often to create special effects such
as blur or echo. Effect Filters are classfied as either pre-processing effects or postprocessing effects, depending on whether they are applied before or after the codec
processes the track. Typically, effect Filters are applied to uncompressed (raw) data.
16
Renderers
A renderer is an abstraction of a presentation device. For audio, the presentation device
is typically the computers hardware audio card that outputs sound to the speakers. For
video, the presentation device is typically the computer monitor.
Compositing
Certain specialized devices support compositing. Compositing time-based media is the
process of combining multiple tracks of data onto a single presentation medium. For
example, overlaying text on a video presentation is one common form of compositing.
Compositing can be done in either hardware or software. A device that performs
compositing can be abstracted as a renderer that can receive multiple tracks of input
data.
Media Capture
Time-based media can be captured from a live source for processing and playback. For
example, audio can be captured from a microphone or a video capture card can be used
to obtain video from a camera. Capturing can be thought of as the input phase of the
standard media processing model.
A capture device might deliver multiple media streams. For example, a video camera
might deliver both audio and video. These streams might be captured and manipulated
separately or combined into a single, multiplexed stream that contains both an audio
track and a video track.
Capture Devices
To capture time-based media you need specialized hardware-for example, to capture
audio from a live source, you need a microphone and an appropriate audio card.
Similarly, capturing a TV broadcast requires a TV tuner and an appropriate video
capture card. Most systems provide a query mechanism to find out what capture devices
are available. Capture devices can be characterized as either push or pull sources. For
example, a still camera is a pull source-the user controls when to capture
an image. A microphone is a push source-the live source continuously provides a stream
of audio.
The format of a captured media stream depends on the processing performed by the
capture device. Some devices do very little processing and deliver raw, uncompressed
data. Other capture devices might deliver the data in a compressed format.
Capture Controls
Controls are sometimes provided to enable the user to manage the capture process. For
example, a capture control panel might enable the user to specify the data rate and
encoding type for the captured stream and start and stop the capture process.
17
JMF uses this same basic model. A data source encapsulates the media stream much
like a video tape and a player provides processing and control mechanisms similar to a
VCR. Playing and capturing audio and video with JMF requires the appropriate input and
output devices such as microphones, cameras, speakers, and monitors. Data sources
and players are integral parts of JMFs high-level API for managing the capture,
representation, and processing of time-based media. JMF also provides a lower-level
API that supports the seamless integration of custom processing components and
extensions. This layering provides Java developers with an easy-to-use API for
incorporating time-based media into Java programs while maintaining the flexibility and
extensibility required to support advanced media applications and future media
technologies.
High Level JMF Architecture
18
Presentation
In JMF, the presentation process is modeled by the Controller interface. Controller defines
the basic state and control mechanism for an object that controls, presents, or captures
time-based media. It defines the phases that a media controller goes through and
provides a mechanism for controlling the transitions between those phases. A number of
the operations that must be performed before media data can be presented can be time
consuming, so JMF allows programmatic control over when they occur. A Controller posts
a variety of controller-specific MediaEvents to provide notification of changes in its status.
To receive events from a Controller such as a Player, you implement the ControllerListener
interface. The JMF API defines two types of Controllers: Players and Processors. A Player or
Processor is constructed for a particular data source and is normally not re-used to
present other media data.
19
A Player does not provide any control over the processing that it performs or how it
renders the media data. Player supports standardized user control and relaxes some of
the operational restrictions imposed by Clock and Controller.
20
In normal operation, a Player steps through each state until it reaches the Started state:
1. A Player in the Unrealized state has been instantiated, but does not yet know
anything about its media. When a media Player is first created, it is Unrealized.
2. When realize is called, a Player moves from the Unrealized state into the Realizing
state. A Realizing Player is in the process of determining its resource
equirements. During realization, a Player acquires the resources that it only needs
to acquire once. These might include rendering resources other than exclusiveuse resources. (Exclusiveuse resources are limited resources such as particular
hardware devices that can only be used by one Player at a time; such resources
are acquired during Prefetching.) A Realizing Player often downloads assets over
the network.
3. When a Player finishes Realizing, it moves into the Realized state. A Realized
Player knows what resources it needs and information about the type of media it is
to present. Because a Realized Player knows how to render its data, it can
provide visual components and controls. Its connections to other objects in the
system are in place, but it does not own any resources that would prevent
another Player from starting.
4. When prefetch is called, a Player moves from the Realized state into the
Prefetching state. A Prefetching Player is preparing to present its media. During
this phase, the Player preloads its media data, obtains exclusive-use resources,
and does whatever else it needs to do to prepare itself to play. Prefetching
might have to recur if a Player objects media presentation is repositioned, or if a
change in the Player objects rate requires that additional buffers be acquired or
alternate processing take place.
5. When a Player finishes Prefetching, it moves into the Prefetched state. A
Prefetched Player is ready to be started.
6. Calling start puts a Player into the Started state. A Started Player objects time-base
time and media time are mapped and its clock is running, though the Player might
be waiting for a particular time to begin presenting its media data.
A Player posts TransitionEvents as it moves from one state to another. The ControllerListener
interface provides a way for your program to determine what state a Player is in and to
respond appropriately.
21
1.Time Model
JMF keeps time to nanosecond precision. A particular point in time is typically
represented by a Time object, though some classes also support the specification of time
in nanoseconds.
Classes that support the JMF time model implement Clock to keep track of time for a
particular media stream. The Clock interface defines the basic timing and synchronization
operations that are needed to control the presentation of media data.
A Clock uses a TimeBase to keep track of the passage of time while a media stream is
being presented. A TimeBase provides a constantly ticking time source, much like a
crystal oscillator in a watch. The only information that a TimeBase provides is its current
time, which is referred to as the time-base time. The time-base time cannot be stopped
or reset. Time-base time is often based on the system clock.
A Clock objects media time represents the current position within a
media stream the beginning of the stream is media time zero, the end of
the stream is the maximum media time for the stream. The duration of the
media stream is the elapsed time from start to finish the length of time
that it takes to present the media stream. (Media objects implement the
Duration interface if they can report a media streams duration.)
To keep track of the current media time, a Clock uses:
1. The time-base start-time the time that its TimeBase reports when the presentation
begins.
2. The media start-time the position in the media stream where presentation begins.
3. The playback rate how fast the Clock is running in relation to its TimeBase. The rate
is a scale factor that is applied to the TimeBase. For example, a rate of 1.0
represents the normal playback rate for the media stream, while a rate of 2.0
indicates that the presentation will run at twice the normal rate. A negative rate
indicates that the Clock is running in the opposite direction from its TimeBasefor
example, a negative rate might be used to play a media stream backward.
22
When presentation begins, the media time is mapped to the time-base time and the
advancement of the time-base time is used to measure the passage of time.
During presentation, the current media time is calculated using the following formula:
MediaTime = MediaStartTime + Rate(TimeBaseTime - TimeBaseStartTime)
When the presentation stops, the media time stops, but the time-base time continues to
advance. If the presentation is restarted, the media time is remapped to the current timebase time.
2.Data Model
JMF media players usually use DataSources to manage the transfer of media-content. A
DataSource encapsulates both the location of media and the protocol and software used to
deliver the media. Once obtained, the source cannot be reused to deliver other media.
A DataSource is identified by either a JMF MediaLocator or a URL (universal resource
locator). A MediaLocator is similar to a URL and can be constructed from a URL, but can be
constructed even if the corresponding protocol handler is not installed on the system. (In
Java, a URL can only be constructed if the corresponding protocol handler is installed on
the system.) A DataSource manages a set of SourceStream objects. A standard data source
uses a byte array as the unit of transfer. A buffer data source uses a Buffer object as its
unit of transfer. JMF defines several types of Data- Source objects:
23
3.Controls
JMF Control provides a mechanism for setting and querying attributes of an object. A
Control often provides access to a corresponding user interface component that enables
user control over an objects attributes. Many JMF objects expose Controls, including
Controller objects, DataSource objects, DataSink objects, and JMF plug-ins.
Any JMF object that wants to provide access to its corresponding Control objects can
implement the Controls interface. Controls denes methods for retrieving associated Control
objects. DataSource and PlugIn use the Controls interface to provide access to their Control
objects.
Standard Controls
JMF defines the standard Control interfaces shown CachingControl enables download
progress to be monitored and displayed. If a Player or Processor can report its download
progress, it implements this interface so that a progress bar can be displayed to the
user.
GainControl enables audio volume adjustments such as setting the level and muting the
output of a Player or Processor. It also supports a listener mechanism for volume changes.
24
Controller Events
The ControllerEvents posted by a Controller such as a Player or Processor fall into three
categories: change notifications, closed events, and transition events:
1. Change notification events such as RateChangeEvent, DurationUpdateEvent, and
FormatChangeEvent indicate that some attribute of the Controller has changed, often
in response to a method call. For example, a Player posts a RateChangeEvent when
its rate is changed by a call to setRate.
2. TransitionEvents allow your program to respond to changes in a Controller objects
state. A Player posts transition events whenever it moves from one state to
another ControllerClosedEvents are posted by a Controller when it shuts down. When a
Controller posts a ControllerClosedEvent, it is no longer usable.
ControllerErrorEvents
4.Event Model
JMF uses a structured event reporting mechanism to keep JMF-based programs
informed of the current state of the media system and enable JMFbased programs to
respond to media-driven error conditions, such as out of data and resource unavailable
conditions. Whenever a JMF object needs to report on the current conditions, it posts a
MediaEvent. MediaEvent is subclassed to identify many particular types of events. These
objects follow the established Java Beans patterns for events.
For each type of JMF object that can
post MediaEvents, JMF denes a corresponding listener interface. To receive notication
when a MediaEvent is posted, you implement the appropriate listener interface and
register your listener class with the object that posts the event by calling its addListener
method. Controller objects (such as Players and Processors) and certain Control objects such
as GainControl post media events.
25
Events in JMF
26
Function Modeling
1. Context Diagram (DFD Level 0)
Above is the top level diagram of the proposed system. It has four external entities
FileSystem, Speakers , Playlist ,Control panel and mobile device panel(optional), as mp3
player can work without it also.
Main process takes three types of information from these entities
1. MP3 Files from file-system
2. File(s) information from Playlist
3. Control Information from Control Interface
.
Audio Data from main process to Speakers is the output.
27
DFD Level 1
28
DFD Level 1
29
Play, Pause, Stop, Next, Previous, Mute, Change Volume, Seek. Only two entities are
there in this level. Setting and temporary store which holds number of current track,
Saves playlist when user quits program.
Rest all controls are basic for any player.
30
31
State Transition Diagram shows various states of player when user takes different
commands. Here from above diagram programmer can easily interpret the required
objective and easily understand the functionality.
We have three states in player
1. Play
2. Pause
3. Stop
Play state is achieved by taking play action, it can be directed from stop state as well as
paused state.
Pause state is achieved when user takes pause command. Commonly there is
play<>pause state interchange donefrequently.
Stop state activates when user takes stop command or playing song finishes.
32
ID3 Tag
ID3 is a metadata container most often used in conjunction with the MP3 audio file
format. It allows information such as the title, artist, album, track number, or other
information about the file to be stored in the file itself. There are two unrelated versions
of ID3: ID3v1 and ID3v2.
ID3v1 was created by Eric Kemp in 1996 and quickly became the de facto standard for
storing metadata in MP3s. The ID3v1 tag occupies 128 bytes, beginning with the string
TAG. To maintain compatibility with older media players the tag was placed at the end of
the file. Some players played a small burst of static when they read the tag, but most
ignored it, and almost all modern players will correctly skip it.
The placement of the tag, as the data was called, was probably chosen as there were little
chance that it should disturb decoders. In order to make it easy to detect a fixed size of
128 bytes was chosen. The tag has the following layout (as hinted by the scheme to the
right):
Internal layout of an ID3v1 tagged file.
ID3V1
ID3V1.1
33
Data dictionary
Song Information
Name:
Track number
Aliases:
Where/How
Used:
Read-track-number (input)
Description:
Format:
Numeric Data
Name:
Song Title
Aliases:
Song name
Where/How
Used:
Read-song-title (input)
Description:
Display-track-number (output)
Display-song-title (output)
Letter = [ A | B | C | . | Z | a | b | c | . | z | 0 | 1 | . | 9 ]
Format:
Alphanumeric Data
Name:
Artist
Aliases:
Where/How
Used:
Read-artist-name (input)
Description:
Artist = { Letter } n
Display-artist-name (output)
Letter = [ A | B | C | . | Z | a | b | c | . | z | 0 | 1 | . | 9 ]
Format:
Alphanumeric Data
34
Name:
Album
Aliases:
Album name
Where/How
Used:
Read-album-name (input)
Description:
Album = { Letter } n
Display-album-name (output)
Letter = [ A | B | C | . | Z | a | b | c | . | z | 0 | 1 | .| 9 ]
Format:
Alphanumeric Data
Name:
Year
Aliases:
Where/How
Used:
Read-year (input)
Description:
Year = { Letter } 4
Display-year (output)
Letter = [ 0 | 1 | .| 9 ]
Format:
Numeric Data
Name:
Genre
Aliases:
Where/How
Used:
Read-genre (input)
Description:
Genre = [ M | F ]
Format:
Character
Display-genre (output)
35
Name:
Comment
Aliases:
Where/How
Used:
Read-comment (input)
Description:
Comment = { Letter } n
Display-comment (output)
Letter = [ A | B | C | . | Z | a | b | c | . | z | 0 | 1 | .| 9 ]
Format:
Alphanumeric Data
Name:
Copyright
Aliases:
Where/How
Used:
Read-copyright (input)
Description:
Copyright = { Letter } n
Display-copyright (output)
Letter = [ A | B | C | . | Z | a | b | c | . | z | 0 | 1 | .| 9 ]
Format:
Alphanumeric Data
Name:
Size
Aliases:
Where/How
Used:
Read-size-name (input)
Description:
Size = Number
Format:
Numeric Data
Display-size-name (output)
36
Name:
Length
Aliases:
Song length
Where/How
Used:
Read-length (input)
Description:
Length = { 0 | 1 | 2 | . | 9 } 2 + : + { 0 | 1 | 2 | . | 9 } 2
Format:
Display-length (output)
37
Implementation (Interfaces)
Implementation is the realization, application, or execution of a plan, idea, model,
design, specification, standard, algorithm, or policy.
In computer science, an implementation is a realization of a technical specification or
algorithm as a program, software component, or other computer system. Many
implementations may exist for a given specification or standard. For example, web
browsers contain implementations of World Wide Web Consortium-recommended
specifications, and software development tools contain implementations of programming
languages.
38
2.Playlist Manager
39
ID3 tag editor has fields are visible in the above form. Id3 tags are meant for
metadata about the songs. Important point is that is saves entered data in mp3 file
itself so when those files are open with other media players like winamp or windows
media player then id3 tags will be present there.
40
Testing
Software Testing is the process used to help identify the correctness, completeness,
security, and quality of developed computer software. Testing is a process of technical
investigation, performed on behalf of stakeholders, that is intended to reveal qualityrelated information about the product with respect to the context in which it is intended to
operate. This includes, but is not limited to, the process of executing a program or
application with the intent of finding errors. Quality is not an absolute; it is value to some
person. With that in mind, testing can never completely establish the correctness of
arbitrary computer software; testing furnishes a 'criticism' or comparison that compares
the state and behaviour of the product against a specification.
There are many approaches to software testing, but effective testing of complex products
is essentially a process of investigation, not merely a matter of creating and following
routine procedure. One definition of testing is "the process of questioning a product in
order to evaluate it", where the "questions" are operations the tester attempts to execute
with the product, and the product answers with its behavior in reaction to the probing of
the tester.Although most of the intellectual processes of testing are nearly identical to that
of review or inspection, the word testing is connoted to mean the dynamic analysis of the
productputting the product through its paces. Some of the common quality attributes
include capability, reliability, efficiency, portability, maintainability, compatibility, and
usability. A good test is sometimes described as one which reveals an error; however,
more recent thinking suggests that a good test is one which reveals information of interest
to someone who matters within the project community.
For testing our project we followed Black Box technique.
Black box testing takes an external perspective of the test object to derive test cases.
These tests can be functional or non-functional, though usually functional. The test
designer selects valid and invalid input and determines the correct output. There is no
knowledge of the test object's internal structure.
Test Results
** test were performed for various files with different sampling rate, different bit
rate, different file size. And results were satisfying. Quality of sound output was also
acceptable.
*** In testing its found that the project is incomplete with respect to specified
objectives.
41
Installation
Installation (or setup) of a program (including drivers) is the act and the effect of putting
the program in a computer system so that it can be executed.
Most programs are supplied in a condensed form intended for sale and distribution. In
order to be used, they must be 'unpacked' and the relevant information placed correctly on
the computer, taking account of variations between computers, and any customized
settings required by the user. During installation, various tests are made of system
suitability, and the computer is configured to store the relevant files and any necessary
settings required for that program to operate correctly.
One file installation (Setup.exe), an executable file thats synonymous for installation can
be made for java applications as well. All we need to follow these steps.
Our prerequisites are:
1.
2.
3.
4.
42
Main-Class: myPrograms.MyClass
43
Its does not support other file formats than MP3.A file filter is used to accept only
files of mp3 extension.
It doesnt support video files.
While accessing playlist its not possible to command the main interface.
There is no facility to add or remove columns, i.e. custom column selection for
metadata that are visible in playlist table.
No support for custom Skins like winamp or windows media player
No support for Lyrics,
>> there are plug-ins available for other popular software which show lyrics
accordingly with playing speed of song.
Plug-in support is not there
>> Additional plug-in for controlling output, listening internet radio, network file
listening is not supported
No graphic equalizer, for filtering sound
No Visualizer
Drag and drop facility is not there
Context menu for explorer is absent. With this facility, user can enqueue
Lack of intelligence for automatic rating, and grouping of songs, for example,
most recently played, top 25.
Conclusions
Working on this project was quite difficult as even till date project is incomplete. I really
enjoyed this work because of the following reasons
44
Advantages
1. MP3 player of this system is fast, reliable robust and platform independent in
nature as it developed with java language.
2. ID3 tag editor is unique in nature as very few popular media players facilitate us
for same.
3. Its simple user interface is user friendly and even a 5 year kid can operate it .We
have just concentrated on basic functionality of a player that everybody uses.
4. Its expandable, i.e. features of this player can be expanded as project is open
source.
Disadvantages
1. As project is incomplete and due to poor design, its expansion and maintenance is
difficult.
2. Too small scaled for implementation at enterprise level.
45
Source Code
As this project is open source, we are providing full source code.
It has four java source files
1. JavaPlayer.java
2. PlayListManager.java
3. Settings.java
4. TagEditor.java
Following are the optional packages that needs to be downloaded in order to run these
files.
JMF(Java Media Framework). Download from link below
http://java.sun.com/products/java-media/jmf/2.1.1/download.html
MP3 Plug-in for JMF .Download from link below
http://java.sun.com/products/java-media/jmf/mp3/download.html
Hellikar.ID3 package
http://sourceforge.net/projects/jd3lib/
after downloading these packages, copy .jar files from these downloads in your lib/ext
directory of java directory. Then compile those four files and run main file, that is
javaplayer.java
java.lang.Object
o java.awt.Component (implements java.awt.image.ImageObserver,
java.awt.MenuContainer, java.io.Serializable)
o java.awt.Container
o java.awt.Window (implements
javax.accessibility.Accessible)
46
java.awt.Dialog
o javax.swing.JDialog (implements
javax.accessibility.Accessible,
javax.swing.RootPaneContainer,
javax.swing.WindowConstants)
o PlaylistManager (implements
java.awt.event.ActionListener,
java.awt.dnd.DropTargetListener,
java.awt.event.MouseListener)
TagEditor (implements
java.awt.event.ActionListener)
o javax.swing.JWindow (implements
javax.accessibility.Accessible,
javax.swing.RootPaneContainer)
o JavaPlayer (implements
java.awt.event.ActionListener,
javax.swing.event.ChangeListener,
javax.media.ControllerListener,
java.awt.event.MouseMotionListener,
java.lang.Runnable)
o
Settings
47
1. JavaPlayer.java
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
java.awt.Dimension;
java.awt.Rectangle;
java.awt.FlowLayout;
java.awt.Font;
java.awt.Point;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
java.awt.event.MouseEvent;
java.awt.event.MouseMotionListener;
javax.swing.event.*;
java.io.BufferedReader;
java.io.File;
java.io.FileReader;
java.io.IOException;
java.net.MalformedURLException;
javax.media.*;
javax.media.ControllerEvent;
javax.media.ControllerListener;
javax.media.EndOfMediaEvent;
javax.media.Manager;
javax.media.MediaLocator;
javax.media.NoPlayerException;
javax.media.Player;
javax.media.PrefetchCompleteEvent;
javax.media.RealizeCompleteEvent;
javax.media.Time;
javax.media.control.*;
javax.media.Controller.*;
javax.swing.BorderFactory;
javax.swing.Box;
javax.swing.Icon;
javax.swing.ImageIcon;
javax.swing.JButton;
javax.swing.JSlider;
javax.swing.JFileChooser;
javax.swing.JOptionPane;
javax.swing.JPanel;
javax.swing.JProgressBar;
javax.swing.JWindow;
javax.swing.filechooser.FileFilter;
helliker.id3.ID3v2FormatException;
helliker.id3.PlaylistException;
helliker.id3.MP3File;
helliker.id3.Playlist;
48
49
button.addActionListener(this);
mainPanel.add(button);
button = new JButton(new
ImageIcon(getClass().getClassLoader().getResource("icons/Pause16.gif"))
);
button.setPreferredSize(new Dimension(20,20));
button.setToolTipText("Pause");
button.setActionCommand("Pause");
button.addActionListener(this);
mainPanel.add(button);
button = new JButton(new
ImageIcon(getClass().getClassLoader().getResource("icons/Stop16.gif")))
;
button.setPreferredSize(new Dimension(20,20));
button.setToolTipText("Stop");
button.setActionCommand("Stop");
button.addActionListener(this);
mainPanel.add(button);
button = new JButton(new
ImageIcon(getClass().getClassLoader().getResource("icons/Previous16.gif
")));
button.setPreferredSize(new Dimension(20,20));
button.setToolTipText("Previous Song");
button.setActionCommand("Previous");
button.addActionListener(this);
mainPanel.add(button);
button = new JButton(new
ImageIcon(getClass().getClassLoader().getResource("icons/Next16.gif")))
;
button.setPreferredSize(new Dimension(20,20));
button.setToolTipText("Next Song");
button.setActionCommand("Next");
button.addActionListener(this);
mainPanel.add(button);
mainPanel.add(Box.createHorizontalStrut(2));
progressBar = new JProgressBar();
progressBar.setPreferredSize(new Dimension(270,18));
progressBar.setStringPainted(true);
progressBar.setFont(new Font("Dialog",Font.BOLD,10));
progressBar.setString("");
mainPanel.add(progressBar);
mainPanel.add(Box.createHorizontalStrut(2));
50
51
}
public Playlist getPlaylist() {
return playlist;
}
public void setPlaylist(Playlist p) {
playlist = p;
}
public Player getPlayer() {
return player;
}
public void play() {
MP3File mp3File = null;
int position = Settings.getPlaylistPosition();
try {
mp3File = (MP3File) playlist.get(position);
fileTitle = mp3File.getTitle();
} catch(ID3v2FormatException ex) {
errorMessage(ex.getMessage());
}
if(player == null) {
try {
File file = new File(mp3File.getPath());
MediaLocator mediaLocator = new
MediaLocator(file.toURL());
player = Manager.createPlayer(mediaLocator);
player.addControllerListener(this);
progressBar.setString("Realizing...");
player.realize();
} catch(MalformedURLException ex) {
errorMessage(ex.getMessage());
} catch(NoPlayerException ex) {
errorMessage(ex.getMessage());
} catch(IOException ex) {
errorMessage(ex.getMessage());
}
} else {
player.start();
progressBar.setString("Playing " + fileTitle);
}
}
private void pause() {
if(player != null) {
MP3File mp3File = null;
int position = Settings.getPlaylistPosition();
try {
mp3File = (MP3File) playlist.get(position);
fileTitle = mp3File.getTitle();
progressBar.setString( fileTitle + " Paused");
} catch(ID3v2FormatException ex) {
errorMessage(ex.getMessage());
}
player.stop();
}
}
public void stop() {
if(player != null) {
52
player.removeControllerListener(this);
player.stop();
player.close();
player = null;
}
if(playThread != null) {
playThread = null;
}
progressBar.setValue(0);
progressBar.setString("");
}
private void previous() {
int position = Settings.getPlaylistPosition();
position--;
if(position < 0)
position = 0;
Settings.setPlaylistPosition(position);
if(player != null)
stop();
play();
}
private void next() {
int position = Settings.getPlaylistPosition();
position++;
if(position >= playlist.size()) {
position = 0;
Settings.setPlaylistPosition(position);
stop();
return;
}
Settings.setPlaylistPosition(position);
if(player != null)
stop();
play();
}
public static void main(String args[]) {
new JavaPlayer();
}
public void actionPerformed(ActionEvent ev) {
JButton button = (JButton) ev.getSource();
String command = button.getActionCommand();
if(command.equals("Exit"))
exitAction();
else if(command.equals("Open Playlist"))
playlistAction();
else if(command.equals("Playlist Manager"))
managerAction();
else if(command.equals("Play"))
play();
else if(command.equals("Pause"))
pause();
else if(command.equals("Stop"))
stop();
else if(command.equals("Previous"))
previous();
else if(command.equals("Next"))
next();
53
}
public void stateChanged(ChangeEvent ev)
{
float vol=slider.getValue();
GainControl gc=player.getGainControl();
gc.setLevel(vol/100);
}
public void controllerUpdate(ControllerEvent ev) {
if(ev instanceof RealizeCompleteEvent) {
player.prefetch();
progressBar.setString("Prefetching...");
}
if(ev instanceof PrefetchCompleteEvent) {
Time time = player.getDuration();
progressBar.setMaximum((int) time.getSeconds());
progressBar.setString("Playing " + fileTitle);
playThread = new Thread(this);
playThread.start();
player.getGainControl().setLevel(1);
player.start();
}
if(ev instanceof EndOfMediaEvent) {
player.removeControllerListener(this);
player.stop();
player.close();
player = null;
if(playThread != null) {
playThread = null;
}
progressBar.setValue(0);
next();
}
}
public void mouseDragged(MouseEvent ev) {
Point loc = getLocation();
Point clk = ev.getPoint();
Point pt = new Point(loc.x + clk.x,loc.y + clk.y);
setLocation(pt);
}
public void mouseMoved(MouseEvent ev) {}
public void run() {
while(playThread != null) {
if(player != null) {
Time time = player.getMediaTime();
progressBar.setValue((int) time.getSeconds());
try {
playThread.sleep(500);
} catch(InterruptedException ex) {}
}
}
}
class PlaylistFilter extends FileFilter{
public boolean accept(File file) {
if(file.isDirectory())
return true;
String s = file.getName().toLowerCase();
if (s.endsWith(".m3u"))
54
return true;
return false;
}
public String getDescription() {
return "Playlist Files";
}
}
}
2. PlalistManager.java
import
import
import
import
import
import
import
import
import
import
java.awt.datatransfer.DataFlavor;
java.awt.datatransfer.Transferable;
java.awt.datatransfer.UnsupportedFlavorException;
java.awt.dnd.DnDConstants;
java.awt.dnd.DropTarget;
java.awt.dnd.DropTargetContext;
java.awt.dnd.DropTargetEvent;
java.awt.dnd.DropTargetDragEvent;
java.awt.dnd.DropTargetDropEvent;
java.awt.dnd.DropTargetListener;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
java.awt.event.MouseEvent;
java.awt.event.MouseListener;
java.io.File;
java.io.FilenameFilter;
java.io.FileWriter;
java.io.IOException;
java.io.PrintWriter;
java.util.List;
java.util.Vector;
javax.swing.ButtonGroup;
javax.swing.JDialog;
javax.swing.JFileChooser;
javax.swing.JList;
javax.swing.JMenu;
javax.swing.JMenuBar;
javax.swing.JMenuItem;
javax.swing.JRadioButtonMenuItem;
javax.swing.JTable;
javax.swing.JScrollPane;
javax.swing.ListSelectionModel;
javax.swing.filechooser.FileFilter;
javax.swing.table.DefaultTableModel;
javax.swing.table.TableColumn;
helliker.id3.ID3v2FormatException;
helliker.id3.MP3File;
helliker.id3.NoMPEGFramesException;
import helliker.id3.Playlist;
55
table.setDropTarget(new DropTarget(table,this));
table.getTableHeader().setDropTarget(new
DropTarget(table.getTableHeader(),this));
getJMenuBar().setDropTarget(new
DropTarget(getJMenuBar(),this));
setDropTarget(new DropTarget(this,this));
}
private JMenuBar buildMenu() {
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("File");
JMenuItem menuItem = new JMenuItem("New");
menuItem.addActionListener(this);
56
menu.add(menuItem);
menuItem = new JMenuItem("Save");
menuItem.addActionListener(this);
menu.add(menuItem);
menuItem = new JMenuItem("Save As");
menuItem.addActionListener(this);
menu.add(menuItem);
//
JMenu optionMenu = new JMenu("Save Option");
//
ButtonGroup group = new ButtonGroup();
//
JRadioButtonMenuItem musicMatch = new
JRadioButtonMenuItem("MusicMatch Format");
//
group.add(musicMatch);
//
musicMatch.setSelected(!Settings.getWinampFormat());
//
musicMatch.addActionListener(this);
//
optionMenu.add(musicMatch);
//
JRadioButtonMenuItem winamp = new
JRadioButtonMenuItem("Winamp Format");
//
group.add(winamp);
//
winamp.setSelected(Settings.getWinampFormat());
//
winamp.addActionListener(this);
//
optionMenu.add(winamp);
//
menu.add(optionMenu);
menu.addSeparator();
menuItem = new JMenuItem("Exit");
menuItem.addActionListener(this);
menu.add(menuItem);
menuBar.add(menu);
menu = new JMenu("Edit");
menuItem = new JMenuItem("Add Files");
menuItem.addActionListener(this);
menu.add(menuItem);
menuItem = new JMenuItem("Add Directory");
menuItem.addActionListener(this);
menu.add(menuItem);
menu.addSeparator();
menuItem = new JMenuItem("Edit Tags");
menuItem.addActionListener(this);
menu.add(menuItem);
menu.addSeparator();
menuItem = new JMenuItem("Remove File");
menuItem.addActionListener(this);
menu.add(menuItem);
menuBar.add(menu);
return menuBar;
}
private void addToTable(MP3File mp3File, int pos) {
try {
Vector row = new Vector();
row.addElement(new Integer(pos));
row.addElement(mp3File.getTrack());
row.addElement(mp3File.getTitle());
row.addElement(mp3File.getAlbum());
row.addElement(mp3File.getArtist());
row.addElement(mp3File.getPlayingTimeString());
model.addRow(row);
57
}
catch(ID3v2FormatException ex) {
player.errorMessage(ex.getMessage());
}
}
private void scanDirectory(File dir) {
try {
Playlist pl = new Playlist();
pl.loadFromDirectory(dir,true);
for(int i=0;i<pl.size();i++) {
MP3File mp3 = (MP3File)pl.get(i);
playlist.add(mp3);
addToTable(mp3,model.getRowCount()+1);
}
}
catch(IOException ex) {
player.errorMessage(ex.getMessage());
}
}
private void saveAs() {
JFileChooser fileChooser = new
JFileChooser(Settings.getPlaylistDirectory());
fileChooser.addChoosableFileFilter(new PlaylistFilter());
fileChooser.setMultiSelectionEnabled(false);
if(fileChooser.showSaveDialog(null) ==
JFileChooser.APPROVE_OPTION) {
File file = fileChooser.getSelectedFile();
String path = file.getParent();
Settings.setPlaylistDirectory(path);
String name = file.getName();
if(!name.endsWith(".m3u"))
name = name + ".m3u";
file = new File(path,name);
savePlaylist(file);
Settings.setPlaylistDirectory(file.getParent());
Settings.setPlaylistFile(file.getName());
}
}
private void savePlaylist(File file) {
try {
playlist.writeToFile(file);
}
catch(IOException ex) {
player.errorMessage(ex.getMessage());
}
}
public void actionPerformed(ActionEvent ev) {
JMenuItem menuItem = (JMenuItem) ev.getSource();
String command = menuItem.getActionCommand();
if(command.equals("New")) {
playlist.clear();
model.setRowCount(0);
Settings.setPlaylistDirectory("");
Settings.setPlaylistFile("");
Settings.setPlaylistPosition(0);
58
}
else if(command.equals("Save")) {
File playlistFile = new
File(Settings.getPlaylistDirectory(),
Settings.getPlaylistFile());
if(playlistFile.exists() && playlistFile.isFile())
savePlaylist(playlistFile);
else
saveAs();
}
else if(command.equals("Save As")) {
saveAs();
}
else if(command.equals("Winamp Format")) {
Settings.setWinampFormat(true);
}
else if(command.equals("MusicMatch Format")) {
Settings.setWinampFormat(false);
}
else if(command.equals("Exit")) {
Settings.setManagerRect(getBounds());
player.setPlaylist(playlist);
dispose();
}
else if(command.equals("Add Files")) {
JFileChooser fileChooser = new
JFileChooser(Settings.getOpenDirectory());
fileChooser.addChoosableFileFilter(new MP3Filter());
fileChooser.setMultiSelectionEnabled(true);
if(fileChooser.showOpenDialog(null) ==
JFileChooser.APPROVE_OPTION) {
File[] files = fileChooser.getSelectedFiles();
for(int i=0;i<files.length;i++) {
if(files[i].exists()) {
Settings.setOpenDirectory(files[i].getParent());
try {
MP3File file = new
MP3File(files[i],MP3File.BOTH_TAGS);
playlist.add(file);
addToTable(file,model.getRowCount()+1);
}
catch(ID3v2FormatException ex) {
player.errorMessage(ex.getMessage());
}
catch(IOException ex) {
player.errorMessage(ex.getMessage());
}
catch(NoMPEGFramesException ex) {
player.errorMessage(ex.getMessage());
}
}
59
}
}
else if(command.equals("Add Directory")) {
JFileChooser fileChooser = new
JFileChooser(Settings.getOpenDirectory());
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fileChooser.setMultiSelectionEnabled(true);
if(fileChooser.showOpenDialog(null) ==
JFileChooser.APPROVE_OPTION) {
File[] files = fileChooser.getSelectedFiles();
for(int i=0;i<files.length;i++) {
if(files[i].exists()) {
Settings.setOpenDirectory(files[i].getParent());
scanDirectory(files[i]);
}
}
}
}
else if(command.equals("Edit Tags")) {
ListSelectionModel lsm = table.getSelectionModel();
if (!lsm.isSelectionEmpty()) {
int selectedRow = lsm.getMinSelectionIndex();
MP3File file = (MP3File)
playlist.get(selectedRow);
TagEditor tagEditor = new TagEditor(this,file);
tagEditor.setVisible(true);
playlist.set(selectedRow,file);
try {
Vector row = new Vector();
row.addElement(new
Integer(selectedRow+1));
row.addElement(file.getTrack());
row.addElement(file.getTitle());
row.addElement(file.getAlbum());
row.addElement(file.getArtist());
row.addElement(file.getPlayingTimeString());
model.insertRow(selectedRow,row);
model.removeRow(selectedRow+1);
}
catch(ID3v2FormatException ex) {
player.errorMessage(ex.getMessage());
}
}
}
else if(command.equals("Remove File")) {
int row = table.getSelectedRow();
if(row != -1) {
model.removeRow(row);
playlist.remove(row);
}
60
}
}
public void drop(DropTargetDropEvent ev) {
DropTargetContext targetContext =
ev.getDropTargetContext();
boolean outcome = false;
ev.acceptDrop(DnDConstants.ACTION_COPY);
List dataFlavors = ev.getCurrentDataFlavorsAsList();
Transferable t = ev.getTransferable();
for (int i = 0; i < dataFlavors.size(); i++) {
try {
DataFlavor flavor = (DataFlavor)
dataFlavors.get(i);
if(flavor.isFlavorJavaFileListType()) {
List list = (List)
t.getTransferData(flavor);
for(int j=0;j<list.size();j++) {
File file = (File) list.get(j);
if(file.isDirectory()) {
scanDirectory(file);
}
else
if(file.getName().toLowerCase().endsWith(".mp3")) {
try {
MP3File mp3File = new
MP3File(file);
playlist.add(mp3File);
addToTable(mp3File,playlist.size());
}
catch(ID3v2FormatException
ex) {
player.errorMessage(ex.getMessage());
}
catch(NoMPEGFramesException
ex) {
player.errorMessage(ex.getMessage());
}
}
}
}
outcome = true;
}
catch (IOException ex) {
player.errorMessage(ex.getMessage());
}
catch (UnsupportedFlavorException ex) {
player.errorMessage(ex.getMessage());
}
}
targetContext.dropComplete(outcome);
}
public void dropActionChanged(DropTargetDragEvent ev){}
public void dragOver(DropTargetDragEvent ev){}
61
if (s.endsWith(".mp3"))
return true;
return false;
}
public String getDescription() {
return "MP3 Files";
}
}
class PlaylistFilter extends FileFilter{
public boolean accept(File file) {
if(file.isDirectory())
return true;
String s = file.getName().toLowerCase();
if (s.endsWith(".m3u"))
return true;
return false;
}
public String getDescription() {
return "Playlist Files";
}
}
}
62
3.TagEditor.java
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
java.awt.GridBagConstraints;
java.awt.GridBagLayout;
java.awt.Insets;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
java.io.IOException;
javax.swing.JButton;
javax.swing.JComboBox;
javax.swing.JDialog;
javax.swing.JLabel;
javax.swing.JPanel;
javax.swing.JTextField;
javax.swing.SwingConstants;
helliker.id3.ID3v2FormatException;
helliker.id3.MP3File;
helliker.id3.NoMPEGFramesException;
63
"Club","Tango","Samba","Folklore","Ballad","Power
Ballad","Rhythmic Soul","Freestyle","Duet","Punk Rock","Drum Solo","A
capella","Euro-House","Dance Hall"};
public TagEditor(PlaylistManager p, MP3File f) {
super(p,"Tag Editor",true);
getContentPane().setLayout(new GridBagLayout());
file = f;
buildGUI();
populateFields();
pack();
}
private void buildGUI() {
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.NONE;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.insets = new Insets(0,1,1,1);
gbc.gridheight = 1;
gbc.gridwidth = 1;
gbc.gridx = 0;
gbc.gridy = 0;
getContentPane().add(new JLabel("Track Number:
",SwingConstants.RIGHT),gbc);
gbc.gridx = GridBagConstraints.RELATIVE;
trackNumber = new JTextField(3);
getContentPane().add(trackNumber,gbc);
gbc.gridy = 1;
gbc.gridx = 0;
getContentPane().add(new JLabel("Track Title:
",SwingConstants.RIGHT),gbc);
gbc.gridx = GridBagConstraints.RELATIVE;
trackTitle = new JTextField(30);
getContentPane().add(trackTitle,gbc);
gbc.gridy = 2;
gbc.gridx = 0;
getContentPane().add(new JLabel("Album:
",SwingConstants.RIGHT),gbc);
gbc.gridx = GridBagConstraints.RELATIVE;
album = new JTextField(30);
getContentPane().add(album,gbc);
gbc.gridy = 3;
gbc.gridx = 0;
getContentPane().add(new JLabel("Artist:
",SwingConstants.RIGHT),gbc);
gbc.gridx = GridBagConstraints.RELATIVE;
artist = new JTextField(30);
getContentPane().add(artist,gbc);
gbc.gridy = 4;
gbc.gridx = 0;
getContentPane().add(new JLabel("Genre:
",SwingConstants.RIGHT),gbc);
gbc.gridx = GridBagConstraints.RELATIVE;
genre = new JComboBox(genres);
getContentPane().add(genre,gbc);
gbc.gridy = 5;
gbc.gridx = 0;
getContentPane().add(new JLabel("Comment:
",SwingConstants.RIGHT),gbc);
64
gbc.gridx = GridBagConstraints.RELATIVE;
comment = new JTextField(30);
getContentPane().add(comment,gbc);
gbc.gridy = 6;
gbc.gridx = 0;
getContentPane().add(new JLabel("Composer:
",SwingConstants.RIGHT),gbc);
gbc.gridx = GridBagConstraints.RELATIVE;
composer = new JTextField(30);
getContentPane().add(composer,gbc);
gbc.gridy = 7;
gbc.gridx = 0;
getContentPane().add(new JLabel("Copyright Info:
",SwingConstants.RIGHT),gbc);
gbc.gridx = GridBagConstraints.RELATIVE;
copyright = new JTextField(30);
getContentPane().add(copyright,gbc);
gbc.gridy = 8;
gbc.gridx = 0;
getContentPane().add(new JLabel("Encoded By:
",SwingConstants.RIGHT),gbc);
gbc.gridx = GridBagConstraints.RELATIVE;
encoded = new JTextField(30);
getContentPane().add(encoded,gbc);
gbc.gridy = 9;
gbc.gridx = 0;
getContentPane().add(new JLabel("Original Artist:
",SwingConstants.RIGHT),gbc);
gbc.gridx = GridBagConstraints.RELATIVE;
original = new JTextField(30);
getContentPane().add(original,gbc);
gbc.gridy = 10;
gbc.gridx = 0;
getContentPane().add(new JLabel("URL:
",SwingConstants.RIGHT),gbc);
gbc.gridx = GridBagConstraints.RELATIVE;
userDefined = new JTextField(30);
getContentPane().add(userDefined,gbc);
gbc.gridy = 11;
gbc.gridx = 0;
getContentPane().add(new JLabel("Year:
",SwingConstants.RIGHT),gbc);
gbc.gridx = GridBagConstraints.RELATIVE;
year = new JTextField(4);
getContentPane().add(year,gbc);
gbc.gridy = 12;
gbc.gridx = 1;
JPanel buttonPanel = new JPanel();
JButton button = new JButton("OK");
button.addActionListener(this);
buttonPanel.add(button);
button = new JButton("Cancel");
button.addActionListener(this);
buttonPanel.add(button);
getContentPane().add(buttonPanel,gbc);
}
private void populateFields() {
65
try {
trackNumber.setText(file.getTrack());
trackTitle.setText(file.getTitle());
album.setText(file.getAlbum());
artist.setText(file.getArtist());
genre.setSelectedItem(file.getGenre());
comment.setText(file.getComment());
composer.setText(file.getComposer());
copyright.setText(file.getCopyrightInfo());
encoded.setText(file.getEncodedBy());
original.setText(file.getOriginalArtist());
userDefined.setText(file.getUserDefinedURL());
year.setText(file.getYear());
}
catch(ID3v2FormatException ex) {
System.out.println(ex.getMessage());
ex.printStackTrace();
}
}
public void actionPerformed(ActionEvent ev) {
JButton button = (JButton) ev.getSource();
String command = button.getActionCommand();
if(command.equals("OK")) {
try {
file.setTrack(Integer.parseInt(trackNumber.getText()));
file.setTitle(trackTitle.getText());
file.setAlbum(album.getText());
file.setArtist(artist.getText());
file.setGenre((String)genre.getSelectedItem());
file.setComment(comment.getText());
file.setComposer(composer.getText());
file.setCopyrightInfo(copyright.getText());
file.setEncodedBy(encoded.getText());
file.setOriginalArtist(original.getText());
file.setUserDefinedURL(userDefined.getText(),userDefined.getText(
));
file.setYear(year.getText());
file.writeTags();
}
catch(IOException ex) {
System.out.println(ex.getMessage());
ex.printStackTrace();
}
}
dispose();
}
}
4.Settings.java
import java.awt.Rectangle;
import java.io.File;
import java.io.FileInputStream;
66
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public class Settings {
private static Properties properties;
public static String getPlaylistFile() {
return properties.getProperty("player.playlistFile","");
}
public static void setPlaylistFile(String str) {
properties.setProperty("player.playlistFile",str);
}
public static String getPlaylistDirectory() {
return
properties.getProperty("player.playlistDirectory",System.getProperty("u
ser.dir"));
}
public static void setPlaylistDirectory(String str) {
properties.setProperty("player.playlistDirectory",str);
}
public static String getOpenDirectory() {
return
properties.getProperty("player.openDirectory",System.getProperty("user.
dir"));
}
public static void setOpenDirectory(String str) {
properties.setProperty("player.openDirectory",str);
}
public static int getPlaylistPosition() {
return
Integer.parseInt(properties.getProperty("player.playlistPosition","1"));
}
public static void setPlaylistPosition(int pos) {
properties.setProperty("player.playlistPosition",Integer.toString
(pos));
}
public static boolean getWinampFormat() {
String tmp =
properties.getProperty("player.winampFormat","false");
Boolean bool = new Boolean(tmp);
return bool.booleanValue();
}
public static void setWinampFormat(boolean winamp) {
properties.setProperty("player.winampFormat",new
Boolean(winamp).toString());
}
public static Rectangle getMainWindowRect() {
String x =
properties.getProperty("player.mainWindow.x","1");
String y =
properties.getProperty("player.mainWindow.y","1");
String width =
properties.getProperty("player.mainWindow.width","600");
67
String height =
properties.getProperty("player.mainWindow.height","25");
return new
Rectangle(Integer.parseInt(x),Integer.parseInt(y),Integer.parseInt(widt
h),Integer.parseInt(height));
}
public static void setMainWindowRect(Rectangle r) {
properties.setProperty("player.mainWindow.x",Integer.toString(r.x
));
properties.setProperty("player.mainWindow.y",Integer.toString(r.y
));
properties.setProperty("player.mainWindow.width",Integer.toString
(r.width));
properties.setProperty("player.mainWindow.height",Integer.toStrin
g(r.height));
}
public static Rectangle getManagerRect() {
String x = properties.getProperty("player.manager.x","1");
String y = properties.getProperty("player.manager.y","1");
String width =
properties.getProperty("player.manager.width","1000");
String height =
properties.getProperty("player.manager.height","500");
return new
Rectangle(Integer.parseInt(x),Integer.parseInt(y),Integer.parseInt(widt
h),Integer.parseInt(height));
}
public static void setManagerRect(Rectangle r) {
properties.setProperty("player.manager.x",Integer.toString(r.x));
properties.setProperty("player.manager.y",Integer.toString(r.y));
properties.setProperty("player.manager.width",Integer.toString(r.
width));
properties.setProperty("player.manager.height",Integer.toString(r
.height));
}
public static void loadSettings() {
properties = new Properties();
File file = new
File(System.getProperty("user.home"),"JavaPlayer.properties");
if(file.exists()) {
try {
FileInputStream istream = new
FileInputStream(file);
properties.load(istream);
istream.close();
}
catch(IOException ex) {
ex.printStackTrace();
}
68
}
}
public static void storeSettings() {
try {
File file = new
File(System.getProperty("user.home"),"JavaPlayer.properties");
FileOutputStream ostream = new
FileOutputStream(file);
properties.store(ostream,"General Player Settings");
ostream.close();
}
catch(IOException ex) {
ex.printStackTrace();
}
}
}
69