Skip to content

Commit

Permalink
Add extensions to play from url
Browse files Browse the repository at this point in the history
  • Loading branch information
Him188 committed Dec 22, 2024
1 parent 9b37d11 commit 19e46a9
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 22 deletions.
30 changes: 30 additions & 0 deletions mediamp-api/src/androidMain/kotlin/MediampPlayer.android.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (C) 2024 OpenAni and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the Apache-2.0 license, which can be found at the following link.
*
* https://github.com/open-ani/mediamp/blob/main/LICENSE
*/

package org.openani.mediamp

import android.net.Uri
import android.os.Build
import androidx.annotation.RequiresApi
import java.nio.file.Path


/**
* Plays the video at the specified [uri].
*/
public suspend inline fun MediampPlayer.playUri(uri: Uri): Unit =
playUri(uri.toString())


/**
* Plays the file.
*/
@RequiresApi(Build.VERSION_CODES.O)
public suspend inline fun MediampPlayer.playFile(file: Path): Unit =
playUri(file.toUri().toString())
14 changes: 14 additions & 0 deletions mediamp-api/src/commonMain/kotlin/MediampPlayer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ import org.openani.mediamp.metadata.SubtitleTrack
import org.openani.mediamp.metadata.TrackGroup
import org.openani.mediamp.metadata.VideoProperties
import org.openani.mediamp.metadata.emptyTrackGroup
import org.openani.mediamp.source.MediaExtraFiles
import org.openani.mediamp.source.MediaSource
import org.openani.mediamp.source.UriMediaSource
import org.openani.mediamp.source.VideoData
import org.openani.mediamp.source.VideoSourceOpenException
import kotlin.coroutines.CoroutineContext
Expand Down Expand Up @@ -137,13 +139,15 @@ public interface MediampPlayer {
* Resumes playback.
*
* If there is no video source set, this function will do nothing.
* @see togglePause
*/
public fun resume()

/**
* Pauses playback.
*
* If there is no video source set, this function will do nothing.
* @see togglePause
*/
public fun pause()

Expand Down Expand Up @@ -186,6 +190,15 @@ public interface MediampPlayer {
public val features: PlayerFeatures
}

/**
* Plays the video at the specified [uri], e.g. a local file or a remote URL.
*/
public suspend fun MediampPlayer.playUri(uri: String): Unit =
setVideoSource(UriMediaSource(uri, emptyMap(), MediaExtraFiles()))

/**
* Toggles between [MediampPlayer.pause] and [MediampPlayer.resume] based on the current playback state.
*/
public fun MediampPlayer.togglePause() {
if (playbackState.value.isPlaying) {
pause()
Expand All @@ -194,6 +207,7 @@ public fun MediampPlayer.togglePause() {
}
}


@MediampInternalApi
public abstract class AbstractMediampPlayer<D : AbstractMediampPlayer.Data>(
parentCoroutineContext: CoroutineContext,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,23 @@ import org.openani.mediamp.internal.MediampInternalApi
import org.openani.mediamp.io.SeekableInput
import kotlin.coroutines.CoroutineContext

public open class HttpStreamingMediaSource(
public open class UriMediaSource(
override val uri: String,
private val filename: String,
public val headers: Map<String, String> = emptyMap(),
override val extraFiles: MediaExtraFiles,
) : MediaSource<HttpStreamingVideoData> {
override suspend fun open(): HttpStreamingVideoData {
return HttpStreamingVideoData(uri, filename)
) : MediaSource<UriVideoData> {
override suspend fun open(): UriVideoData {
return UriVideoData(uri)
}

override fun toString(): String {
return "HttpStreamingVideoSource(filename='$filename')"
return "HttpStreamingVideoSource(uri='$uri')"
}
}


public class HttpStreamingVideoData(
public class UriVideoData(
public val url: String,
override val filename: String
) : VideoData {
override fun fileLength(): Long? = null

Expand Down
3 changes: 0 additions & 3 deletions mediamp-api/src/commonMain/kotlin/source/VideoData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ import kotlin.coroutines.EmptyCoroutineContext
* Holds information about a video file.
*/
public interface VideoData {
public val filename: String

/**
* Returns the length of the video file in bytes, or `null` if not known.
*/
Expand Down Expand Up @@ -72,7 +70,6 @@ public class NetStats @MediampInternalApi public constructor(
public fun emptyVideoData(): VideoData = EmptyVideoData

private object EmptyVideoData : VideoData {
override val filename: String get() = ""
override fun fileLength(): Long? = null

@OptIn(MediampInternalApi::class)
Expand Down
18 changes: 18 additions & 0 deletions mediamp-api/src/desktopMain/kotlin/MediampPlayer.desktop.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright (C) 2024 OpenAni and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the Apache-2.0 license, which can be found at the following link.
*
* https://github.com/open-ani/mediamp/blob/main/LICENSE
*/

package org.openani.mediamp

import java.nio.file.Path

/**
* Plays the file.
*/
public suspend inline fun MediampPlayer.playFile(file: Path): Unit =
playUri(file.toUri().toString())
34 changes: 34 additions & 0 deletions mediamp-api/src/jvmMain/kotlin/MediampPlayer.jvm.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (C) 2024 OpenAni and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the Apache-2.0 license, which can be found at the following link.
*
* https://github.com/open-ani/mediamp/blob/main/LICENSE
*/

package org.openani.mediamp

import java.io.File
import java.net.URI
import java.net.URL

/**
* Plays the video at the specified [uri].
*/
public suspend inline fun MediampPlayer.playUri(uri: URI): Unit =
playUri(uri.toString())

/**
* Plays the video at the specified [url].
*/
public suspend inline fun MediampPlayer.playUri(url: URL): Unit =
playUri(url.toString())


/**
* Plays the file.
*/
public suspend fun MediampPlayer.playFile(file: File) {
playUri(file.toURI().toString())
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ import org.openani.mediamp.metadata.Chapter
import org.openani.mediamp.metadata.SubtitleTrack
import org.openani.mediamp.metadata.TrackLabel
import org.openani.mediamp.metadata.VideoProperties
import org.openani.mediamp.source.HttpStreamingMediaSource
import org.openani.mediamp.source.MediaSource
import org.openani.mediamp.source.UriMediaSource
import org.openani.mediamp.source.VideoData
import org.openani.mediamp.source.emptyVideoData
import kotlin.coroutines.CoroutineContext
Expand Down Expand Up @@ -134,7 +134,7 @@ class ExoPlayerMediampPlayer @UiThread constructor(
}

override suspend fun openSource(source: MediaSource<*>): ExoPlayerData {
if (source is HttpStreamingMediaSource) {
if (source is UriMediaSource) {
return ExoPlayerData(
source,
emptyVideoData(),
Expand Down Expand Up @@ -429,7 +429,7 @@ class ExoPlayerMediampPlayer @UiThread constructor(
format.metadata
this.yield(
SubtitleTrack(
"${openResource.value?.videoData?.filename}-${mediaTrackGroup.id}-$index",
"${mediaTrackGroup.id}-$index",
mediaTrackGroup.id,
firstLabel ?: mediaTrackGroup.id,
format.labels.map { TrackLabel(it.language, it.value) },
Expand All @@ -445,7 +445,7 @@ class ExoPlayerMediampPlayer @UiThread constructor(
format.metadata
this.yield(
AudioTrack(
"${openResource.value?.videoData?.filename}-${mediaTrackGroup.id}-$index",
"${mediaTrackGroup.id}-$index",
mediaTrackGroup.id,
firstLabel ?: mediaTrackGroup.id,
format.labels.map { TrackLabel(it.language, it.value) },
Expand Down
8 changes: 4 additions & 4 deletions mediamp-backend-vlc/src/main/kotlin/VlcVideoMediampPlayer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ import org.openani.mediamp.metadata.SubtitleTrack
import org.openani.mediamp.metadata.TrackGroup
import org.openani.mediamp.metadata.TrackLabel
import org.openani.mediamp.metadata.VideoProperties
import org.openani.mediamp.source.HttpStreamingMediaSource
import org.openani.mediamp.source.MediaSource
import org.openani.mediamp.source.UriMediaSource
import org.openani.mediamp.source.VideoData
import org.openani.mediamp.source.emptyVideoData
import uk.co.caprica.vlcj.factory.MediaPlayerFactory
Expand Down Expand Up @@ -135,7 +135,7 @@ class VlcVideoMediampPlayer(parentCoroutineContext: CoroutineContext) : MediampP
) : Data(mediaSource, videoData, releaseResource)

override suspend fun openSource(source: MediaSource<*>): VlcjData {
if (source is HttpStreamingMediaSource) {
if (source is UriMediaSource) {
return VlcjData(
source,
emptyVideoData(),
Expand Down Expand Up @@ -420,7 +420,7 @@ class VlcVideoMediampPlayer(parentCoroutineContext: CoroutineContext) : MediampP
.filterNot { it.id() == -1 } // "Disable"
.map {
SubtitleTrack(
openResource.value?.videoData?.filename + "-" + it.id(),
it.id().toString(),
it.id().toString(),
null,
listOf(TrackLabel(null, it.description())),
Expand All @@ -438,7 +438,7 @@ class VlcVideoMediampPlayer(parentCoroutineContext: CoroutineContext) : MediampP
.filterNot { it.id() == -1 } // "Disable"
.map {
AudioTrack(
openResource.value?.videoData?.filename + "-" + it.id(),
it.id().toString(),
it.id().toString(),
null,
listOf(TrackLabel(null, it.description())),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ public class SystemFileVideoData(
public val file: Path,
private val bufferSize: Int = 8 * 1024,
) : VideoData {
override val filename: String
get() = file.name

override fun fileLength(): Long? = SystemFileSystem.metadataOrNull(file)?.size

@OptIn(MediampInternalApi::class)
Expand Down

0 comments on commit 19e46a9

Please sign in to comment.