Giter Site home page Giter Site logo

m3u-parser's Introduction

m3u-parser

GitHub (pre-)release GitHub license Main Maintainability Rating codecov

A parser for simple and extended M3U playlist files written in Kotlin.

This parser can also be used in Java projects.

Due to the underspecified nature of the M3U format, the parser tries to accept all files it gets, as weird as they may are. This especially includes extended M3U files with missing "#EXTM3U" headers and mixed extended/simple files.

Dependency configuration

The library is available in Maven Central. Java 8 or higher is required to use it.

Gradle

Kotlin DSL

build.gradle.kts

dependencies {
    implementation("com.github.bjoernpetersen:m3u-parser:$m3uParserVersion")
    // or
    implementation(
        group = "com.github.bjoernpetersen",
        name = "m3u-parser",
        version = "$m3uParserVersion",
    )
}

Groovy DSL

build.gradle

dependencies {
    implementation "com.github.bjoernpetersen:m3u-parser:$m3uParserVersion"
}

Maven

pom.xml

<dependency>
    <groupId>com.github.bjoernpetersen</groupId>
    <artifactId>m3u-parser</artifactId>
    <version>${m3uParser.version}</version>
</dependency>

Usage

// Simply pass in a file
val m3uFile = Paths.get("myplaylist.m3u")
val fileEntries: List<M3uEntry> = M3uParser.parse(m3uFile)

// You may also pass in an InputStreamReader
val m3uStream: InputStream = javaClass.getResourceAsStream("myplaylist.m3u")
val m3uReader: InputStreamReader = m3uStream.reader()
val streamEntries: List<M3uEntry> = M3uParser.parse(m3uReader)

// Passing in the content of an M3U file as a String also works
val someApi = TODO("Not a real API object")
// Returns a playlist in the M3U format
val m3uContent: String = someApi.getPlaylist("Best of Willy Astor")
val entries: List<M3uEntry> = M3uParser.parse(m3uContent)

Nested playlists

If your M3U file contains the path of another playlist file

MyPlaylist.m3u

AnotherPlayList.m3u

then you'll get a M3uEntry with a MediaPath location for that file. To get the contents of that playlist, you'll need to pass it to the parser again:

val nestedM3uLocation: MediaPath = TODO("...")
M3uParser.parse(nestedM3uLocation.path)

You can use the M3uParser.resolveNestedPlaylists() method to recursively parse all nested playlist file references:

val entries: List<M3uEntry> = M3uParser.parse(Paths.get("playlist.m3u"))
// Doesn't contain any .m3u file references anymore
val resolvedEntries: List<M3uEntry> = M3uParser.resolveNestedPlaylists(entries)

License

This project is released under the MIT License. That includes every file in this repository, unless explicitly stated otherwise at the top of a file. A copy of the license text can be found in the LICENSE file.

m3u-parser's People

Contributors

bjoernpetersen avatar oxyroid avatar renovate-bot avatar renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

m3u-parser's Issues

Cannot get it to import properly

Discussed in #49

Originally posted by jleohr February 8, 2022
My students and I are a little new to Android Studio and Kotlin as a language. They are attempting to create an app that will play sound files when buttons are clicked. Everything we've read points to using M3U files and your project is the only thing we can find that might work for us. However, when we attempt to open the downloaded Git repository there is not an interface for the Android device. We decided we needed to import it into our existing project but when we do it results in errors that we have Unresolved reference: libs. Any suggestions of what we might be doing wrong?

Introduce parseHead

It would be great to parse also header information (metadata) if available.
E.g.
#EXTM3U url-tvg="http://toplevel.domain/epg/epgfull.xml.gz"

Maybe I will be able to create a PR for this.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Awaiting Schedule

These updates are awaiting their schedule. Click on a checkbox to get an update now.

  • chore(deps): lock file maintenance

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Vulnerabilities

Renovate has not found any CVEs on osv.dev.

Detected dependencies

github-actions
.github/workflows/Main.yaml
  • actions/checkout v4
  • actions/setup-java v4
  • codecov/codecov-action v3
  • actions/checkout v4
  • actions/setup-java v4
  • actions/cache v4
