Compare commits

...

14 commits

Author SHA1 Message Date
3ee781bfc2 chore: fige Cargo.lock (epoch-1.9.0, [patch] locaux)
Some checks failed
Validate .desktop files / validate (push) Has been cancelled
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-24 21:03:54 +02:00
cfdeaa3ae1 merge: epoch-1.9.0 d'upstream 2026-09-24 20:46:53 +02:00
Michael Murphy
66b3f34335
i18n: translation update from Hosted Weblate (#328)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for [Pop OS/COSMIC
Player](https://hosted.weblate.org/projects/pop-os/cosmic-player/).



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/pop-os/cosmic-player/matrix-auto.svg)
2026-09-15 21:57:21 +02:00
Hosted Weblate
3d8af19ac4
i18n: translation updates from weblate
Co-authored-by: Amadɣas <massiin@proton.me>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Kurt Harren Catindig <kurtharrencatindig03@gmail.com>
Co-authored-by: Quentin PAGÈS <quentinantonin@free.fr>
Co-authored-by: Satakun Utama <galaxytomostore@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-player/kab/
Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-player/oc/
Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-player/th/
Translation: Pop OS/COSMIC Player
2026-09-12 11:51:35 +00:00
78b806a347 chore: fige Cargo.lock
Some checks failed
Validate .desktop files / validate (push) Has been cancelled
2026-09-10 18:11:31 +02:00
45c9b1aa19 Merge tag 'epoch-1.8.0'
Epoch 1.8.0

