You are on page 1of 96

PROJECT REPORT

ON
“POMP”
(PORTABLE MEDIA PLAYER)

NAME : - ANAND ADLAKHA


REGISTRATION No : - 200604063

SYMBIOSIS CENTRE FOR DISTANCE LEARNING


ACADEMIC YEAR - 2006

RECOMMENDATION

The project work entitled “POMP” submitted by “Anand Adlakha” is a


satisfactory account of the bona-fide work under my supervision is
recommended towards the end of his 4th semester of MBA IT.

Guided By

“Mr. Ritesh Rustagi”

2
CIT COMPUTER CENTER
REWARI (HARYANA) PIN-123401
STUDENT PROFILE
Anand Adlakha Tel: 91-9812204989
H.No. 195 M Krishna Nagar, Email:- akhilashin@yahoo.com
Distt.- Rewari

OBJECTIVE
To obtain a creative & challenging position in computer Software & Hardware Development
that will utilize my knowledge and Experience and continue to accumulate Knowledge with a
progressive growth Oriented Company.

WORK EXPERIENCE
 From April’04 to till now with M/s. UJALA PUMPS (P) LTD. as a
EDP Head & Accounts Executive.
 To Maintain books of A/c
 To Manage cash flow and Manage banks.
 To Prepare B.R.S and MIS.
 Creation of every type Vouchers entry.
 Check the Salary sheet & Disbursement
 Check the Inventory.
 Monthly Reconciliation with Branches and creditors
 To Manage Networking & Hardware.
 Security of Data
 Installation of Software in all branches of UPPL Group.

SOFTWARE / HARDWARE SKILLS


Operating Systems : Dos, Windows9x, Windows 2000, Windows
Me, Windows XP.

Languages : C With Data Structure , C++ , Visual Basic 6.0,


Java Core, Advance Java (Servlets, RMI, JDBC,
Swing)

Database : Dbase, Visual Foxpro, Oracle 8i.

Packages : Wordstar, Lotus, Page Maker 6.5, Coral


Draw 10, Ms-Office, Html, Java Script,
FrontPage & Basic Knowledge of SAP.

Accounting Package : Tally 7.2 & 9 & Busy Soft.

3
EDUCATIONAL QUALIFICATION
• B.Com from Delhi University 50%.
• 12th from Commerce with 63%.
• 10th with 66%

TECHNICAL QUALIFICATIONS

 One-Year Diploma in Computer Programming and System Management from


Capital Computer’s New Delhi.

 Six-Month Diploma in Office Automation and Financial Accounting from C-


DEC Netcom Rewari.

 E-Commerce Course from Wintech E-Commerce Centre (South Ext.) New Delhi

 M Sc IT From M.D University Rohtak with 78%.


Sem-1 - 72%
Sem-2 - 76%
Sem-3 - 83%
Sem-4 - 83%

• Pursuing PGDIT (Post Graduate Diploma in Information Technology) from


Symbiosis University Pune.-

PERSONAL PROFILE

Father’s Name : Lt Sh. K K Adlakha

Date of Birth : 04-02-1983

Marital Status : Unmarried

Language Known : Hindi & English.

4
(ANAND ADLAKHA)

CONTENTS
CHAPTERS

PRELIMINARIES
• Recommendation
• Student Information