gradle
settings.gradle.kts
build.gradle.kts
  • org.jetbrains.kotlin.jvm 1.9.23
gradle/libs.versions.toml
  • org.assertj:assertj-core 3.25.3
  • org.junit.jupiter:junit-jupiter-api 5.10.2
  • org.junit.jupiter:junit-jupiter-engine 5.10.2
  • org.junit.platform:junit-platform-launcher 1.10.2
  • io.github.oshai:kotlin-logging 6.0.9
  • org.slf4j:slf4j-api 2.0.13
  • org.slf4j:slf4j-simple 2.0.13
  • io.gitlab.arturbosch.detekt 1.23.6
  • org.jetbrains.dokka 1.9.20
  • com.diffplug.spotless 6.25.0
  • org.sonarqube 4.4.1.3373
  • com.github.ben-manes.versions 0.51.0
gradle-wrapper
gradle/wrapper/gradle-wrapper.properties
  • gradle 8.6

  • Check this box to trigger a request for Renovate to run again on this repository

Add more return types support

Hi, nice parser.
I have used it as my android app's default m3u parser.
But I think adding some other return types like Flow, Sequence etc is necessary.

Improve charset handling

Loading m3u playlists from a file requires the file's content to be decoded using a Charset. Currently the user can specify a Charset for decoding, otherwise the parser defaults to UTF-8.

Instead of expecting the user to choose a Charset, the parser should default to the local system's default non-Unicode encoding for .m3u files and UTF-8 for .m3u8 files.

As always, we can't expect all .m3u files to follow the "convention" of using the local system's encoding, so we should detect signals of having used the wrong Charset and then fall back to UTF-8 anyway.

Users should still be able to completely override this "auto detection".

Error "Retrieving groups by name is not supported on this platform"

Hi!

I'm using this library for future new function in my project FeedTV, and when I parse the M3U file, I get an exception with the error "Retrieving groups by name is not supported on this platform".

2022-01-06 00:53:17.341 7411-7411/org.juanro.feedtv E/AndroidRuntime: FATAL EXCEPTION: main Process: org.juanro.feedtv, PID: 7411 java.lang.UnsupportedOperationException: Retrieving groups by name is not supported on this platform. at kotlin.internal.PlatformImplementations.getMatchResultNamedGroup(PlatformImplementations.kt:42) at kotlin.text.MatcherMatchResult$groups$1.get(Regex.kt:372) at kotlin.text.jdk8.RegexExtensionsJDK8Kt.get(RegexExtensions.kt:34) at net.bjoernpetersen.m3u.M3uParser.parseExtended(M3uParser.kt:166) at net.bjoernpetersen.m3u.M3uParser.parse(M3uParser.kt:137) at net.bjoernpetersen.m3u.M3uParser.parse(M3uParser.kt:54) at net.bjoernpetersen.m3u.M3uParser.parse$default(M3uParser.kt:52) at net.bjoernpetersen.m3u.M3uParser.parse(Unknown Source:2) at org.juanro.feedtv.M3UParser$1.onResponse(M3UParser.java:150) at org.juanro.feedtv.M3UParser$1.onResponse(M3UParser.java:125) at org.juanro.feedtv.Http.InputStreamVolleyRequest.deliverResponse(InputStreamVolleyRequest.java:57) at org.juanro.feedtv.Http.InputStreamVolleyRequest.deliverResponse(InputStreamVolleyRequest.java:29) at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:102) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7839) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

It seems to be because of using name groups in Regex (seconds and title)

private const val EXTENDED_INFO = """${COMMENT_START}EXTINF:(?<$SECONDS>[-]?\d+).*,(?<$TITLE>.+)"""

I'm using this version:
implementation "com.github.bjoernpetersen:m3u-parser:1.1.0"

Suggestion: Add logo to M3uEntry model

Hi!

First, thank you for resolving the issue #42 ๐Ÿ˜Š . I have a suggestion that I don't know if it could be implemented, which is to add the logo (and optionally, the group) to the M3uEntry model.

The logo is usually defined in the tvg-logo tag of the line (and group in group-title)
2022-01-06_19-16

Thank you very much for your effort!

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.