# Conflicts:
#	Cargo.lock
#	src/video.rs
2026-09-10 17:57:28 +02:00
Levi Portenier
a297c24a96
Epoch 1.8.0 version update (#331)
Generated by cosmic-epoch scripts/version-update.sh
2026-09-02 12:19:07 -06:00
Jeremy Soller
f0365d411b Epoch 1.8.0 version update
Generated by cosmic-epoch scripts/version-update.sh
2026-09-02 08:15:29 -06:00
krakotay
e040f7fbc7
fix: playback of malformed MP4 files with invalid framerates
- [x] I have disclosed use of any AI generated code in my commit
messages.
- If you are using an LLM, and do not fully understand the changes it is
making to the code base, do not create a PR.
- In our experience, AI generated code often results in overly complex
code that lacks enough context for a proper fix or feature inclusion.
This results in considerably longer code reviews. Due to this, AI
authored or partially authored PRs may be closed without comment.
- [x] I understand these changes in full and will be able to respond to
review comments.
- [x] My change is accurately described in the commit message.
- [x] My contribution is tested and working as described.
- [x] I have read the [Developer Certificate of
Origin](https://developercertificate.org/) and certify my contribution
under its conditions.

Some malformed MP4 files previously wouldn't play at all because they
reported a 0/1 framerate.
Other files suffered from severe audio stuttering caused by repeated
long GAP events emitted from malformed edit lists.
This patch treats invalid framerates as unknown (allowing the existing
fallback to be used) and suppresses suspicious long audio GAP events
before they reach the audio sink.
As a result, both kinds of videos now play correctly.
2026-08-29 02:31:43 +02:00
89dd5e1f10 chore: fige Cargo.lock tel que resolu apres le merge 1.7.0
Some checks failed
Validate .desktop files / validate (push) Has been cancelled
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 07:58:51 +02:00
3171217e5a Merge tag 'epoch-1.7.0'
Some checks failed
Validate .desktop files / validate (push) Has been cancelled
Epoch 1.7.0
2026-08-27 07:50:01 +02:00
Jeremy Soller
c9cba75c84 Epoch 1.7.0 version update
Generated by cosmic-epoch scripts/version-update.sh
2026-08-25 12:11:05 -06:00
Michael Aaron Murphy
23254703eb
i18n(da): Weblate translation update 2026-08-24 20:05:24 +02:00
Hosted Weblate
b5f2fffe65
i18n: translation updates from weblate
Co-authored-by: Andi Chandler <andi@gowling.com>
Co-authored-by: CodeBeats <nicholai67@hotmail.com>
Co-authored-by: Feike Donia <feikedonia@proton.me>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Jiri Grönroos <jiri.gronroos@iki.fi>
Co-authored-by: Martin Meizoso <martinmeizoso@gmail.com>
Co-authored-by: Michael Millet <mikevlet@protonmail.com>
Co-authored-by: Quentin PAGÈS <quentinantonin@free.fr>
Co-authored-by: Steen Rabol <steen@rabol.dev>
Co-authored-by: Walter William Beckerleg Bruckman <spayk.99@protonmail.com>
Co-authored-by: Wilbur Lindqvist <william@willmantrade.com>
Co-authored-by: therealmate <hellogaming91@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-player/da/
Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-player/en_GB/
Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-player/fi/
Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-player/gl/
Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-player/hu/
Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-player/it/
Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-player/oc/
Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-player/pt_BR/
Translation: Pop OS/COSMIC Player
2026-08-19 11:51:33 +02:00
11 changed files with 325 additions and 341 deletions

2
.gitignore vendored
View file

@ -10,4 +10,4 @@
!/vendor/iced_video_player/
!/vendor/iced_video_player/**
/vendor.tar
.idea/
.idea/

516
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
[package]
name = "cosmic-player"
version = "1.6.0"
version = "1.8.0"
edition = "2024"
rust-version = "1.93"

12
debian/changelog vendored
View file

@ -1,3 +1,15 @@
cosmic-player (1.8.0) noble; urgency=medium
* Epoch 1.8.0 version update
-- Jeremy Soller <jeremy@system76.com> Wed, 02 Sep 2026 08:15:23 -0600
cosmic-player (1.7.0) noble; urgency=medium
* Epoch 1.7.0 version update
-- Jeremy Soller <jeremy@system76.com> Tue, 25 Aug 2026 09:20:51 -0600
cosmic-player (1.6.0) noble; urgency=medium
* Epoch 1.6.0 version update

View file

@ -9,3 +9,28 @@ settings = Indstillinger
open-file = Åbn fil
open-folder = Åbn mappe
file = Fil
album = Album: { $album }
audio = Lyd
no-video-or-audio-file-open = Ingen video- eller lydfil åben
off = Fra
subtitles = Undertekster
unknown-author = Ukendt Forfatter
untitled = Utituleret
open-media = Åbn medie...
open-recent-media = Åbn seneste medie
clear-recent = Ryd seneste-liste
open-media-folder = Åbn mediemappe...
open-recent-media-folder = Åbn seneste mediemappe
close-media-folder = Luk mediemappe
repeat-disabled = Gentagelse deaktiveret
repeat-track = Gentag nummer
playback = Afspilning
next-frame = Næste billede
previous-frame = Forrige billede
ab-repeat = A-B-gentagelse
ab-repeat-set-a = A-B-gentagelse (A)
ab-repeat-set-b = A-B-gentagelse (B)
ab-repeat-clear = Ryd A-B-gentagelse
xdg-name = COSMIC Medieafspiller
xdg-comment = Medieafspiller til COSMIC-skrivebordet
xdg-keywords = Lyd;Film;Film;Musik;Lyd;Video;

View file

View file

@ -2,13 +2,13 @@ open-file = Ldi afaylu
open-folder = Ldi akaram
repeat-disabled = Allus yensa
repeat-track = Ales tazribt
quit = Tuffɣa
quit = Ffeɣ
settings = Iɣewwaṛen
appearance = Timeẓri
theme = Asentel
dark = Aɣmayan
light = Aceɛlal
match-desktop = Amṣada d tnarit
match-desktop = Semṣada akked tnarit
file = Afaylu
close-file = Mdel afaylu
album = Album: { $album }

View file

@ -1,4 +1,4 @@
settings = Paramètres
settings = Configuracion
album = Album : { $album }
audio = Àudio
no-video-or-audio-file-open = Cap de fichièr vidèo o àudio pas dobèrt
@ -9,7 +9,7 @@ untitled = Sens títol
appearance = Aparéncia
theme = Tèma
match-desktop = Assortir al burèu
dark = Fosc
dark = Escur
light = Clar
file = Fichièr
open-media = Dorbir mèdia...
@ -31,3 +31,4 @@ ab-repeat-clear = Escafar la repeticion A-B
xdg-name = Lector multimèdia COSMIC
xdg-comment = Lector multimèdia pel burèu COSMIC
xdg-keywords = Àudio;Musica;Vidèo;Film;Son;
quit = Quitar

View file

@ -0,0 +1,4 @@
settings = การตั้งค่า
dark = มืด
light = สว่าง
appearance = ลักษณะ

View file

@ -82,7 +82,32 @@ fn get_framerate(video: &Video) -> Option<f64> {
let caps = pad.current_caps()?;
let structure = caps.structure(0)?;
let framerate = structure.get::<gst::Fraction>("framerate").ok()?;
Some(framerate.numer() as f64 / framerate.denom() as f64)
positive_framerate(framerate)
}
fn positive_framerate(framerate: gst::Fraction) -> Option<f64> {
if framerate.numer() <= 0 || framerate.denom() <= 0 {
return None;
}
let fps = framerate.numer() as f64 / framerate.denom() as f64;
fps.is_finite().then_some(fps)
}
#[cfg(test)]
mod tests {
use super::positive_framerate;
use iced_video_player::gst;
#[test]
fn variable_framerate_uses_fallback() {
assert_eq!(positive_framerate(gst::Fraction::new(0, 1)), None);
}
#[test]
fn fixed_framerate_is_preserved() {
assert_eq!(positive_framerate(gst::Fraction::new(30, 1)), Some(30.0));
}
}
/// Runs application with these settings

View file

@ -4,6 +4,40 @@ use iced_video_player::{Video, gst, gst_app, gst_pbutils};
use cosmic::action;
use cosmic::app::Task;
const SUSPICIOUS_AUDIO_GAP_DURATION: gst::ClockTime = gst::ClockTime::SECOND;
fn is_suspicious_audio_gap(duration: Option<gst::ClockTime>) -> bool {
duration.is_some_and(|duration| duration >= SUSPICIOUS_AUDIO_GAP_DURATION)
}
fn suppress_suspicious_audio_gaps(audio_filter: &gst::Element) {
let Some(src_pad) = audio_filter.static_pad("src") else {
log::warn!("audio filter has no source pad; malformed audio gaps will not be suppressed");
return;
};
let _ = src_pad.add_probe(gst::PadProbeType::EVENT_DOWNSTREAM, |_, info| {
let Some(event) = info.event() else {
return gst::PadProbeReturn::Ok;
};
let gst::EventView::Gap(gap) = event.view() else {
return gst::PadProbeReturn::Ok;
};
let (timestamp, duration) = gap.get();
if !is_suspicious_audio_gap(duration) {
return gst::PadProbeReturn::Ok;
}
// Some malformed MP4 edit lists cause streamsynchronizer to emit a
// long GAP before almost every audio buffer. The next buffer's PTS is
// still continuous, so forwarding those events makes audio sinks
// repeatedly wait or resynchronise and produces choppy playback.
log::debug!("suppressing audio GAP at {timestamp} with duration {duration:?}");
drop(info.take_event());
gst::PadProbeReturn::Handled
});
}
#[derive(Debug, Default)]
pub struct VideoSettings {
pub mute: bool,
@ -33,11 +67,14 @@ pub fn new_video(
.downcast::<gst::Pipeline>()
.map_err(|_| iced_video_player::Error::Cast)
.unwrap();
if let Ok(scaletempo) = gst::ElementFactory::make("scaletempo").build() {
pipeline.set_property("audio-filter", &scaletempo);
} else {
log::warn!("scaletempo element not available; speed changes will affect pitch");
}
let audio_filter = gst::ElementFactory::make("scaletempo")
.build()
.unwrap_or_else(|_| {
log::warn!("scaletempo element not available; speed changes will affect pitch");
gst::ElementFactory::make("identity").build().unwrap()
});
suppress_suspicious_audio_gaps(&audio_filter);
pipeline.set_property("audio-filter", &audio_filter);
pipeline.connect("element-setup", false, |vals| {
let Ok(elem) = vals[1].get::<gst::Element>() else {
return None;
@ -111,3 +148,25 @@ fn disable_broken_hardware_decoders() {
}
}
}
#[cfg(test)]
mod tests {
use super::is_suspicious_audio_gap;
use iced_video_player::gst;
#[test]
fn long_audio_gap_is_suspicious() {
assert!(is_suspicious_audio_gap(Some(gst::ClockTime::SECOND)));
assert!(is_suspicious_audio_gap(Some(
gst::ClockTime::from_seconds(3)
)));
}
#[test]
fn short_or_unknown_audio_gap_is_preserved() {
assert!(!is_suspicious_audio_gap(Some(
gst::ClockTime::from_mseconds(999)
)));
assert!(!is_suspicious_audio_gap(None));
}
}