Giter Site home page Giter Site logo

ruby-playlist's Introduction

Build Status

Playlist

This ruby gem allows you to create and manipulate playlists of musical tracks.

It supports parsing and generating playlists in the following formats:

  • Cue Sheet
  • JSPF
  • M3U
  • PLS
  • XSPF
  • A simple human readable format

Installation

Add this line to your application's Gemfile:

gem 'playlist'

And then execute:

$ bundle

Or install it yourself as:

$ gem install playlist

Usage

For full details, please see the API Documentation.

Creating a Playlist

The playlist gem provides data model classes for creating and manipulating playlists and music metadata in ruby.

Playlists can be constructed by passing a list of attributes to the constructor or by setting the attributes directly:

playlist = Playlist.new(:title => "My awesome playlist")
playlist.description = "Each week I add best tracks I can think of."
playlist.add_track(
  :performer => "Jon Hopkins",
  :title => "Everything Connected"
)

track = Playlist::Track.new(:title => "Get Your Shirt")
track.add_contributor(:name => "Underworld", :role => :performer)
track.add_contributor(:name => "Iggy Pop", :role => :performer)
playlist.add_track(track)

Parsing a playlist file

The playlist gem supports a number of different playlist file formats. Here is an example of parsing a M3U file:

File.open("playlist.m3u") do |file|
  playlist = Playlist::Format::M3U.parse(file)
  puts "The playlist contains #{playlist.tracks.count} tracks"
end

Generating a playlist file

Having created a Playlist object, it can be converted to a playlist file using:

File.open("playlist.m3u", "wb") do |file|
  file.write Playlist::Format::M3U.generate(playlist)
end

Development

After checking out the repo, run bundle install to install dependencies. Then, run rake spec to run the tests.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/njh/ruby-playlist.

License

The gem is available as open source under the terms of the MIT License.

ruby-playlist's People

Contributors

njh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

sztheory

ruby-playlist's Issues

output to JSON ?