1. Abstract 6
2. Introduction 7
3. Present Scenario 8
4. Methodology 10
5. Problem Definition 11
6. Feasibility Study 12
7. Business Model 14
8. Requirement analysis 16
9. Initial Study 18
A. Time Based Data 18
B. Media presentation 18
C. JMF Architecture 23
D. Presentation 24
E. Time Model 27
F. Data Model 29
G. Controls 31
H. Event Model 33
10. Functional Modelling 35
A. Context Diagram 35
B. DFD Level 1 (Basic Player) 36
C. DFD Level 1 (Mobile application) 37
D. DFD Level 2 (Player) 39
E. DFD Level 2 (Playlist Manager) 40
F. State Transition Diagram 41
11. ID3 Tag 42
12. Data Dictionary 43
13. Implementation 46
A. Main Interface 46
B. Playlist Mnager 47
C. Tag Editor 48
14. Testing 49
5
15. Installation 51
16. Limitations 54
17. Conclusion 55
18. Source Code 56

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 (that’s 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.

6
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 java’s “Write once run
everywhere” title.

Benefits of the system


1. Fast standalone mp3 player.
2. Save user time controlling playback from their mobile doing anything else.
3. Facility to save play-list files.
4. ID3 tag editor to edit mp3 metadata.
5. Made in java, hence is extensible, platform independent, robust.

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:
� Provide a platform to play audio (MP3) file
� Provide different interfaces for different level users
� Support playlist (M3U) file
� Provide playlist management

General Requirements
The following general requirements were laid out for our project named POMP:
7
• The player can play audio (MP3) file
• The player can provide some necessary function of playing audio
(MP3) file, such as previous, next, random, repeat etc.
• Users can choose their interface for their level
• Users can add new songs to the playlist or manage their playlist
• All user’s data and playlists could be stored electronically
Introduction of present scenario
Presently users use software like winamp ,windows media player and open source’s vlc
player. Plug-ins for these software are available to control these players. These packs have two
parts . First part is installed on computer that acts as a server. Second part is installed on our
Bluetooth enabled mobile device. This way program on mobile device communicates with the
application on system. Its generally a two way communication. Player receives control
information and transforms it in proper manner to control playback of songs.

One of these plug-ins for most popular mp3 player, Winamp is available at its website at
http://www.winamp.com/plugins/browse.php?search=yes&filter=C&query=bluetooth

but main drawback of this plug-in is that its platform dependent i.e. available only for
Microsoft windows. They are coded in languages like c++ or visual basic. Hence there is no
scope for these plug-ins what are written for winamp, windows media player or other players.
They can not run on other operating systems like Linux or Mac OS.

Other option is proprietary software like Bluetooth Remote Control download from
http://www.bluetoothshareware.com/bluetooth_remote_control_manual.asp Demo is available
here. This software is very good as it supports many features like iTunes, Windows media
player, PowerPoint, file browser etc.

Good thing with these popular software is, they are rich in features. They have graphic
equalizer. Support for custom skins, custom plug-ins for extensibility.

8
Today in the rapidly increasing world of internet, culture for internet radio and online
streaming video is increasing and people are making it a habit. Many media player nowadays
support listening to internet radio channels and live video broadcast. One of the pioneers in
streaming technology is real player which offers great performance even on low bandwidth.

Missing codec were everybody’s headache few years back but nowadays we have
manysoftware bundles that offer large variety of codec altogether like K-Lite pack have about
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.

9
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

10
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.

11
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:

• The current system may no longer suit its purpose,


• Technological advancement may have rendered the current system redundant,
• The business is expanding, allowing it to cope with extra work load,
• Customers are complaining about the speed and quality of work the business provides,
• Competitors are now winning a big enough market share due to an effective integration
of a computerized system.

Within a feasibility study, six areas must be reviewed, including those of Economics,
Technical, Schedule, Organizational, Cultural, and Legal.

1. Economic feasibility study


This involves questions such as whether the firm can afford to build the system, whether its
benefits should substantially exceed its costs, and whether the project has higher priority and
profits than other projects that might use the same resources. This also includes whether the
project is in the condition to fulfill all the eligibility criteria and the 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.

2. Technical feasibility study


This involves questions such as whether the technology needed for the system exists, how
difficult it will be to build, and whether the firm has enough experience using that

12
technology.The assessment is based on an outline design of system requirements in terms of
Input, Output, Fields, Programs, and Procedures.This can be qualified in terms of volumes of
data,trends,frequency of updating,etc..in order to give an introduction to the technical system.

1 **Needed Technologies are known but whether they work together is question of
research. We drop it on learning and analyzing with the help of so many code
snippets and check their functionality.

2 **Streaming of audio as well as video data to Bluetooth device from computer


may be restricted or have a jitter due to low bandwidth of Bluetooth.

3. Behavioral changes study


This involves questions such as whether the system has enough support to be implemented
successfully, whether it brings an excessive amount of change, and whether the organization is
changing too rapidly to absorb it.
**All the behaviors are expected to be in favor of our candidate system as its promising a
flexibility in controlling the music they way you liked and too without worrying about
the operating system you use.

**As its and open source project, it can be downloaded by anybody and can be modified
according to their taste and functional need.

13
Business Model
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: “

“ A business model is a conceptual tool that contains a big set of elements and their
relationships and allows expressing the business logic of a specific firm. It is a description of
the value a company offers to one or several segments of customers and of the architecture of
the firm and its network of partners for creating, marketing, and delivering this value and
relationship capital, to generate profitable and sustainable revenue streams. “
— Osterwalder, Pigneur and Tucci (2005)
**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

14
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 don’t 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 don’t have enough time to improve the software.
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 don’t 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 don’t have enough time to make the player more powerful.

15
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 300 MHz or higher
Memory 64 MB RAM 128 MB RAM or higher
Video adapter and monitor Super VGA (800 x 600) Super VGA (800 x 600) or
higher resolution
Hard drive disk free space 1.5 GB 1.5 GB or higher
Devices Keyboard and mouse Keyboard and
mouse
Others Sound card, speakers, Sound card, speakers, and

16
hdh hdh

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. JCreator (an IDE for programming in java).
2. JDK(Java Development Kit) 4 or better.
3. Sun Java Wireless Toolkit
4. Java Media Framework (JMF) API for developing media applications.
5. JSR82, JSR135 API for Bluetooth Profiles and Developing Multimedia application for
mobile device.
6. Impronto Simulator (a proprietary software for execution of mobile application in
simulator) provided by Rococo Software.

17
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
haracteristics of time-based media and describes the use of timebasedmedia in terms of a
undamental 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 destinationsÑfor example, saved to a Þle or
transmitted across the network. An output destination for media data is sometimes referred to
as a data sink.

18
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 streamÑotherwise the playback of the different streams might actually
begin at different times.

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.

19
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.

20
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.

Renderers
A renderer is an abstraction of a presentation device. For audio, the presentation device is
typically the computer’s 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.

21
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.

22
High-Level Architecture of JMF
Devices such as tape decks and VCRs provide a familiar model for recording, processing, and
presenting time-based media. When you play a movie using a VCR, you provide the media
stream to the VCR by inserting a video tape. The VCR reads and interprets the data on the
tape and sends appropriate signals to your television and speakers.

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 JMF’s 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

23
programs while maintaining the flexibility and extensibility required to support advanced
media applications and future media technologies.
High Level JMF Architecture

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.

24
JMF Processor Model

Players
A Player processes an input stream of media data and renders it at a precise time. A
DataSource is used to deliver the input media-stream to the Player. The rendering destination
depends on the type of media being presented.

JMF Player Model


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.

Classes involved in JMF Player

Player States

25
A Player can be in one of six states. The Clock interface defines the two primary states:
topped and Started. To facilitate resource management, Controller breaks the Stopped state
down into five standby states: Unrealized, Realizing, Realized, Prefetching, and Prefetched.

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
26
object’s media presentation is repositioned, or if a change in the Player object’s 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 object’s 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.

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.

27
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 object’s 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 stream’s 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 TimeBase for example, a negative rate
might be used to play a media stream backward. 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.

28
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:

29
JMF Data Model

Push and Pull Data Sources


Media data can be obtained from a variety of sources, such as local or network files and live
broadcasts. JMF data sources can be categorized according to how data transfer is initiated:

1. Pull Data-Source - the client initiates the data transfer and controls the flow of data
from pull data-sources. Established protocols for this type of data include Hypertext
Transfer Protocol (HTTP) and FILE. JMF defines two types of pull data sources:
PullDataSource and PullBufferDataSource, which uses a Buffer object as its unit of
transfer.

2. Push Data-Source - the server initiates the data transfer and controls the flow of data
from a push data-source. Push data-sources include broadcast media, multicast media,
30
and video-on-demand (VOD). For broadcast data, one protocol is the Real-time
Transport Protocol (RTP), under development by the Internet Engineering Task Force
(IETF). The Media Base protocol developed by SGI is one protocol used for VOD.
JMF defines two types of push data sources: PushDataSource and
PushBufferDataSource, which uses a Buffer object as its unit of transfer.

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 objectÕs 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 deÞnes 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.

31
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.

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 object’s
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. 3. A
ControllerErrorEvent is a special case of ControllerClosedEvent. You can listen for

32
ControllerErrorEvents so that your program can respond to Controller malfunctions to
minimize the impact on the user.

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 deÞnes a corresponding
listener interface. To receive notiÞcation 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.

33
JMF Event Model

34
Events in JMF

35
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.

36
DFD Level 1

Here in this diagram are shown three processes


1. Initialize.
2. Play
3. Manage Play-List

Initialize process collects system information and initializes GUI of our MP3 player. It also
loads previous settings.

37
Play process has all the functionalities required for playback. Like play, Pause, Stop, Next,
Previous, Mute, Change Volume, Seek.

Manage Playlist process gives facility to load a saved playlist, Save a plalist. Build a playlist
by adding files and folders to it. It also provides an additional facility, to edit ID3 header
information of MP3 file and save them.

DFD Level 1

38
39
DFD Level 2 (Play Process)
Play process has all the functionalities required for playback

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.

40
DFD Level 2 (Manage Play-List)

This process performs three tasks


1. Open Play-list
2. Save Play-list
3. Edit ID3 tags of a file
Open playlist process opens previously saved playlist files of standard type, .pls.

Save paylist save the currently loaded playlist as .pls file on the file system.

Edit Id3 tag process is used to edit metadata about mp3 files like album, author, title, duration,
year, etc.

41
STD (State Transition Diagram)

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 done frequently.
Stop state activates when user takes stop command or playing song finishes.

42
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

43
Data dictionary
Song Information

Name : Track Number


Aliases : Song order Number
Where / How used : Read Track Number (Input)
Display- Track – Number (Output)
Description : Track No. = Linear number
Format : Numeric Data

Name: Song Title


Aliases: Song name
Where/How Read-song-title (input)
Used: Display-song-title (output)
Description: Song title = { Letter } n
Letter = [ A | B | C | …. | Z | a | b | c | …. | z | 0 | 1 | …. | 9 ]
Format: Alphanumeric Data

Name: Artist
Aliases:
Where/How Read-artist-name (input)
Used: Display-artist-name (output)
Description: Artist = { Letter } n
Letter = [ A | B | C | …. | Z | a | b | c | …. | z | 0 | 1 | …. | 9 ]
Format : Alphanumeric Data

Name: Album
Aliases: Album name
Where/How Read-album-name (input)
Used: Display-album-name (output)
Description: Album = { Letter } n

44
Letter = [ A | B | C | …. | Z | a | b | c | …. | z | 0 | 1 | ….| 9 ]

Format: Alphanumeric Data

Name: Year
Aliases:
Where/How Read-year (input)
Used: Display-year (output)
Description: Year = { Letter } 4
Letter = [ 0 | 1 | ….| 9 ]

Format: Numeric Data

Name: Genre
Aliases:
Where/How Read-genre (input)
Used: Display-genre (output)
Description: Genre = [ M | F ]
Format: Character

Name: Comment
Aliases:
Where/How Read-comment (input)
Used: Display-comment (output)
Description: Comment = { Letter } n
Letter = [ A | B | C | …. | Z | a | b | c | …. | z | 0 | 1 | ….| 9 ]
Format: Alphanumeric Data

Name: Copyright
Aliases:
Where/How Read-copyright (input)

45
Used: Display-copyright (output)

Description: Copyright = { Letter } n


Letter = [ A | B | C | …. | Z | a | b | c | …. | z | 0 | 1 | ….| 9 ]
Format: Alphanumeric Data

Name: Size
Aliases:
Where/How Read-size-name (input)
Used: Display-size-name (output)
Description: Size = Number
Format: Numeric Data

Name: Length
Aliases: Song length
Where/How Read-length (input)
Used: Display-length (output)
Description : Length = { 0 | 1 | 2 | …. | 9 } 2 + : + { 0 | 1 | 2 | …. | 9 } 2
Format: Symbol and Numeric Data

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.
Our project has 3 forms
1. Main interface (Control panel)
2. Playlist manager
3. ID3 Tag Editor

46
1. Main interface implements all the basic commands for playback control like play,
pause, stop, previous, next and volume control. Provides facility to open previously saved
playlist, show playlist manager.
Following is a snapshot of main interface.

Following is the list of buttons on this form from left to right.


1. Open PlayList (pls)
2. Show Playlist
3. play
4. pause
5. stop
6. previous
7. next
8. Song info pallatte
9. volume control
10. exit
2. Playlist Manager

This interface has a menu, a dynamically expandable table in scrollpane.


Menu bar in this interfae has following commands

47
File
New (starts a new playlist by clearing old one )
Save (Saves current playlist, opens savefile dialog, in .pls file)
Save as (Saves current playlist, opens savefile dialog, in user define file format)
Exit (Exits from program)
Edit
Add file(s) (Adds files to playlist, openfile dialog opens, multiple files allowed)
Add folder (Adds all files, of the folder and files in folder in side it to playlist)
Edit Tags (Open a tageditor form for selected file)
Remove File (Removes file from playlist)
It has a table which shows list of files that are currently in playlist.
Following metadata about mp3 files are shown in this table
1. Serial Number
2. Track number
3. Track Title
4. Album
5. Artist
6. Time

2. ID3 Tag Editor

48
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.

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 quality related 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 behavior of the product
against a specification.

49
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 product
—putting 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.

50
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.

51
One file installation (Setup.exe), an executable file that’s synonymous for installation can be
made for java applications as well. All we need to follow these steps.

Our prerequisites are:

1. Jar file of our project.


2. Jar files of optional API’s we have used in java.
3. JRE should be included in our bundle as it may not be installed on client’s system.
4. All media files, images, databases and sound files should be stored in a well organized
folder which is accessed by our java files by means of absolute path. Images that are
part of user interface can be put in jar file.
5. A full documentation of project, for example as generated by Netbeans.
6. A third party software like Install4j to pack-up all these files together and can be set
accordingly for installation. Means a installable file that creates start menu shortcuts as
well as registers our application to operating system’s registry.
1. Making a JAR file
JAR (Java ARchive) is a ZIP file used to distribute a set of Java classes. It is used to store
compiled Java classes and associated metadata that can constitute a program. JAR files can be
created and extracted using the "jar" command that comes with the JDK. It can be done using
zip tools, but as WinZip has a habit of renaming all-uppercase directories and files in lower
case, this can raise support calls with whoever created the JAR or the tool authors themselves.
WinRAR, on the other hand, retains the original case of filenames.

A JAR file has a manifest file located in the path META-INF/MANIFEST.MF. The entries in
the manifest file determine how the JAR file will be used. JAR files which are intended to be
executed as standalone programs will have one of their classes specified as he "main" class.
The manifest file would have an entry such as

Main-Class: myPrograms.MyClass

Such JAR files are typically started with a command similar to


52
java -jar foo.jar

These files can also include a Classpath entry, which identifies other JAR files to be loaded
with the JAR. This entry consists of a list of absolute or relative paths to other JAR files.
Although intended to simplify JAR use, in practice, it turns out to be notoriously brittle as it
depends on all the relevant JARs being in the exact locations specified when the entry-point
JAR was built. To change versions or locations of libraries, a new manifest is needed.

** for making our jar file we first of all keep all 4 class files JavaPlayer.class,
PlaylistManager.class, Settings.java, TagEditor,java in a single directory. Then maing a folder
of images used in our applications within it. Now we will execute following command

jar cvf pomp.jar *.class images


now we make a text file say mf.txt with following lines in it.
Class-path : jmf.jar helliker.id3.jar mp3plugin.jar
Main-Class : JavaPlayer
Now execute following command.
Jar vfm pomp.jar mf.txt
2. Create Documetation with NetBeans

Create javadoc with Netbeans IDE. For this just right click on project in project window
a>>right click on it and click on generate documentation. Our documentation will be ready on
the fly.

3. Create Setup file with Install4j


Create a installer with the third party software called Install4j. For this just follow the wizard
and make settings accordingly.

53
Limitations of our system
Following are limitations of the system that should be removed.
• Its does not support other file formats than MP3.A file filter is used to accept only files
of mp3 extension.
• It doesn’t 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,

54
>> 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

• There is no book available on JMF, so it was quite difficult to learn as I had to follow
“learn by work” technique, originally been main motto at MIT.
• Got to know about optional API’s of java, it started understanding of java’s main
utility , that is its expandability and being open source in nature.

55
• As even I kept this project as open source, many others will be using my code and they
can make it better and complete. I will start this project on Sourceforge.net, biggest
online open-source contribution site.
• Learned how media files work and got to now internal file structure of MP3 file.
• I knew at the beginning of this project that its too ambitious for me, and chances for its
success are very low. Taking risk helped me to learn faster.
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.

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.

56
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

Hierarchy For All Packages


Class Hierarchy
o 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)

