skip credits
This commit is contained in:
parent
015ddd19bd
commit
92eaefe6e1
38 changed files with 194 additions and 35 deletions
|
@ -32,6 +32,7 @@ import androidx.media3.ui.DefaultTimeBar
|
|||
import androidx.media3.ui.PlayerView
|
||||
import androidx.navigation.navArgs
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.databinding.ActivityPlayerBinding
|
||||
import dev.jdtech.jellyfin.dialogs.SpeedSelectionDialogFragment
|
||||
import dev.jdtech.jellyfin.dialogs.TrackSelectionDialogFragment
|
||||
|
@ -136,10 +137,15 @@ class PlayerActivity : BasePlayerActivity() {
|
|||
videoNameTextView.text = currentItemTitle
|
||||
|
||||
// Skip Intro button
|
||||
skipIntroButton.isVisible = !isInPictureInPictureMode && currentIntro != null
|
||||
skipIntroButton.isVisible = !isInPictureInPictureMode && (currentIntro != null || currentCredit != null)
|
||||
skipIntroButton.text = if (currentCredit != null) getString(CoreR.string.skip_credit_button) else getString(CoreR.string.skip_intro_button)
|
||||
skipIntroButton.setOnClickListener {
|
||||
currentIntro?.let {
|
||||
binding.playerView.player?.seekTo((it.introEnd * 1000).toLong())
|
||||
if (currentIntro != null) {
|
||||
currentIntro?.let {
|
||||
binding.playerView.player?.seekTo((it.introEnd * 1000).toLong())
|
||||
}
|
||||
} else if (currentCredit != null) {
|
||||
binding.playerView.player?.seekToNext()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,6 @@
|
|||
android:layout_gravity="end|bottom"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:layout_marginBottom="64dp"
|
||||
android:text="@string/player_controls_skip_intro"
|
||||
android:textColor="@android:color/white"
|
||||
android:visibility="gone"
|
||||
app:backgroundTint="@color/player_background"
|
||||
|
|
|
@ -15,6 +15,7 @@ import dev.jdtech.jellyfin.models.FindroidMovie
|
|||
import dev.jdtech.jellyfin.models.FindroidSource
|
||||
import dev.jdtech.jellyfin.models.TrickPlayManifest
|
||||
import dev.jdtech.jellyfin.models.UiText
|
||||
import dev.jdtech.jellyfin.models.toCreditDto
|
||||
import dev.jdtech.jellyfin.models.toFindroidEpisodeDto
|
||||
import dev.jdtech.jellyfin.models.toFindroidMediaStreamDto
|
||||
import dev.jdtech.jellyfin.models.toFindroidMovieDto
|
||||
|
@ -46,6 +47,7 @@ class DownloaderImpl(
|
|||
try {
|
||||
val source = jellyfinRepository.getMediaSources(item.id, true).first { it.id == sourceId }
|
||||
val intro = jellyfinRepository.getIntroTimestamps(item.id)
|
||||
val credit = jellyfinRepository.getCreditTimestamps(item.id)
|
||||
val trickPlayManifest = jellyfinRepository.getTrickPlayManifest(item.id)
|
||||
val trickPlayData = if (trickPlayManifest != null) {
|
||||
jellyfinRepository.getTrickPlayData(
|
||||
|
@ -81,6 +83,9 @@ class DownloaderImpl(
|
|||
if (intro != null) {
|
||||
database.insertIntro(intro.toIntroDto(item.id))
|
||||
}
|
||||
if (credit != null) {
|
||||
database.insertCredit(credit.toCreditDto(item.id))
|
||||
}
|
||||
if (trickPlayManifest != null && trickPlayData != null) {
|
||||
downloadTrickPlay(item, trickPlayManifest, trickPlayData)
|
||||
}
|
||||
|
@ -110,6 +115,9 @@ class DownloaderImpl(
|
|||
if (intro != null) {
|
||||
database.insertIntro(intro.toIntroDto(item.id))
|
||||
}
|
||||
if (credit != null) {
|
||||
database.insertCredit(credit.toCreditDto(item.id))
|
||||
}
|
||||
if (trickPlayManifest != null && trickPlayData != null) {
|
||||
downloadTrickPlay(item, trickPlayManifest, trickPlayData)
|
||||
}
|
||||
|
|
|
@ -185,4 +185,6 @@
|
|||
<string name="live_tv">Diretta TV</string>
|
||||
<string name="play">Riproduci</string>
|
||||
<string name="remove_from_favorites">Rimuovi dai preferiti</string>
|
||||
<string name="skip_intro_button">Salta intro</string>
|
||||
<string name="skip_credit_button">Prossimo episodio</string>
|
||||
</resources>
|
|
@ -140,9 +140,9 @@
|
|||
<string name="pref_player_mpv_vo">Video output</string>
|
||||
<string name="pref_player_mpv_ao">Audio output</string>
|
||||
<string name="pref_player_intro_skipper">Intro Skipper</string>
|
||||
<string name="pref_player_intro_skipper_summary">Requires ConfusedPolarBear\'s Intro Skipper plugin to be installed on the server</string>
|
||||
<string name="pref_player_intro_skipper_summary">Requires <i>ConfusedPolarBear\'s</i> <b>Intro Skipper</b> plugin to be installed on the server.\nInstall <i>jumoog\'s</i> <b>Intro Skipper v0.1.8 or higher</b> to skip end credits.</string>
|
||||
<string name="pref_player_trick_play">Trick Play</string>
|
||||
<string name="pref_player_trick_play_summary">Requires nicknsy\'s Jellyscrub plugin to be installed on the server</string>
|
||||
<string name="pref_player_trick_play_summary">Requires <i>nicknsy\'s</i> <b>Jellyscrub</b> plugin to be installed on the server</string>
|
||||
<string name="addresses">Addresses</string>
|
||||
<string name="add_address">Add address</string>
|
||||
<string name="add_server_address">Add server address</string>
|
||||
|
@ -185,4 +185,6 @@
|
|||
<string name="unmark_as_played">Unmark as played</string>
|
||||
<string name="add_to_favorites">Add to favorites</string>
|
||||
<string name="remove_from_favorites">Remove from favorites</string>
|
||||
<string name="skip_intro_button">Skip Intro</string>
|
||||
<string name="skip_credit_button">Next episode</string>
|
||||
</resources>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 3,
|
||||
"identityHash": "3cb9aaa3295b9e461cb94dfc708258ed",
|
||||
"identityHash": "2611f255654b3d481be40f080a8b5401",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "servers",
|
||||
|
@ -758,6 +758,50 @@
|
|||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "credits",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`itemId` TEXT NOT NULL, `start` REAL NOT NULL, `end` REAL NOT NULL, `showAt` REAL NOT NULL, `hideAt` REAL NOT NULL, PRIMARY KEY(`itemId`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "itemId",
|
||||
"columnName": "itemId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "start",
|
||||
"columnName": "start",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "end",
|
||||
"columnName": "end",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "showAt",
|
||||
"columnName": "showAt",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "hideAt",
|
||||
"columnName": "hideAt",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"itemId"
|
||||
]
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "userdata",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`userId` TEXT NOT NULL, `itemId` TEXT NOT NULL, `played` INTEGER NOT NULL, `favorite` INTEGER NOT NULL, `playbackPositionTicks` INTEGER NOT NULL, `toBeSynced` INTEGER NOT NULL, PRIMARY KEY(`userId`, `itemId`))",
|
||||
|
@ -813,7 +857,7 @@
|
|||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '3cb9aaa3295b9e461cb94dfc708258ed')"
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '2611f255654b3d481be40f080a8b5401')"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import androidx.room.AutoMigration
|
|||
import androidx.room.Database
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.room.TypeConverters
|
||||
import dev.jdtech.jellyfin.models.CreditDto
|
||||
import dev.jdtech.jellyfin.models.FindroidEpisodeDto
|
||||
import dev.jdtech.jellyfin.models.FindroidMediaStreamDto
|
||||
import dev.jdtech.jellyfin.models.FindroidMovieDto
|
||||
|
@ -18,7 +19,7 @@ import dev.jdtech.jellyfin.models.TrickPlayManifestDto
|
|||
import dev.jdtech.jellyfin.models.User
|
||||
|
||||
@Database(
|
||||
entities = [Server::class, ServerAddress::class, User::class, FindroidMovieDto::class, FindroidShowDto::class, FindroidSeasonDto::class, FindroidEpisodeDto::class, FindroidSourceDto::class, FindroidMediaStreamDto::class, TrickPlayManifestDto::class, IntroDto::class, FindroidUserDataDto::class],
|
||||
entities = [Server::class, ServerAddress::class, User::class, FindroidMovieDto::class, FindroidShowDto::class, FindroidSeasonDto::class, FindroidEpisodeDto::class, FindroidSourceDto::class, FindroidMediaStreamDto::class, TrickPlayManifestDto::class, IntroDto::class, CreditDto::class, FindroidUserDataDto::class],
|
||||
version = 3,
|
||||
autoMigrations = [
|
||||
AutoMigration(from = 2, to = 3),
|
||||
|
|
|
@ -6,6 +6,7 @@ import androidx.room.OnConflictStrategy
|
|||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import androidx.room.Update
|
||||
import dev.jdtech.jellyfin.models.CreditDto
|
||||
import dev.jdtech.jellyfin.models.FindroidEpisodeDto
|
||||
import dev.jdtech.jellyfin.models.FindroidMediaStreamDto
|
||||
import dev.jdtech.jellyfin.models.FindroidMovieDto
|
||||
|
@ -222,6 +223,15 @@ interface ServerDatabaseDao {
|
|||
@Query("DELETE FROM intros WHERE itemId = :itemId")
|
||||
fun deleteIntro(itemId: UUID)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insertCredit(credit: CreditDto)
|
||||
|
||||
@Query("SELECT * FROM credits WHERE itemId = :itemId")
|
||||
fun getCredit(itemId: UUID): CreditDto?
|
||||
|
||||
@Query("DELETE FROM credits WHERE itemId = :itemId")
|
||||
fun deleteCredit(itemId: UUID)
|
||||
|
||||
@Query("SELECT * FROM seasons")
|
||||
fun getSeasons(): List<FindroidSeasonDto>
|
||||
|
||||
|
|
33
data/src/main/java/dev/jdtech/jellyfin/models/Credit.kt
Normal file
33
data/src/main/java/dev/jdtech/jellyfin/models/Credit.kt
Normal file
|
@ -0,0 +1,33 @@
|
|||
package dev.jdtech.jellyfin.models
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class Credit(
|
||||
@SerialName("Credits")
|
||||
val credit: Credits,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Credits(
|
||||
@SerialName("IntroStart")
|
||||
val introStart: Double,
|
||||
@SerialName("IntroEnd")
|
||||
val introEnd: Double,
|
||||
@SerialName("ShowSkipPromptAt")
|
||||
val showSkipPromptAt: Double,
|
||||
@SerialName("HideSkipPromptAt")
|
||||
val hideSkipPromptAt: Double,
|
||||
)
|
||||
|
||||
fun CreditDto.toCredit(): Credit {
|
||||
return Credit(
|
||||
credit = Credits(
|
||||
introStart = start,
|
||||
introEnd = end,
|
||||
showSkipPromptAt = showAt,
|
||||
hideSkipPromptAt = hideAt,
|
||||
)
|
||||
)
|
||||
}
|
25
data/src/main/java/dev/jdtech/jellyfin/models/CreditDto.kt
Normal file
25
data/src/main/java/dev/jdtech/jellyfin/models/CreditDto.kt
Normal file
|
@ -0,0 +1,25 @@
|
|||
package dev.jdtech.jellyfin.models
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import java.util.UUID
|
||||
|
||||
@Entity(tableName = "credits")
|
||||
data class CreditDto(
|
||||
@PrimaryKey
|
||||
val itemId: UUID,
|
||||
val start: Double,
|
||||
val end: Double,
|
||||
val showAt: Double,
|
||||
val hideAt: Double,
|
||||
)
|
||||
|
||||
fun Credit.toCreditDto(itemId: UUID): CreditDto {
|
||||
return CreditDto(
|
||||
itemId = itemId,
|
||||
start = credit.introStart,
|
||||
end = credit.introEnd,
|
||||
showAt = credit.showSkipPromptAt,
|
||||
hideAt = credit.hideSkipPromptAt,
|
||||
)
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package dev.jdtech.jellyfin.repository
|
||||
|
||||
import androidx.paging.PagingData
|
||||
import dev.jdtech.jellyfin.models.Credit
|
||||
import dev.jdtech.jellyfin.models.FindroidCollection
|
||||
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||
import dev.jdtech.jellyfin.models.FindroidItem
|
||||
|
@ -86,6 +87,8 @@ interface JellyfinRepository {
|
|||
|
||||
suspend fun getIntroTimestamps(itemId: UUID): Intro?
|
||||
|
||||
suspend fun getCreditTimestamps(itemId: UUID): Credit?
|
||||
|
||||
suspend fun getTrickPlayManifest(itemId: UUID): TrickPlayManifest?
|
||||
|
||||
suspend fun getTrickPlayData(itemId: UUID, width: Int): ByteArray?
|
||||
|
|
|
@ -7,6 +7,7 @@ import androidx.paging.PagingData
|
|||
import dev.jdtech.jellyfin.AppPreferences
|
||||
import dev.jdtech.jellyfin.api.JellyfinApi
|
||||
import dev.jdtech.jellyfin.database.ServerDatabaseDao
|
||||
import dev.jdtech.jellyfin.models.Credit
|
||||
import dev.jdtech.jellyfin.models.FindroidCollection
|
||||
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||
import dev.jdtech.jellyfin.models.FindroidItem
|
||||
|
@ -17,6 +18,7 @@ import dev.jdtech.jellyfin.models.FindroidSource
|
|||
import dev.jdtech.jellyfin.models.Intro
|
||||
import dev.jdtech.jellyfin.models.SortBy
|
||||
import dev.jdtech.jellyfin.models.TrickPlayManifest
|
||||
import dev.jdtech.jellyfin.models.toCredit
|
||||
import dev.jdtech.jellyfin.models.toFindroidCollection
|
||||
import dev.jdtech.jellyfin.models.toFindroidEpisode
|
||||
import dev.jdtech.jellyfin.models.toFindroidItem
|
||||
|
@ -372,6 +374,28 @@ class JellyfinRepositoryImpl(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun getCreditTimestamps(itemId: UUID): Credit? =
|
||||
withContext(Dispatchers.IO) {
|
||||
val credit = database.getCredit(itemId)?.toCredit()
|
||||
|
||||
if (credit != null) {
|
||||
return@withContext credit
|
||||
}
|
||||
|
||||
// https://github.com/ConfusedPolarBear/intro-skipper/blob/master/docs/api.md
|
||||
val pathParameters = mutableMapOf<String, UUID>()
|
||||
pathParameters["itemId"] = itemId
|
||||
|
||||
try {
|
||||
return@withContext jellyfinApi.api.get<Credit>(
|
||||
"/Episode/{itemId}/IntroSkipperSegments",
|
||||
pathParameters,
|
||||
).content
|
||||
} catch (e: Exception) {
|
||||
return@withContext null
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTrickPlayManifest(itemId: UUID): TrickPlayManifest? =
|
||||
withContext(Dispatchers.IO) {
|
||||
val trickPlayManifest = database.getTrickPlayManifest(itemId)
|
||||
|
|
|
@ -5,6 +5,7 @@ import androidx.paging.PagingData
|
|||
import dev.jdtech.jellyfin.AppPreferences
|
||||
import dev.jdtech.jellyfin.api.JellyfinApi
|
||||
import dev.jdtech.jellyfin.database.ServerDatabaseDao
|
||||
import dev.jdtech.jellyfin.models.Credit
|
||||
import dev.jdtech.jellyfin.models.FindroidCollection
|
||||
import dev.jdtech.jellyfin.models.FindroidEpisode
|
||||
import dev.jdtech.jellyfin.models.FindroidItem
|
||||
|
@ -15,6 +16,7 @@ import dev.jdtech.jellyfin.models.FindroidSource
|
|||
import dev.jdtech.jellyfin.models.Intro
|
||||
import dev.jdtech.jellyfin.models.SortBy
|
||||
import dev.jdtech.jellyfin.models.TrickPlayManifest
|
||||
import dev.jdtech.jellyfin.models.toCredit
|
||||
import dev.jdtech.jellyfin.models.toFindroidEpisode
|
||||
import dev.jdtech.jellyfin.models.toFindroidMovie
|
||||
import dev.jdtech.jellyfin.models.toFindroidSeason
|
||||
|
@ -184,6 +186,11 @@ class JellyfinRepositoryOfflineImpl(
|
|||
database.getIntro(itemId)?.toIntro()
|
||||
}
|
||||
|
||||
override suspend fun getCreditTimestamps(itemId: UUID): Credit? =
|
||||
withContext(Dispatchers.IO) {
|
||||
database.getCredit(itemId)?.toCredit()
|
||||
}
|
||||
|
||||
override suspend fun getTrickPlayManifest(itemId: UUID): TrickPlayManifest? =
|
||||
withContext(Dispatchers.IO) {
|
||||
database.getTrickPlayManifest(itemId)?.toTrickPlayManifest()
|
||||
|
|
|
@ -18,6 +18,8 @@ import androidx.media3.exoplayer.ExoPlayer
|
|||
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dev.jdtech.jellyfin.AppPreferences
|
||||
import dev.jdtech.jellyfin.models.Credit
|
||||
import dev.jdtech.jellyfin.models.Credits
|
||||
import dev.jdtech.jellyfin.models.Intro
|
||||
import dev.jdtech.jellyfin.models.PlayerItem
|
||||
import dev.jdtech.jellyfin.mpv.MPVPlayer
|
||||
|
@ -55,6 +57,7 @@ constructor(
|
|||
UiState(
|
||||
currentItemTitle = "",
|
||||
currentIntro = null,
|
||||
currentCredit = null,
|
||||
currentTrickPlay = null,
|
||||
fileLoaded = false,
|
||||
),
|
||||
|
@ -65,12 +68,14 @@ constructor(
|
|||
val eventsChannelFlow = eventsChannel.receiveAsFlow()
|
||||
|
||||
private val intros: MutableMap<UUID, Intro> = mutableMapOf()
|
||||
private val credits: MutableMap<UUID, Credits> = mutableMapOf()
|
||||
|
||||
private val trickPlays: MutableMap<UUID, BifData> = mutableMapOf()
|
||||
|
||||
data class UiState(
|
||||
val currentItemTitle: String,
|
||||
val currentIntro: Intro?,
|
||||
val currentCredit: Credits?,
|
||||
val currentTrickPlay: BifData?,
|
||||
val fileLoaded: Boolean,
|
||||
)
|
||||
|
@ -152,6 +157,9 @@ constructor(
|
|||
jellyfinRepository.getIntroTimestamps(item.itemId)?.let { intro ->
|
||||
intros[item.itemId] = intro
|
||||
}
|
||||
jellyfinRepository.getCreditTimestamps(item.itemId)?.let { credit ->
|
||||
credits[item.itemId] = credit.credit
|
||||
}
|
||||
}
|
||||
|
||||
Timber.d("Stream url: $streamUrl")
|
||||
|
@ -241,10 +249,11 @@ constructor(
|
|||
handler.postDelayed(this, 5000L)
|
||||
}
|
||||
}
|
||||
val introCheckRunnable = object : Runnable {
|
||||
val skipCheckRunnable = object : Runnable {
|
||||
override fun run() {
|
||||
if (player.currentMediaItem != null && player.currentMediaItem!!.mediaId.isNotEmpty()) {
|
||||
val itemId = UUID.fromString(player.currentMediaItem!!.mediaId)
|
||||
|
||||
intros[itemId]?.let { intro ->
|
||||
val seconds = player.currentPosition / 1000.0
|
||||
if (seconds > intro.showSkipPromptAt && seconds < intro.hideSkipPromptAt) {
|
||||
|
@ -253,12 +262,22 @@ constructor(
|
|||
}
|
||||
_uiState.update { it.copy(currentIntro = null) }
|
||||
}
|
||||
|
||||
credits[itemId]?.let { credit ->
|
||||
val seconds = player.currentPosition / 1000.0
|
||||
if (seconds > credit.showSkipPromptAt && seconds < credit.hideSkipPromptAt) {
|
||||
_uiState.update { it.copy(currentCredit = credit) }
|
||||
return@let
|
||||
}
|
||||
_uiState.update { it.copy(currentCredit = null) }
|
||||
}
|
||||
}
|
||||
|
||||
handler.postDelayed(this, 1000L)
|
||||
}
|
||||
}
|
||||
handler.post(playbackProgressRunnable)
|
||||
if (intros.isNotEmpty()) handler.post(introCheckRunnable)
|
||||
if (intros.isNotEmpty()) handler.post(skipCheckRunnable)
|
||||
}
|
||||
|
||||
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
<string name="player_controls_rewind">Rebobinar</string>>
|
||||
<string name="player_controls_exit">Salir de reproductor</string>
|
||||
<string name="player_controls_fast_forward">Avanzar</string>
|
||||
<string name="player_controls_skip_intro">Saltar intro</string>
|
||||
<string name="external">Externo</string>
|
||||
<string name="player_controls_skip_back">Saltar atrás</string>
|
||||
<string name="player_controls_play_pause">Reproducir pausar</string>
|
||||
|
|
|
@ -14,6 +14,5 @@
|
|||
<string name="player_trickplay">Truques</string>
|
||||
<string name="player_controls_play_pause">Pausa na reprodução</string>
|
||||
<string name="player_controls_exit">Sair do reprodutor</string>
|
||||
<string name="player_controls_skip_intro">Pular introdução</string>
|
||||
<string name="player_controls_picture_in_picture">Insira imagem em imagem</string>
|
||||
</resources>
|
|
@ -9,7 +9,6 @@
|
|||
<string name="player_controls_skip_back">Přeskočit zpět</string>
|
||||
<string name="player_controls_play_pause">Přehrát pauza</string>
|
||||
<string name="player_controls_rewind">Přetočit</string>
|
||||
<string name="player_controls_skip_intro">Přeskočit úvod</string>
|
||||
<string name="player_controls_exit">Ukončit přehrávač</string>
|
||||
<string name="player_controls_fast_forward">Rychlý posun vpřed</string>
|
||||
<string name="player_controls_skip_forward">Přeskočit vpřed</string>
|
||||
|
|
|
@ -8,5 +8,4 @@
|
|||
<string name="player_controls_exit">Player verlassen</string>
|
||||
<string name="player_controls_rewind">Wiederholen</string>
|
||||
<string name="player_controls_fast_forward">Vorspulen</string>
|
||||
<string name="player_controls_skip_intro">Intro überspringen</string>
|
||||
</resources>
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
<string name="player_controls_exit">Salir de reproductor</string>
|
||||
<string name="player_controls_rewind">Atrasar</string>
|
||||
<string name="player_controls_fast_forward">Avanzar</string>
|
||||
<string name="player_controls_skip_intro">Saltar intro</string>
|
||||
<string name="player_controls_skip_forward">Saltar adelante</string>
|
||||
<string name="player_trickplay">Avance</string>
|
||||
<string name="player_controls_lock">Bloquea el reproductor</string>
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
<string name="player_controls_exit">Salir del reproductor</string>
|
||||
<string name="player_controls_rewind">Rebobinar</string>
|
||||
<string name="player_controls_fast_forward">Avanzar</string>
|
||||
<string name="player_controls_skip_intro">Saltar introducción</string>
|
||||
<string name="player_controls_skip_forward">Saltar adelante</string>
|
||||
<string name="player_controls_lock">Bloquea el reproductor</string>
|
||||
<string name="player_controls_play_pause">Reproducir pausar</string>
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
<string name="player_controls_exit">Quitter le lecteur</string>
|
||||
<string name="player_controls_rewind">Rembobiner</string>
|
||||
<string name="player_controls_fast_forward">Avance rapide</string>
|
||||
<string name="player_controls_skip_intro">Ignorer l\'introduction</string>
|
||||
<string name="player_controls_lock">Verrouille le lecteur</string>
|
||||
<string name="player_controls_play_pause">Lecture / Pause</string>
|
||||
<string name="player_controls_skip_back">Retour en arrière</string>
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
<string name="player_controls_exit">Kilépés a lejátszóból</string>
|
||||
<string name="player_controls_rewind">Visszatekerés</string>
|
||||
<string name="player_controls_fast_forward">Előrepörgetés</string>
|
||||
<string name="player_controls_skip_intro">Intro kihagyása</string>
|
||||
<string name="player_controls_lock">Zárolja a lejátszót</string>
|
||||
<string name="player_controls_skip_back">Ugrás vissza</string>
|
||||
<string name="player_controls_skip_forward">Ugrás előre</string>
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
<string name="player_controls_rewind">Riavvolgi</string>
|
||||
<string name="player_controls_lock">Blocca il player</string>
|
||||
<string name="player_controls_exit">Esci dal player</string>
|
||||
<string name="player_controls_skip_intro">Salta intro</string>
|
||||
<string name="player_controls_picture_in_picture">Attiva picture in picture</string>
|
||||
<string name="none">Nessuno</string>
|
||||
</resources>
|
|
@ -8,7 +8,6 @@
|
|||
<string name="player_controls_exit">צא מהנגן</string>
|
||||
<string name="player_controls_rewind">הרצה אחורה</string>
|
||||
<string name="player_controls_fast_forward">הרצה קדימה</string>
|
||||
<string name="player_controls_skip_intro">דלג פתיח</string>
|
||||
<string name="player_controls_skip_forward">דלג קדימה</string>
|
||||
<string name="player_controls_lock">נועל את הנגן</string>
|
||||
<string name="player_controls_skip_back">דלג אחורה</string>
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
<string name="player_controls_rewind">되감기</string>
|
||||
<string name="player_controls_fast_forward">빨리 감기</string>
|
||||
<string name="player_controls_exit">플레이어 나가기</string>
|
||||
<string name="player_controls_skip_intro">오프닝 스킵</string>
|
||||
<string name="player_controls_lock">플레이어 잠금</string>
|
||||
<string name="player_trickplay">Trickplay</string>
|
||||
<string name="player_controls_skip_back">뒤로 건너뛰기</string>
|
||||
|
|
|
@ -8,5 +8,4 @@
|
|||
<string name="player_controls_exit">Sluit speler</string>
|
||||
<string name="player_controls_rewind">Terugspoelen</string>
|
||||
<string name="player_controls_fast_forward">Snel vooruit</string>
|
||||
<string name="player_controls_skip_intro">Intro overslaan</string>
|
||||
</resources>
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
<string name="player_controls_exit">Zamknij odtwarzacz</string>
|
||||
<string name="player_controls_rewind">Przewiń</string>
|
||||
<string name="player_controls_fast_forward">Przewiń do przodu</string>
|
||||
<string name="player_controls_skip_intro">Pomiń czołówkę</string>
|
||||
<string name="player_controls_lock">Zablokuj odtwarzacz</string>
|
||||
<string name="player_controls_skip_back">Skocz do tyłu</string>
|
||||
<string name="player_trickplay">Trickplay</string>
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
<string name="player_controls_exit">Sair do reprodutor</string>
|
||||
<string name="player_controls_rewind">Retroceder</string>
|
||||
<string name="player_controls_fast_forward">Avanço rápido</string>
|
||||
<string name="player_controls_skip_intro">Pular introdução</string>
|
||||
<string name="player_controls_lock">Bloqueia o reprodutor</string>
|
||||
<string name="player_controls_skip_back">Saltar para trás</string>
|
||||
<string name="player_trickplay">Miniatura de pré-visualização</string>
|
||||
|
|
|
@ -14,6 +14,5 @@
|
|||
<string name="player_controls_progress">Barra de progresso</string>
|
||||
<string name="player_controls_skip_forward">Avançar</string>
|
||||
<string name="player_controls_skip_back">Pular para trás</string>
|
||||
<string name="player_controls_skip_intro">Pular introdução</string>
|
||||
<string name="player_controls_picture_in_picture">Insira imagem em imagem</string>
|
||||
</resources>
|
|
@ -8,7 +8,6 @@
|
|||
<string name="player_controls_exit">Выйти из проигрывателя</string>
|
||||
<string name="player_controls_rewind">Перемотка</string>
|
||||
<string name="player_controls_fast_forward">Быстрая перемотка</string>
|
||||
<string name="player_controls_skip_intro">Пропустить заставку</string>
|
||||
<string name="player_controls_lock">Блокировка</string>
|
||||
<string name="player_controls_skip_back">Перейти назад</string>
|
||||
<string name="player_controls_play_pause">Плей пауза</string>
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
<string name="player_controls_exit">Zavrieť prehrávač</string>
|
||||
<string name="player_controls_rewind">Pretočiť dozadu</string>
|
||||
<string name="player_controls_fast_forward">Pretočiť dopredu</string>
|
||||
<string name="player_controls_skip_intro">Preskočiť úvodnú zvučku</string>
|
||||
<string name="player_controls_lock">Zamkne prehrávač</string>
|
||||
<string name="player_controls_skip_back">Preskočiť späť</string>
|
||||
<string name="player_controls_skip_forward">Preskočiť dopredu</string>
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
<string name="player_controls_exit">Izhod iz predvajalnika</string>
|
||||
<string name="player_controls_rewind">Previj nazaj</string>
|
||||
<string name="player_controls_fast_forward">Navijaj naprej</string>
|
||||
<string name="player_controls_skip_intro">Preskoči uvod</string>
|
||||
<string name="player_controls_lock">Zaklene predvajalnik</string>
|
||||
<string name="player_controls_skip_back">Preskoči nazaj</string>
|
||||
<string name="player_controls_play_pause">Predvajaj ustavi</string>
|
||||
|
|
|
@ -8,5 +8,4 @@
|
|||
<string name="player_controls_exit">Avsluta spelare</string>
|
||||
<string name="player_controls_rewind">Spola tillbaka</string>
|
||||
<string name="player_controls_fast_forward">Spola framåt</string>
|
||||
<string name="player_controls_skip_intro">Hoppa över intro</string>
|
||||
</resources>
|
|
@ -8,5 +8,4 @@
|
|||
<string name="player_controls_rewind">Відмотка</string>
|
||||
<string name="player_controls_fast_forward">Швидке перемотування</string>
|
||||
<string name="player_controls_exit">Вийти з плеєра</string>
|
||||
<string name="player_controls_skip_intro">Пропустити вступ</string>
|
||||
</resources>
|
|
@ -8,7 +8,6 @@
|
|||
<string name="player_controls_exit">Thoát khỏi trình xem</string>
|
||||
<string name="player_controls_rewind">Tua lùi</string>
|
||||
<string name="player_controls_fast_forward">Tua tới</string>
|
||||
<string name="player_controls_skip_intro">Bỏ qua đoạn mở đầu</string>
|
||||
<string name="player_controls_skip_back">Bỏ qua / Trở về</string>
|
||||
<string name="player_controls_lock">Khoá trình phát</string>
|
||||
<string name="player_controls_play_pause">Phát / Tạm dừng</string>
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
<string name="player_controls_exit">退出播放器</string>
|
||||
<string name="player_controls_rewind">快退</string>
|
||||
<string name="player_controls_fast_forward">快进</string>
|
||||
<string name="player_controls_skip_intro">跳过片头</string>
|
||||
<string name="player_controls_lock">锁定播放器</string>
|
||||
<string name="player_controls_skip_back">跳回</string>
|
||||
<string name="player_controls_play_pause">播放暂停</string>
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
<string name="player_controls_exit">關閉播放器</string>
|
||||
<string name="player_controls_rewind">倒帶</string>
|
||||
<string name="player_controls_fast_forward">快轉</string>
|
||||
<string name="player_controls_skip_intro">跳過片頭</string>
|
||||
<string name="player_controls_lock">鎖定播放器</string>
|
||||
<string name="player_controls_skip_back">跳回</string>
|
||||
<string name="player_controls_play_pause">播放暫停</string>
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
<string name="player_controls_play_pause">Play pause</string>
|
||||
<string name="player_controls_rewind">Rewind</string>
|
||||
<string name="player_controls_exit">Exit player</string>
|
||||
<string name="player_controls_skip_intro">Skip Intro</string>
|
||||
<string name="player_controls_fast_forward">Fast forward</string>
|
||||
<string name="player_controls_skip_forward">Skip forward</string>
|
||||
<string name="player_trickplay">Trickplay</string>
|
||||
|
|
Loading…
Reference in a new issue