Hi, is there a way to output the tracklist as a JSON object, based, ideally, on the XSPF playlist (since it's a standard) ?

Thanks !

How to assign track links to Spotify/Youtube/... ?

Hi, could you add a :link property for tracks ?
it differs from the :location property, as seen on the XSPF specs :

4.1.1.2.14.1.1.1.1 location
URI of resource to be rendered. Probably an audio resource, but MAY be any type of resource with a well-known duration, such as video, a SMIL document, or an XSPF document. The duration of the resource defined in this element defines the duration of rendering. xspf:track elements MAY contain zero or more location elements, but a user-agent MUST NOT render more than one of the named resources.

4.1.1.2.14.1.1.1.11 link
The link element allows XSPF to be extended without the use of XML namespaces. xspf:track elements MAY contain zero or more link elements.

I would use this to define links to audio services (like Spotify, Youtube, Soundcloud), which are not really an audio ressource. + I need to be able to add several links.

Thanks a lot, again.

support for playlist/track metas

Hi, your gem is great because I need to convert playlists between several formats.
I've based my whole app on the XSPF/JSPF formats since they are standards.
But you don't currently support some of their properties, like playlist and track metas.
Would it be possible to include that ?

Thanks !

generating XSPF is broken ?

Hi again !
Looks like generating XSPF playlists is broken, the artist is missing in the output !

puts Playlist::Format::SimpleText.generate(playlist)

give me

Victor Wooten - Flip Flop (Bonus Track)

while

puts Playlist::Format::XSPF.generate(playlist)

gives me

<track>
  <title>Flip Flop (Bonus Track)</title>
  <album>A Show of Hands 15</album>
</track>

Any chance that you could fix this ?
Thanks a lot for your work !

"Internal Server Error" when trying to set identifiers for a track

Hi, I got a Internal Server Error when I'm trying to set the identifier attribute for a track ๐Ÿ‘

track = Playlist::Track.new(
  :artist =>      'U2',
  :title =>       'Sunday Bloody Sunday',
  :duration =>    '54321',
  :identifiers => {
                    "http://example.com/rel/1/" => "http://example.com/body/1/",
                    "http://example.com/rel/2/" => "http://example.com/body/2/"
                  }
)

It seems that it is related to the :identifier attribute, since it does work if I use :location instead.

"error": "Internal Server Error",
"exception": "#<NoMethodError: undefined method `identifiers=' for #<Playlist::Track:0x0000557337d59e40>\nDid you mean?  identifiers>",

"Framework Trace": [
{
"exception_object_id": 63840,
"id": 0,
"trace": "ruby-playlist (65154d8) lib/playlist/track.rb:68:in block in initialize'" }, { "exception_object_id": 63840, "id": 1, "trace": "ruby-playlist (65154d859585) lib/playlist/track.rb:67:in each_pair'"
},
{
"exception_object_id": 63840,
"id": 2,
"trace": "ruby-playlist (65154d8) lib/playlist/track.rb:67:in initialize'" }, { "exception_object_id": 63840, "id": 5, "trace": "actionpack (6.0.3.3) lib/action_controller/metal/basic_implicit_render.rb:6:in send_action'"
},
{
"exception_object_id": 63840,
"id": 6,
"trace": "actionpack (6.0.3.3) lib/abstract_controller/base.rb:195:in process_action'" }, { "exception_object_id": 63840, "id": 7, "trace": "actionpack (6.0.3.3) lib/action_controller/metal/rendering.rb:30:in process_action'"
},
{
"exception_object_id": 63840,
"id": 8,
"trace": "actionpack (6.0.3.3) lib/abstract_controller/callbacks.rb:42:in block in process_action'" }, { "exception_object_id": 63840, "id": 9, "trace": "activesupport (6.0.3.3) lib/active_support/callbacks.rb:101:in run_callbacks'"
},
{
"exception_object_id": 63840,
"id": 10,
"trace": "actionpack (6.0.3.3) lib/abstract_controller/callbacks.rb:41:in process_action'" }, { "exception_object_id": 63840, "id": 11, "trace": "actionpack (6.0.3.3) lib/action_controller/metal/rescue.rb:22:in process_action'"
},
{
"exception_object_id": 63840,
"id": 12,
"trace": "actionpack (6.0.3.3) lib/action_controller/metal/instrumentation.rb:33:in block in process_action'" }, { "exception_object_id": 63840, "id": 13, "trace": "activesupport (6.0.3.3) lib/active_support/notifications.rb:180:in block in instrument'"
},
{
"exception_object_id": 63840,
"id": 14,
"trace": "activesupport (6.0.3.3) lib/active_support/notifications/instrumenter.rb:24:in instrument'" }, { "exception_object_id": 63840, "id": 15, "trace": "activesupport (6.0.3.3) lib/active_support/notifications.rb:180:in instrument'"
},
{
"exception_object_id": 63840,
"id": 16,
"trace": "actionpack (6.0.3.3) lib/action_controller/metal/instrumentation.rb:32:in process_action'" }, { "exception_object_id": 63840, "id": 17, "trace": "actionpack (6.0.3.3) lib/action_controller/metal/params_wrapper.rb:245:in process_action'"
},
{
"exception_object_id": 63840,
"id": 18,
"trace": "activerecord (6.0.3.3) lib/active_record/railties/controller_runtime.rb:27:in process_action'" }, { "exception_object_id": 63840, "id": 19, "trace": "actionpack (6.0.3.3) lib/abstract_controller/base.rb:136:in process'"
},
{
"exception_object_id": 63840,
"id": 20,
"trace": "actionview (6.0.3.3) lib/action_view/rendering.rb:39:in process'" }, { "exception_object_id": 63840, "id": 21, "trace": "actionpack (6.0.3.3) lib/action_controller/metal.rb:190:in dispatch'"
},
{
"exception_object_id": 63840,
"id": 22,
"trace": "actionpack (6.0.3.3) lib/action_controller/metal.rb:254:in dispatch'" }, { "exception_object_id": 63840, "id": 23, "trace": "actionpack (6.0.3.3) lib/action_dispatch/routing/route_set.rb:50:in dispatch'"
},
{
"exception_object_id": 63840,
"id": 24,
"trace": "actionpack (6.0.3.3) lib/action_dispatch/routing/route_set.rb:33:in serve'" }, { "exception_object_id": 63840, "id": 25, "trace": "actionpack (6.0.3.3) lib/action_dispatch/journey/router.rb:49:in block in serve'"
},
{
"exception_object_id": 63840,
"id": 26,
"trace": "actionpack (6.0.3.3) lib/action_dispatch/journey/router.rb:32:in each'" }, { "exception_object_id": 63840, "id": 27, "trace": "actionpack (6.0.3.3) lib/action_dispatch/journey/router.rb:32:in serve'"
},
{
"exception_object_id": 63840,
"id": 28,
"trace": "actionpack (6.0.3.3) lib/action_dispatch/routing/route_set.rb:834:in call'" }, { "exception_object_id": 63840, "id": 29, "trace": "rack (2.2.3) lib/rack/etag.rb:27:in call'"
},
{
"exception_object_id": 63840,
"id": 30,
"trace": "rack (2.2.3) lib/rack/conditional_get.rb:40:in call'" }, { "exception_object_id": 63840, "id": 31, "trace": "rack (2.2.3) lib/rack/head.rb:12:in call'"
},
{
"exception_object_id": 63840,
"id": 32,
"trace": "activerecord (6.0.3.3) lib/active_record/migration.rb:567:in call'" }, { "exception_object_id": 63840, "id": 33, "trace": "actionpack (6.0.3.3) lib/action_dispatch/middleware/callbacks.rb:27:in block in call'"
},
{
"exception_object_id": 63840,
"id": 34,
"trace": "activesupport (6.0.3.3) lib/active_support/callbacks.rb:101:in run_callbacks'" }, { "exception_object_id": 63840, "id": 35, "trace": "actionpack (6.0.3.3) lib/action_dispatch/middleware/callbacks.rb:26:in call'"
},
{
"exception_object_id": 63840,
"id": 36,
"trace": "actionpack (6.0.3.3) lib/action_dispatch/middleware/executor.rb:14:in call'" }, { "exception_object_id": 63840, "id": 37, "trace": "actionpack (6.0.3.3) lib/action_dispatch/middleware/actionable_exceptions.rb:17:in call'"
},
{
"exception_object_id": 63840,
"id": 38,
"trace": "actionpack (6.0.3.3) lib/action_dispatch/middleware/debug_exceptions.rb:32:in call'" }, { "exception_object_id": 63840, "id": 39, "trace": "actionpack (6.0.3.3) lib/action_dispatch/middleware/show_exceptions.rb:33:in call'"
},
{
"exception_object_id": 63840,
"id": 40,
"trace": "railties (6.0.3.3) lib/rails/rack/logger.rb:37:in call_app'" }, { "exception_object_id": 63840, "id": 41, "trace": "railties (6.0.3.3) lib/rails/rack/logger.rb:26:in block in call'"
},
{
"exception_object_id": 63840,
"id": 42,
"trace": "activesupport (6.0.3.3) lib/active_support/tagged_logging.rb:80:in block in tagged'" }, { "exception_object_id": 63840, "id": 43, "trace": "activesupport (6.0.3.3) lib/active_support/tagged_logging.rb:28:in tagged'"
},
{
"exception_object_id": 63840,
"id": 44,
"trace": "activesupport (6.0.3.3) lib/active_support/tagged_logging.rb:80:in tagged'" }, { "exception_object_id": 63840, "id": 45, "trace": "railties (6.0.3.3) lib/rails/rack/logger.rb:26:in call'"
},
{
"exception_object_id": 63840,
"id": 46,
"trace": "actionpack (6.0.3.3) lib/action_dispatch/middleware/remote_ip.rb:81:in call'" }, { "exception_object_id": 63840, "id": 47, "trace": "actionpack (6.0.3.3) lib/action_dispatch/middleware/request_id.rb:27:in call'"
},
{
"exception_object_id": 63840,
"id": 48,
"trace": "rack (2.2.3) lib/rack/runtime.rb:22:in call'" }, { "exception_object_id": 63840, "id": 49, "trace": "activesupport (6.0.3.3) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in call'"
},
{
"exception_object_id": 63840,
"id": 50,
"trace": "actionpack (6.0.3.3) lib/action_dispatch/middleware/executor.rb:14:in call'" }, { "exception_object_id": 63840, "id": 51, "trace": "actionpack (6.0.3.3) lib/action_dispatch/middleware/static.rb:126:in call'"
},
{
"exception_object_id": 63840,
"id": 52,
"trace": "rack (2.2.3) lib/rack/sendfile.rb:110:in call'" }, { "exception_object_id": 63840, "id": 53, "trace": "actionpack (6.0.3.3) lib/action_dispatch/middleware/host_authorization.rb:82:in call'"
},
{
"exception_object_id": 63840,
"id": 54,
"trace": "rack-cors (1.1.1) lib/rack/cors.rb:100:in call'" }, { "exception_object_id": 63840, "id": 55, "trace": "railties (6.0.3.3) lib/rails/engine.rb:527:in call'"
},
{
"exception_object_id": 63840,
"id": 56,
"trace": "puma (4.3.6) lib/puma/configuration.rb:228:in call'" }, { "exception_object_id": 63840, "id": 57, "trace": "puma (4.3.6) lib/puma/server.rb:713:in handle_request'"
},
{
"exception_object_id": 63840,
"id": 58,
"trace": "puma (4.3.6) lib/puma/server.rb:472:in process_client'" }, { "exception_object_id": 63840, "id": 59, "trace": "puma (4.3.6) lib/puma/server.rb:328:in block in run'"
},
{
"exception_object_id": 63840,
"id": 60,
"trace": "puma (4.3.6) lib/puma/thread_pool.rb:134:in `block in spawn_thread'"
}
],

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.