o 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)
57
o 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

1. JavaPlayer.java
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

58
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.event.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.MalformedURLException;
import javax.media.*;
import javax.media.ControllerEvent;
import javax.media.ControllerListener;
import javax.media.EndOfMediaEvent;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.NoPlayerException;
import javax.media.Player;
import javax.media.PrefetchCompleteEvent;
import javax.media.RealizeCompleteEvent;
import javax.media.Time;
import javax.media.control.*;
import javax.media.Controller.*;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JSlider;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
59
import javax.swing.JWindow;
import javax.swing.filechooser.FileFilter;
import helliker.id3.ID3v2FormatException;
import helliker.id3.PlaylistException;
import helliker.id3.MP3File;
import helliker.id3.Playlist;
public class JavaPlayer extends JWindow implements
ActionListener,ControllerListener,MouseMotionListener,ChangeListener,
Runnable {
private Playlist playlist;
private Player player = null;
private JPanel mainPanel = null;
private JProgressBar progressBar = null;
private String fileTitle = "";
private Thread playThread = null;
private JSlider slider;
public JavaPlayer() {
super();
mainPanel = new JPanel(new FlowLayout(FlowLayout.LEADING,1,1));
mainPanel.setBorder(BorderFactory.createRaisedBevelBorder());
mainPanel.addMouseMotionListener(this);
Settings.loadSettings();
Settings.setMainWindowRect(new Rectangle(580,50));
setBounds(Settings.getMainWindowRect());
buildToolbar();
getContentPane().add(mainPanel);
setVisible(true);
playlist = new Playlist();
File playlistFile = new File(Settings.getPlaylistDirectory(),
Settings.getPlaylistFile());
if(playlistFile.exists() && playlistFile.isFile()) {
60
progressBar.setString("Loading Playlist...");
try {
playlist.loadFromFile(playlistFile);
} catch(IOException ex) {
errorMessage(ex.getMessage());
} catch(PlaylistException ex) {
errorMessage(ex.getMessage());
}
progressBar.setString("");
}
}
private void buildToolbar() {
JButton button ;
button = new JButton(new
ImageIcon(getClass().getClassLoader().getResource("icons/Playlist16.gif
")));
button.setPreferredSize(new Dimension(20,20));
button.setToolTipText("Open Playlist");
button.setActionCommand("Open Playlist");
button.addActionListener(this);
mainPanel.add(button);
button = new JButton(new
ImageIcon(getClass().getClassLoader().getResource("icons/Manager16.gif"
)));
button.setPreferredSize(new Dimension(20,20));
button.setToolTipText("Show Playlist");
button.setActionCommand("Playlist Manager");
button.addActionListener(this);
mainPanel.add(button);
button = new JButton(new
ImageIcon(getClass().getClassLoader().getResource("icons/Play16.gif")))
61
;
button.setPreferredSize(new Dimension(20,20));
button.setToolTipText("Play");
button.setActionCommand("Play");

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);
62
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));
slider = new JSlider();
slider.setMaximum(100);
slider.setPreferredSize(new Dimension(120,20));
slider.setToolTipText(Integer.toString(slider.getValue()));
slider.addChangeListener(this);
mainPanel.add(slider);
button = new JButton(new
ImageIcon(getClass().getClassLoader().getResource("icons/Exit16.gif")))
;
button.setPreferredSize(new Dimension(20,20));
button.setToolTipText("Exit Player");
button.setActionCommand("Exit");
button.addActionListener(this);
mainPanel.add(button);
63
mainPanel.add(Box.createHorizontalStrut(2));
}
public void errorMessage(String s) {
JOptionPane.showMessageDialog(null, s, "Error",
JOptionPane.ERROR_MESSAGE);
}
private void exitAction() {
Settings.setMainWindowRect(getBounds());
Settings.storeSettings();
if(player != null) {
player.removeControllerListener(this);
player.stop();
player.close();
player = null;
}
if(playThread != null) {
playThread = null;
}
System.exit(0);
}

private void managerAction() {


if(playlist != null) {
PlaylistManager manager = new PlaylistManager(this);
manager.setVisible(true);
}
}
private void playlistAction() {
JFileChooser fileChooser = new
JFileChooser(Settings.getPlaylistDirectory());
64
fileChooser.setMultiSelectionEnabled(false);
fileChooser.addChoosableFileFilter(new PlaylistFilter());
if(fileChooser.showOpenDialog(null) ==
JFileChooser.APPROVE_OPTION) {
progressBar.setString("Loading Playlist...");
playlist = new Playlist();
try {
File playlistFile = fileChooser.getSelectedFile();
playlist.loadFromFile(playlistFile);
Settings.setPlaylistDirectory(playlistFile.getParent());
Settings.setPlaylistFile(playlistFile.getName());
} catch(IOException ex) {
errorMessage(ex.getMessage());
} catch(PlaylistException ex) {
errorMessage(ex.getMessage());
}
progressBar.setString("");
}
}
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();
65
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();
66
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) {
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();
67
}
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();
68
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();
}
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();
}
69
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) {}
70
}
}
}
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";
}
}
}

2. PlalistManager.java
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetContext;
import java.awt.dnd.DropTargetEvent;

71
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.FilenameFilter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Vector;
import javax.swing.ButtonGroup;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JTable;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.filechooser.FileFilter;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import helliker.id3.ID3v2FormatException;
import helliker.id3.MP3File;
import helliker.id3.NoMPEGFramesException;
72
import helliker.id3.Playlist;

public class PlaylistManager extends JDialog implements ActionListener,


DropTargetListener,MouseListener {
private JavaPlayer player;
private Playlist playlist;
private Vector columns;
private DefaultTableModel model;
private JTable table;
private int[] columnWidth = {75,100,300,300,300,75};
public PlaylistManager(JavaPlayer p) {
super();
setTitle("Playlist Manager");
setModal(true);
setBounds(Settings.getManagerRect());
setJMenuBar(buildMenu());
player = p;
playlist = player.getPlaylist();
columns = new Vector();
columns.addElement("Number");
columns.addElement("Track Number");
columns.addElement("Track Title");
columns.addElement("Album");
columns.addElement("Artist");
columns.addElement("Time");
model = new DefaultTableModel(columns,0) {
public boolean isCellEditable(int row, int column) {
return false;
}
};
table = new JTable(model);
73
for(int i=0;i<columns.size();i++) {
TableColumn column = table.getColumn((String)
columns.elementAt(i));
column.setPreferredWidth(columnWidth[i]);
}
table.getTableHeader().setResizingAllowed(false);
table.setRowSelectionAllowed(true);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.addMouseListener(this);
JScrollPane scrollPane = new JScrollPane(table);
getContentPane().add(scrollPane);
for(int i=0;i<playlist.size();i++)
addToTable((MP3File) playlist.get(i),i+1);
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);
menu.add(menuItem);
menuItem = new JMenuItem("Save");
menuItem.addActionListener(this);
menu.add(menuItem);
74
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();
75
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);
}

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++) {
76
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);
77
}
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);
}
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);
78
}
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());
79
}
}
0
}
}
}
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);
80
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);
}}}
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 {
81
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;
}
82
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){}

public void dragEnter(DropTargetDragEvent ev){}


public void dragExit(DropTargetEvent ev) {}
public void mouseClicked(MouseEvent ev) {
if(ev.getClickCount() == 2) {
int row = table.rowAtPoint(ev.getPoint());
if(row != -1) {
Settings.setPlaylistPosition(row);
if(player.getPlayer() != null)
player.stop();
player.play();
}
}
}
public void mousePressed(MouseEvent ev) {}
public void mouseExited(MouseEvent ev) {}
public void mouseEntered(MouseEvent ev) {}
public void mouseReleased(MouseEvent ev) {}
83
class MP3Filter extends FileFilter implements FilenameFilter{
public boolean accept(File dir, String name) {
String s = name.toLowerCase();
if (s.endsWith(".mp3"))
return true;
File file = new File(dir,name);
if(file.exists() && file.isDirectory())
return true;
return false;
}
public boolean accept(File file) {
if(file.isDirectory())
return true;
String s = file.getName().toLowerCase();
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;
}
84
public String getDescription() {
return "Playlist Files";
}
}
}

3.TagEditor.java
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JButton;

85
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import helliker.id3.ID3v2FormatException;
import helliker.id3.MP3File;
import helliker.id3.NoMPEGFramesException;
public class TagEditor extends JDialog implements ActionListener {
MP3File file;
JTextField
trackNumber,trackTitle,album,artist,comment,composer,copyright,encoded,
original,userDefined,year;
JComboBox genre;
String [] genres = {"Blues","Classic
Rock","Country","Dance","Disco","Funk","General Fiction","Grunge","Hip-
Hop","Jazz","Metal","New
Age","Oldies","Other","Pop","R&B","Rap","Reggae","Rock","Techno",
"Industrial","Alternative","Ska","Death
Metal","Pranks","Soundtrack","Euro-Techno","Ambient","Trip-
Hop","Vocal","Jazz+Funk","Fusion","Trance","Classical","Instrumental","Acid",
"House","Game","Sound
Clip","Gospel","Noise","AlternRock","Bass","Soul","Punk","Space","Medit
ative","Instrumental Pop","Instrumental
Rock","Ethnic","Gothic","Darkwave",
"Techno-Industrial","Electronic","Pop-
Folk","Eurodance","Dream","Southern
Rock","Comedy","Cult","Gangsta","Top 40","Christian
Rap","Pop/Funk","Jungle","Native American",
"Cabaret","New
86
Wave","Psychadelic","Rave","Showtunes","Trailer","Lo-Fi","Tribal","Acid
Punk","Acid Jazz","Polka","Retro","Musical","Rock & Roll","Hard
Rock","Folk","Folk-Rock",
"National Folk","Swing","Fast
Fusion","Bebob","Latin","Revival","Celtic","Bluegrass","Avantgarde","Go
thic Rock","Progressive Rock","Psychedelic Rock","Symphonic Rock","Slow
Rock",
"Big Band","Chorus","Easy
Listening","Acoustic","Humour","Speech","Chanson","Opera","Chamber
Music","Sonata","Symphony","Booty Bass","Primus","Porn
Groove","Satire","Slow Jam","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;
87
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;
88
genre = new JComboBox(genres);
getContentPane().add(genre,gbc);
gbc.gridy = 5; gbc.gridx = 0; getContentPane().add(new JLabel("Comment:
",SwingConstants.RIGHT),gbc);
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:
89
",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() {
try {
trackNumber.setText(file.getTrack());
90
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());
91
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;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

92
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
93
(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");
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.toString(r.height));
}
94
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(width),Integer.parseI
nt(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();
}
}
}
95
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();
}
}
}

96

You might also like