mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-29 23:32:04 +02:00
Compare commits
93 Commits
0.4.0
...
clappersin
Author | SHA1 | Date | |
---|---|---|---|
|
23b57cd326 | ||
|
9a19e10542 | ||
|
0061e133f9 | ||
|
f771e0320c | ||
|
72a64a41d9 | ||
|
2818d3c91b | ||
|
ffb481b52b | ||
|
c5c289d466 | ||
|
3074051b3d | ||
|
980e1d9e1a | ||
|
045e4fc2c4 | ||
|
52aa7710dc | ||
|
5101fce5a7 | ||
|
e0daf8435a | ||
|
9f18295728 | ||
|
8ce977505e | ||
|
8ac839c9aa | ||
|
8fa2036265 | ||
|
1d5bb1e6aa | ||
|
9ec87c1b58 | ||
|
16c0f8baae | ||
|
c94d21fc53 | ||
|
159f96c984 | ||
|
96ad4fa3db | ||
|
b2e7bef8d4 | ||
|
40a1dc6960 | ||
|
c4bd604e17 | ||
|
83c0e3b598 | ||
|
54715023c0 | ||
|
95046ceba8 | ||
|
b189e24b5e | ||
|
cb9e2ac979 | ||
|
545d8826e0 | ||
|
c2160198b9 | ||
|
aa7eae2417 | ||
|
3192a32845 | ||
|
706c783498 | ||
|
8ba3ca4af6 | ||
|
38efa7ab9f | ||
|
d19ddbcaca | ||
|
615f1553fb | ||
|
09c9e7560b | ||
|
f40ce756ad | ||
|
23d51be185 | ||
|
0db2a4a045 | ||
|
469c06d22b | ||
|
3feaf225b5 | ||
|
fc8d881efd | ||
|
ac76836fd7 | ||
|
f6a1aaf1dc | ||
|
000dca82d9 | ||
|
7a508fef39 | ||
|
d465d9f150 | ||
|
5e4dfb322c | ||
|
0c561ab4b3 | ||
|
46ce261524 | ||
|
50aac8cdd8 | ||
|
810aea476f | ||
|
24905f1d60 | ||
|
82e3c9a52f | ||
|
654b8aaf60 | ||
|
3c0e33e4a4 | ||
|
d2df1c3bd8 | ||
|
af24073590 | ||
|
44cee14eb2 | ||
|
b853685dd4 | ||
|
15461dd38a | ||
|
1c1989bc32 | ||
|
e9c9ae073f | ||
|
22d2c40b0f | ||
|
5301c8b368 | ||
|
e910978590 | ||
|
3b99f0ee0c | ||
|
f93a0fed98 | ||
|
6b8c35b16e | ||
|
5fdb6e64be | ||
|
60d4b5aec1 | ||
|
f5258889cf | ||
|
31eddf5dd2 | ||
|
89f7304e0e | ||
|
3c918bda73 | ||
|
2a8ef2559f | ||
|
7676e18eee | ||
|
00b05b460d | ||
|
62f02cf2a3 | ||
|
9fc1d9b8c4 | ||
|
45a5ebb4b6 | ||
|
2500a42286 | ||
|
bafffa59b9 | ||
|
201cb6f64c | ||
|
636098182b | ||
|
5442b0b70a | ||
|
67d1b9f5bc |
7
.github/workflows/flatpak-nightly.yml
vendored
7
.github/workflows/flatpak-nightly.yml
vendored
@@ -1,4 +1,5 @@
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
name: "Flatpak Nightly"
|
||||
@@ -25,8 +26,12 @@ jobs:
|
||||
uses: docker/setup-qemu-action@v1
|
||||
with:
|
||||
platforms: arm64
|
||||
- name: Prepare Runtime
|
||||
run: |
|
||||
flatpak --system install -y --noninteractive flathub org.freedesktop.Sdk.Extension.rust-nightly/${{ matrix.arch }}/21.08
|
||||
flatpak --system install -y --noninteractive flathub org.freedesktop.Sdk.Extension.llvm13/${{ matrix.arch }}/21.08
|
||||
- uses: bilelmoussaoui/flatpak-github-actions/flatpak-builder@v4
|
||||
name: "Build"
|
||||
name: Build
|
||||
with:
|
||||
bundle: com.github.rafostar.Clapper.flatpak
|
||||
manifest-path: pkgs/flatpak/com.github.rafostar.Clapper-nightly.json
|
||||
|
3
.github/workflows/flatpak.yml
vendored
3
.github/workflows/flatpak.yml
vendored
@@ -1,4 +1,5 @@
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
@@ -11,7 +12,7 @@ jobs:
|
||||
name: "Flatpak"
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: bilelmoussaoui/flatpak-github-actions:gnome-40
|
||||
image: bilelmoussaoui/flatpak-github-actions:gnome-42
|
||||
options: --privileged
|
||||
strategy:
|
||||
matrix:
|
||||
|
16
README.md
16
README.md
@@ -2,6 +2,8 @@
|
||||
[](https://github.com/Rafostar/clapper/actions/workflows/flatpak.yml)
|
||||
[](https://github.com/Rafostar/clapper/actions/workflows/flatpak-nightly.yml)
|
||||
[](https://crowdin.com/project/clapper)
|
||||
[](https://matrix.to/#/#clapper-player:matrix.org)
|
||||
[](https://liberapay.com/Clapper)
|
||||
|
||||
A GNOME media player built using [GJS](https://gitlab.gnome.org/GNOME/gjs) with [GTK4](https://www.gtk.org) toolkit.
|
||||
The media player uses [GStreamer](https://gstreamer.freedesktop.org/) as a media backend and renders everything via [OpenGL](https://www.opengl.org).
|
||||
@@ -38,17 +40,13 @@ List of patches used in this version can be found [here](https://github.com/Rafo
|
||||
<img width='240' alt='Download on Flathub' src='https://flathub.org/assets/badges/flathub-badge-en.png'/>
|
||||
</a>
|
||||
|
||||
## Packages
|
||||
#### Fedora & openSUSE
|
||||
Pre-built packages are available in [my repo](https://software.opensuse.org//download.html?project=home%3ARafostar&package=clapper) ([see status](https://build.opensuse.org/package/show/home:Rafostar/clapper)).<br>
|
||||
Those are automatically built on each git commit, and are thus considered unstable.
|
||||
## Packages in Linux Distributions
|
||||
[](https://repology.org/project/clapper/versions)
|
||||
|
||||
#### Arch Linux
|
||||
You can get Clapper from the AUR:
|
||||
* [clapper](https://aur.archlinux.org/packages/clapper) (stable version)
|
||||
* [clapper-git](https://aur.archlinux.org/packages/clapper-git)
|
||||
Pre-built RPM packages are also available in [my repo](https://software.opensuse.org//download.html?project=home%3ARafostar&package=clapper) ([see status](https://build.opensuse.org/package/show/home:Rafostar/clapper)).<br>
|
||||
Those are automatically built on each git commit, thus are considered unstable.
|
||||
|
||||
## Installation from source code
|
||||
## Installation from Source Code
|
||||
```sh
|
||||
meson builddir --prefix=/usr/local
|
||||
sudo meson install -C builddir
|
||||
|
@@ -6,4 +6,4 @@ imports.package.init({
|
||||
prefix: '@prefix@',
|
||||
libdir: '@libdir@',
|
||||
});
|
||||
imports.package.run(imports.src.main@ID_POSTFIX@);
|
||||
imports.package.run(imports.src.main);
|
||||
|
@@ -1,25 +1,19 @@
|
||||
clapper_apps = ['', 'Remote', 'Daemon']
|
||||
bin_conf = configuration_data()
|
||||
|
||||
foreach id_postfix : clapper_apps
|
||||
app_postfix = (id_postfix != '') ? '.' + id_postfix : ''
|
||||
bin_conf.set('GJS', find_program('gjs').path())
|
||||
bin_conf.set('PACKAGE_NAME', meson.project_name())
|
||||
bin_conf.set('PACKAGE_VERSION', meson.project_version())
|
||||
bin_conf.set('prefix', get_option('prefix'))
|
||||
bin_conf.set('libdir', libdir)
|
||||
|
||||
bin_conf = configuration_data()
|
||||
bin_conf.set('GJS', find_program('gjs').path())
|
||||
bin_conf.set('PACKAGE_NAME', meson.project_name())
|
||||
bin_conf.set('PACKAGE_VERSION', meson.project_version())
|
||||
bin_conf.set('ID_POSTFIX', id_postfix)
|
||||
bin_conf.set('prefix', get_option('prefix'))
|
||||
bin_conf.set('libdir', libdir)
|
||||
|
||||
configure_file(
|
||||
input: 'com.github.rafostar.Clapper.in',
|
||||
output: 'com.github.rafostar.Clapper' + app_postfix,
|
||||
configuration: bin_conf,
|
||||
install: true,
|
||||
install_dir: bindir,
|
||||
install_mode: 'rwxr-xr-x'
|
||||
)
|
||||
endforeach
|
||||
configure_file(
|
||||
input: 'com.github.rafostar.Clapper.in',
|
||||
output: 'com.github.rafostar.Clapper',
|
||||
configuration: bin_conf,
|
||||
install: true,
|
||||
install_dir: bindir,
|
||||
install_mode: 'rwxr-xr-x'
|
||||
)
|
||||
|
||||
clapper_symlink_cmd = 'ln -fs @0@ $DESTDIR@1@'.format(
|
||||
'com.github.rafostar.Clapper',
|
||||
|
@@ -10,6 +10,9 @@ scrolledwindow scrollbar.vertical slider {
|
||||
}
|
||||
|
||||
/* Adwaita is missing osd ListBox */
|
||||
.clapperplaylist {
|
||||
background: none;
|
||||
}
|
||||
.clapperplaylist row {
|
||||
border-radius: 5px;
|
||||
}
|
||||
@@ -28,9 +31,6 @@ scrolledwindow scrollbar.vertical slider {
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
.osd .clapperplaylist {
|
||||
background: none;
|
||||
}
|
||||
.osd .clapperplaylist row image {
|
||||
-gtk-icon-shadow: none;
|
||||
}
|
||||
@@ -223,6 +223,9 @@ scale trough slider {
|
||||
.fullscreen.tvmode .positionscale marks.bottom {
|
||||
margin-top: 2px;
|
||||
}
|
||||
.fullscreen.tvmode .positionscale trough {
|
||||
border-radius: 3px;
|
||||
}
|
||||
.fullscreen.tvmode .positionscale trough highlight {
|
||||
border-radius: 3px;
|
||||
min-height: 20px;
|
||||
|
@@ -103,16 +103,6 @@
|
||||
<summary>Set PlayFlags for playbin</summary>
|
||||
</key>
|
||||
|
||||
<!-- YouTube -->
|
||||
<key name="yt-adaptive-enabled" type="b">
|
||||
<default>false</default>
|
||||
<summary>Enable to use adaptive streaming for YouTube</summary>
|
||||
</key>
|
||||
<key name="yt-quality-type" type="i">
|
||||
<default>1</default>
|
||||
<summary>Max YouTube video quality type</summary>
|
||||
</key>
|
||||
|
||||
<!-- Other -->
|
||||
<key name="window-size" type="s">
|
||||
<default>'[800, 490]'</default>
|
||||
|
@@ -48,6 +48,34 @@
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<releases>
|
||||
<release version="0.4.1" date="2021-12-20">
|
||||
<description>
|
||||
<p>Fixes:</p>
|
||||
<ul>
|
||||
<li>Compatibility with more recent libadwaita versions</li>
|
||||
<li>Toggle mute with M button alone</li>
|
||||
<li>Allow handling YouTube with external GStreamer plugins</li>
|
||||
<li>Fix catching errors when reading clipboard</li>
|
||||
<li>Fix missing translator-credits</li>
|
||||
<li>Fix missing gio-unix-2.0 dep</li>
|
||||
<li>Fix playback pausing when entering fullscreen with touchscreen</li>
|
||||
<li>Fix GST_PLUGIN_FEATURE_RANK env usage</li>
|
||||
<li>Fix video/audio decoder change detection</li>
|
||||
<li>Merge global video tags instead replacing them</li>
|
||||
<li>Few other misc bug fixes</li>
|
||||
</ul>
|
||||
<p>New translations:</p>
|
||||
<ul>
|
||||
<li>Chinese Simplified</li>
|
||||
<li>Czech</li>
|
||||
<li>Hungarian</li>
|
||||
<li>Portuguese</li>
|
||||
<li>Portuguese, Brazilian</li>
|
||||
<li>Russian</li>
|
||||
<li>Spanish</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.4.0" date="2021-09-12">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
|
344
lib/gst/clapper/gstclapper.c
vendored
344
lib/gst/clapper/gstclapper.c
vendored
@@ -152,7 +152,7 @@ struct _GstClapper
|
||||
GstBus *bus;
|
||||
GstState target_state, current_state;
|
||||
gboolean is_live;
|
||||
GSource *tick_source, *ready_timeout_source;
|
||||
GSource *tick_source;
|
||||
GstClockTime cached_duration;
|
||||
|
||||
gdouble rate;
|
||||
@@ -253,6 +253,9 @@ static void gst_clapper_audio_info_update (GstClapper * self,
|
||||
static void gst_clapper_subtitle_info_update (GstClapper * self,
|
||||
GstClapperStreamInfo * stream_info);
|
||||
|
||||
static gboolean find_active_decoder_with_stream_id (GstClapper * self,
|
||||
GstElementFactoryListType type, const gchar * stream_id);
|
||||
|
||||
/* For playbin3 */
|
||||
static void gst_clapper_streams_info_create_from_collection (GstClapper * self,
|
||||
GstClapperMediaInfo * media_info, GstStreamCollection * collection);
|
||||
@@ -1135,44 +1138,6 @@ remove_tick_source (GstClapper * self)
|
||||
self->tick_source = NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ready_timeout_cb (gpointer user_data)
|
||||
{
|
||||
GstClapper *self = user_data;
|
||||
|
||||
if (self->target_state <= GST_STATE_READY) {
|
||||
GST_DEBUG_OBJECT (self, "Setting pipeline to NULL state");
|
||||
self->target_state = GST_STATE_NULL;
|
||||
self->current_state = GST_STATE_NULL;
|
||||
gst_element_set_state (self->playbin, GST_STATE_NULL);
|
||||
}
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
add_ready_timeout_source (GstClapper * self)
|
||||
{
|
||||
if (self->ready_timeout_source)
|
||||
return;
|
||||
|
||||
self->ready_timeout_source = g_timeout_source_new_seconds (60);
|
||||
g_source_set_callback (self->ready_timeout_source,
|
||||
(GSourceFunc) ready_timeout_cb, self, NULL);
|
||||
g_source_attach (self->ready_timeout_source, self->context);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_ready_timeout_source (GstClapper * self)
|
||||
{
|
||||
if (!self->ready_timeout_source)
|
||||
return;
|
||||
|
||||
g_source_destroy (self->ready_timeout_source);
|
||||
g_source_unref (self->ready_timeout_source);
|
||||
self->ready_timeout_source = NULL;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GstClapper *clapper;
|
||||
@@ -1217,7 +1182,6 @@ emit_error (GstClapper * self, GError * err)
|
||||
g_error_free (err);
|
||||
|
||||
remove_tick_source (self);
|
||||
remove_ready_timeout_source (self);
|
||||
|
||||
self->target_state = GST_STATE_NULL;
|
||||
self->current_state = GST_STATE_NULL;
|
||||
@@ -1862,6 +1826,17 @@ media_info_update (GstClapper * self, GstClapperMediaInfo * info)
|
||||
"image_sample: %p", info->title, info->container, info->image_sample);
|
||||
}
|
||||
|
||||
static void
|
||||
merge_tags (GstTagList **my_tags, GstTagList *tags)
|
||||
{
|
||||
if (*my_tags) {
|
||||
*my_tags = gst_tag_list_make_writable (*my_tags);
|
||||
gst_tag_list_insert (*my_tags, tags, GST_TAG_MERGE_REPLACE);
|
||||
} else {
|
||||
*my_tags = gst_tag_list_ref (tags);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tags_cb (G_GNUC_UNUSED GstBus * bus, GstMessage * msg, gpointer user_data)
|
||||
{
|
||||
@@ -1877,17 +1852,12 @@ tags_cb (G_GNUC_UNUSED GstBus * bus, GstMessage * msg, gpointer user_data)
|
||||
if (gst_tag_list_get_scope (tags) == GST_TAG_SCOPE_GLOBAL) {
|
||||
g_mutex_lock (&self->lock);
|
||||
if (self->media_info) {
|
||||
if (self->media_info->tags)
|
||||
gst_tag_list_unref (self->media_info->tags);
|
||||
self->media_info->tags = gst_tag_list_ref (tags);
|
||||
merge_tags (&self->media_info->tags, tags);
|
||||
media_info_update (self, self->media_info);
|
||||
g_mutex_unlock (&self->lock);
|
||||
} else {
|
||||
if (self->global_tags)
|
||||
gst_tag_list_unref (self->global_tags);
|
||||
self->global_tags = gst_tag_list_ref (tags);
|
||||
g_mutex_unlock (&self->lock);
|
||||
merge_tags (&self->global_tags, tags);
|
||||
}
|
||||
g_mutex_unlock (&self->lock);
|
||||
}
|
||||
|
||||
gst_tag_list_unref (tags);
|
||||
@@ -2050,6 +2020,7 @@ streams_selected_cb (G_GNUC_UNUSED GstBus * bus, GstMessage * msg,
|
||||
{
|
||||
GstClapper *self = GST_CLAPPER (user_data);
|
||||
GstStreamCollection *collection = NULL;
|
||||
gchar *video_sid, *audio_sid;
|
||||
guint i, len;
|
||||
|
||||
gst_message_parse_streams_selected (msg, &collection);
|
||||
@@ -2098,7 +2069,22 @@ streams_selected_cb (G_GNUC_UNUSED GstBus * bus, GstMessage * msg,
|
||||
|
||||
*current_sid = g_strdup (stream_id);
|
||||
}
|
||||
|
||||
video_sid = g_strdup (self->video_sid);
|
||||
audio_sid = g_strdup (self->audio_sid);
|
||||
|
||||
g_mutex_unlock (&self->lock);
|
||||
|
||||
if (video_sid) {
|
||||
find_active_decoder_with_stream_id (self, GST_ELEMENT_FACTORY_TYPE_DECODER
|
||||
| GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO, video_sid);
|
||||
g_free (video_sid);
|
||||
}
|
||||
if (audio_sid) {
|
||||
find_active_decoder_with_stream_id (self, GST_ELEMENT_FACTORY_TYPE_DECODER
|
||||
| GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO, audio_sid);
|
||||
g_free (audio_sid);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -3009,11 +2995,12 @@ decoder_changed_signal_data_free (DecoderChangedSignalData * data)
|
||||
|
||||
static void
|
||||
emit_decoder_changed (GstClapper * self, gchar * decoder_name,
|
||||
gboolean is_video)
|
||||
GstElementFactoryListType type)
|
||||
{
|
||||
GstClapperSignalDispatcherFunc func = NULL;
|
||||
|
||||
if (is_video) {
|
||||
if ((type & GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO) ==
|
||||
GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO) {
|
||||
if (g_signal_handler_find (self, G_SIGNAL_MATCH_ID,
|
||||
signals[SIGNAL_VIDEO_DECODER_CHANGED], 0, NULL, NULL, NULL) != 0 &&
|
||||
g_strcmp0 (self->last_vdecoder, decoder_name) != 0) {
|
||||
@@ -3021,7 +3008,8 @@ emit_decoder_changed (GstClapper * self, gchar * decoder_name,
|
||||
g_free (self->last_vdecoder);
|
||||
self->last_vdecoder = g_strdup (decoder_name);
|
||||
}
|
||||
} else {
|
||||
} else if ((type & GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO) ==
|
||||
GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO) {
|
||||
if (g_signal_handler_find (self, G_SIGNAL_MATCH_ID,
|
||||
signals[SIGNAL_AUDIO_DECODER_CHANGED], 0, NULL, NULL, NULL) != 0 &&
|
||||
g_strcmp0 (self->last_adecoder, decoder_name) != 0) {
|
||||
@@ -3042,6 +3030,138 @@ emit_decoder_changed (GstClapper * self, gchar * decoder_name,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
iterate_decoder_pads (GstClapper * self, GstElement * element,
|
||||
const gchar * stream_id, GstElementFactoryListType type)
|
||||
{
|
||||
GstIterator *iter;
|
||||
GValue value = { 0, };
|
||||
gboolean found = FALSE;
|
||||
|
||||
iter = gst_element_iterate_src_pads (element);
|
||||
|
||||
while (gst_iterator_next (iter, &value) == GST_ITERATOR_OK) {
|
||||
GstPad *decoder_pad = g_value_get_object (&value);
|
||||
gchar *decoder_stream_id = gst_pad_get_stream_id (decoder_pad);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Decoder stream: %s", decoder_stream_id);
|
||||
|
||||
/* In case of playbin3, pad may not be active yet */
|
||||
if ((found = (g_strcmp0 (decoder_stream_id, stream_id) == 0
|
||||
|| (!decoder_stream_id && self->use_playbin3)))) {
|
||||
GstElementFactory *factory;
|
||||
gchar *plugin_name;
|
||||
|
||||
factory = gst_element_get_factory (element);
|
||||
plugin_name = gst_object_get_name (GST_OBJECT_CAST (factory));
|
||||
|
||||
if (plugin_name) {
|
||||
GST_DEBUG_OBJECT (self, "Found decoder: %s", plugin_name);
|
||||
emit_decoder_changed (self, plugin_name, type);
|
||||
|
||||
g_free (plugin_name);
|
||||
}
|
||||
}
|
||||
|
||||
g_free (decoder_stream_id);
|
||||
g_value_unset (&value);
|
||||
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
|
||||
gst_iterator_free (iter);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
find_active_decoder_with_stream_id (GstClapper * self, GstElementFactoryListType type,
|
||||
const gchar * stream_id)
|
||||
{
|
||||
GstIterator *iter;
|
||||
GValue value = { 0, };
|
||||
gboolean found = FALSE;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Searching for decoder with stream: %s", stream_id);
|
||||
|
||||
iter = gst_bin_iterate_recurse (GST_BIN (self->playbin));
|
||||
|
||||
while (gst_iterator_next (iter, &value) == GST_ITERATOR_OK) {
|
||||
GstElement *element = g_value_get_object (&value);
|
||||
GstElementFactory *factory = gst_element_get_factory (element);
|
||||
|
||||
if (factory && gst_element_factory_list_is_type (factory, type))
|
||||
found = iterate_decoder_pads (self, element, stream_id, type);
|
||||
|
||||
g_value_unset (&value);
|
||||
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
|
||||
gst_iterator_free (iter);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static void
|
||||
update_current_decoder (GstClapper *self, GstElementFactoryListType type)
|
||||
{
|
||||
GstIterator *iter;
|
||||
GValue value = { 0, };
|
||||
|
||||
iter = gst_bin_iterate_all_by_element_factory_name (
|
||||
GST_BIN (self->playbin), "input-selector");
|
||||
|
||||
while (gst_iterator_next (iter, &value) == GST_ITERATOR_OK) {
|
||||
GstElement *element = g_value_get_object (&value);
|
||||
GstPad *active_pad;
|
||||
gboolean found = FALSE;
|
||||
|
||||
g_object_get (G_OBJECT (element), "active-pad", &active_pad, NULL);
|
||||
|
||||
if (active_pad) {
|
||||
gchar *stream_id;
|
||||
|
||||
stream_id = gst_pad_get_stream_id (active_pad);
|
||||
gst_object_unref (active_pad);
|
||||
|
||||
if (stream_id) {
|
||||
found = find_active_decoder_with_stream_id (self, type, stream_id);
|
||||
g_free (stream_id);
|
||||
}
|
||||
}
|
||||
|
||||
g_value_unset (&value);
|
||||
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
|
||||
gst_iterator_free (iter);
|
||||
}
|
||||
|
||||
static void
|
||||
current_video_notify_cb (G_GNUC_UNUSED GObject * obj, G_GNUC_UNUSED GParamSpec * pspec,
|
||||
GstClapper * self)
|
||||
{
|
||||
GstElementFactoryListType type = GST_ELEMENT_FACTORY_TYPE_DECODER
|
||||
| GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO;
|
||||
|
||||
update_current_decoder (self, type);
|
||||
}
|
||||
|
||||
static void
|
||||
current_audio_notify_cb (G_GNUC_UNUSED GObject * obj, G_GNUC_UNUSED GParamSpec * pspec,
|
||||
GstClapper * self)
|
||||
{
|
||||
GstElementFactoryListType type = GST_ELEMENT_FACTORY_TYPE_DECODER
|
||||
| GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO;
|
||||
|
||||
update_current_decoder (self, type);
|
||||
}
|
||||
|
||||
static void
|
||||
element_setup_cb (GstElement * playbin, GstElement * element, GstClapper * self)
|
||||
{
|
||||
@@ -3054,13 +3174,6 @@ element_setup_cb (GstElement * playbin, GstElement * element, GstClapper * self)
|
||||
if (plugin_name) {
|
||||
GST_INFO_OBJECT (self, "Plugin setup: %s", plugin_name);
|
||||
|
||||
if (gst_element_factory_list_is_type (factory,
|
||||
GST_ELEMENT_FACTORY_TYPE_DECODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO))
|
||||
emit_decoder_changed (self, plugin_name, TRUE);
|
||||
else if (gst_element_factory_list_is_type (factory,
|
||||
GST_ELEMENT_FACTORY_TYPE_DECODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO))
|
||||
emit_decoder_changed (self, plugin_name, FALSE);
|
||||
|
||||
/* TODO: Set plugin props */
|
||||
}
|
||||
g_free (plugin_name);
|
||||
@@ -3229,6 +3342,11 @@ gst_clapper_main (gpointer data)
|
||||
G_CALLBACK (audio_tags_changed_cb), self);
|
||||
g_signal_connect (self->playbin, "text-tags-changed",
|
||||
G_CALLBACK (subtitle_tags_changed_cb), self);
|
||||
|
||||
g_signal_connect (self->playbin, "notify::current-video",
|
||||
G_CALLBACK (current_video_notify_cb), self);
|
||||
g_signal_connect (self->playbin, "notify::current-audio",
|
||||
G_CALLBACK (current_audio_notify_cb), self);
|
||||
}
|
||||
|
||||
g_signal_connect (self->playbin, "notify::volume",
|
||||
@@ -3255,7 +3373,6 @@ gst_clapper_main (gpointer data)
|
||||
gst_object_unref (bus);
|
||||
|
||||
remove_tick_source (self);
|
||||
remove_ready_timeout_source (self);
|
||||
|
||||
g_mutex_lock (&self->lock);
|
||||
if (self->media_info) {
|
||||
@@ -3324,6 +3441,104 @@ gst_clapper_has_plugin_with_features (const gchar * name)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_feature_name (gchar * str, const gchar ** feature)
|
||||
{
|
||||
if (!str)
|
||||
return FALSE;
|
||||
|
||||
g_strstrip (str);
|
||||
|
||||
if (str[0] != '\0') {
|
||||
*feature = str;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_feature_rank (gchar * str, GstRank * rank)
|
||||
{
|
||||
if (!str)
|
||||
return FALSE;
|
||||
|
||||
g_strstrip (str);
|
||||
|
||||
if (g_ascii_isdigit (str[0])) {
|
||||
unsigned long l;
|
||||
char *endptr;
|
||||
l = strtoul (str, &endptr, 10);
|
||||
if (endptr > str && endptr[0] == 0) {
|
||||
*rank = (GstRank) l;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
} else if (g_ascii_strcasecmp (str, "NONE") == 0) {
|
||||
*rank = GST_RANK_NONE;
|
||||
} else if (g_ascii_strcasecmp (str, "MARGINAL") == 0) {
|
||||
*rank = GST_RANK_MARGINAL;
|
||||
} else if (g_ascii_strcasecmp (str, "SECONDARY") == 0) {
|
||||
*rank = GST_RANK_SECONDARY;
|
||||
} else if (g_ascii_strcasecmp (str, "PRIMARY") == 0) {
|
||||
*rank = GST_RANK_PRIMARY;
|
||||
} else if (g_ascii_strcasecmp (str, "MAX") == 0) {
|
||||
*rank = (GstRank) G_MAXINT;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_env_feature_rank_update (void)
|
||||
{
|
||||
const gchar *env;
|
||||
gchar **split, **walk;
|
||||
|
||||
env = g_getenv ("GST_PLUGIN_FEATURE_RANK");
|
||||
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
split = g_strsplit (env, ",", 0);
|
||||
|
||||
for (walk = split; *walk; walk++) {
|
||||
if (strchr (*walk, ':')) {
|
||||
gchar **values;
|
||||
|
||||
values = g_strsplit (*walk, ":", 2);
|
||||
if (values[0] && values[1]) {
|
||||
GstRank rank;
|
||||
const gchar *name;
|
||||
|
||||
if (parse_feature_name (values[0], &name)
|
||||
&& parse_feature_rank (values[1], &rank)) {
|
||||
GstPluginFeature *feature;
|
||||
|
||||
feature = gst_registry_find_feature (gst_registry_get (), name,
|
||||
GST_TYPE_ELEMENT_FACTORY);
|
||||
if (feature) {
|
||||
GstRank old_rank;
|
||||
|
||||
old_rank = gst_plugin_feature_get_rank (feature);
|
||||
if (old_rank != rank) {
|
||||
gst_plugin_feature_set_rank (feature, rank);
|
||||
GST_DEBUG ("Updated rank from env: %i -> %i for %s", old_rank, rank, name);
|
||||
}
|
||||
gst_object_unref (feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_strfreev (values);
|
||||
}
|
||||
}
|
||||
|
||||
g_strfreev (split);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_prepare_gstreamer (void)
|
||||
{
|
||||
@@ -3346,6 +3561,9 @@ gst_clapper_prepare_gstreamer (void)
|
||||
gst_clapper_set_feature_rank ("v4l2slvp8dec", GST_RANK_NONE);
|
||||
}
|
||||
|
||||
/* After setting defaults, update them from ENV */
|
||||
_env_feature_rank_update ();
|
||||
|
||||
gst_clapper_gstreamer_prepared = TRUE;
|
||||
GST_DEBUG ("GStreamer plugins prepared");
|
||||
}
|
||||
@@ -3422,7 +3640,6 @@ gst_clapper_play_internal (gpointer user_data)
|
||||
}
|
||||
g_mutex_unlock (&self->lock);
|
||||
|
||||
remove_ready_timeout_source (self);
|
||||
self->target_state = GST_STATE_PLAYING;
|
||||
|
||||
if (self->current_state < GST_STATE_PAUSED)
|
||||
@@ -3490,7 +3707,6 @@ gst_clapper_pause_internal (gpointer user_data)
|
||||
|
||||
tick_cb (self);
|
||||
remove_tick_source (self);
|
||||
remove_ready_timeout_source (self);
|
||||
|
||||
self->target_state = GST_STATE_PAUSED;
|
||||
|
||||
@@ -3570,13 +3786,11 @@ gst_clapper_stop_internal (GstClapper * self, gboolean transient)
|
||||
tick_cb (self);
|
||||
remove_tick_source (self);
|
||||
|
||||
add_ready_timeout_source (self);
|
||||
|
||||
self->target_state = GST_STATE_NULL;
|
||||
self->current_state = GST_STATE_READY;
|
||||
self->current_state = GST_STATE_NULL;
|
||||
self->is_live = FALSE;
|
||||
gst_bus_set_flushing (self->bus, TRUE);
|
||||
gst_element_set_state (self->playbin, GST_STATE_READY);
|
||||
gst_element_set_state (self->playbin, GST_STATE_NULL);
|
||||
gst_bus_set_flushing (self->bus, FALSE);
|
||||
change_state (self, transient && self->app_state != GST_CLAPPER_STATE_STOPPED
|
||||
? GST_CLAPPER_STATE_BUFFERING : GST_CLAPPER_STATE_STOPPED);
|
||||
|
@@ -372,8 +372,10 @@ gst_clapper_gl_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
|
||||
gst_buffer_pool_config_add_option (config,
|
||||
GST_BUFFER_POOL_OPTION_GL_SYNC_META);
|
||||
|
||||
if (!gst_buffer_pool_set_config (pool, config))
|
||||
if (!gst_buffer_pool_set_config (pool, config)) {
|
||||
gst_object_unref (pool);
|
||||
goto config_failed;
|
||||
}
|
||||
}
|
||||
|
||||
/* we need at least 2 buffer because we hold on to the last one */
|
||||
|
33
lib/gst/clapper/meson.build
vendored
33
lib/gst/clapper/meson.build
vendored
@@ -34,36 +34,13 @@ gstclapper_defines = [
|
||||
'-DGST_USE_UNSTABLE_API',
|
||||
'-DHAVE_GTK_GL',
|
||||
]
|
||||
gtk_deps = [gstgl_dep, gstglproto_dep]
|
||||
have_gtk_gl_windowing = false
|
||||
|
||||
gtk4_dep = dependency('gtk4', required: true)
|
||||
|
||||
if not gtk4_dep.version().version_compare('>=4.0.0')
|
||||
error('GTK4 version on this system is too old')
|
||||
if not get_option('lib')
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
if gst_gl_have_window_x11 and (gst_gl_have_platform_egl or gst_gl_have_platform_glx)
|
||||
gtk_x11_dep = dependency('gtk4-x11', required: false)
|
||||
if gtk_x11_dep.found()
|
||||
gtk_deps += gtk_x11_dep
|
||||
if gst_gl_have_platform_glx
|
||||
gtk_deps += gstglx11_dep
|
||||
endif
|
||||
have_gtk_gl_windowing = true
|
||||
endif
|
||||
endif
|
||||
|
||||
if gst_gl_have_window_wayland and gst_gl_have_platform_egl
|
||||
gtk_wayland_dep = dependency('gtk4-wayland', required: false)
|
||||
if gtk_wayland_dep.found()
|
||||
gtk_deps += [gtk_wayland_dep, gstglwayland_dep]
|
||||
have_gtk_gl_windowing = true
|
||||
endif
|
||||
endif
|
||||
|
||||
if gst_gl_have_platform_egl
|
||||
gtk_deps += gstglegl_dep
|
||||
if not gir.found()
|
||||
error('Clapper lib requires GI bindings to be compiled')
|
||||
endif
|
||||
|
||||
if not have_gtk_gl_windowing
|
||||
@@ -84,7 +61,7 @@ gstclapper = library('gstclapper-' + api_version,
|
||||
version: libversion,
|
||||
install: true,
|
||||
install_dir: pkglibdir,
|
||||
dependencies: [gtk4_dep, glib_dep, gio_dep,
|
||||
dependencies: [gtk4_dep, glib_dep, gio_dep, giounix_dep,
|
||||
gstbase_dep, gstvideo_dep, gstaudio_dep,
|
||||
gsttag_dep, gstpbutils_dep, libm] + gtk_deps,
|
||||
)
|
||||
|
1
lib/gst/meson.build
vendored
1
lib/gst/meson.build
vendored
@@ -1 +1,2 @@
|
||||
subdir('clapper')
|
||||
subdir('plugin')
|
||||
|
374
lib/gst/plugin/gstclapperbaseimport.c
vendored
Normal file
374
lib/gst/plugin/gstclapperbaseimport.c
vendored
Normal file
@@ -0,0 +1,374 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstclapperbaseimport.h"
|
||||
#include "gstclappergdkmemory.h"
|
||||
#include "gstclappergdkbufferpool.h"
|
||||
|
||||
#define GST_CAT_DEFAULT gst_clapper_base_import_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
#define parent_class gst_clapper_base_import_parent_class
|
||||
G_DEFINE_TYPE (GstClapperBaseImport, gst_clapper_base_import, GST_TYPE_BASE_TRANSFORM);
|
||||
|
||||
static void
|
||||
gst_clapper_base_import_init (GstClapperBaseImport *self)
|
||||
{
|
||||
g_mutex_init (&self->lock);
|
||||
|
||||
gst_video_info_init (&self->in_info);
|
||||
gst_video_info_init (&self->out_info);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_base_import_finalize (GObject *object)
|
||||
{
|
||||
GstClapperBaseImport *self = GST_CLAPPER_BASE_IMPORT_CAST (object);
|
||||
|
||||
GST_TRACE ("Finalize");
|
||||
g_mutex_clear (&self->lock);
|
||||
|
||||
GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_clapper_base_import_change_state (GstElement *element, GstStateChange transition)
|
||||
{
|
||||
GST_DEBUG_OBJECT (element, "Changing state: %s => %s",
|
||||
gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)),
|
||||
gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition)));
|
||||
|
||||
return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_base_import_start (GstBaseTransform *bt)
|
||||
{
|
||||
GST_INFO_OBJECT (bt, "Start");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_base_import_stop (GstBaseTransform *bt)
|
||||
{
|
||||
GST_INFO_OBJECT (bt, "Stop");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_clapper_base_import_transform_caps (GstBaseTransform *bt,
|
||||
GstPadDirection direction, GstCaps *caps, GstCaps *filter)
|
||||
{
|
||||
GstCaps *result, *tmp;
|
||||
|
||||
tmp = (direction == GST_PAD_SINK)
|
||||
? gst_pad_get_pad_template_caps (GST_BASE_TRANSFORM_SRC_PAD (bt))
|
||||
: gst_pad_get_pad_template_caps (GST_BASE_TRANSFORM_SINK_PAD (bt));
|
||||
|
||||
if (filter) {
|
||||
GST_DEBUG ("Intersecting with filter caps: %" GST_PTR_FORMAT, filter);
|
||||
result = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST);
|
||||
gst_caps_unref (tmp);
|
||||
} else {
|
||||
result = tmp;
|
||||
}
|
||||
GST_DEBUG ("Returning %s caps: %" GST_PTR_FORMAT,
|
||||
(direction == GST_PAD_SINK) ? "src" : "sink", result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_structure_filter_cb (GQuark field_id, GValue *value,
|
||||
G_GNUC_UNUSED gpointer user_data)
|
||||
{
|
||||
const gchar *str = g_quark_to_string (field_id);
|
||||
|
||||
if (!strcmp (str, "format")
|
||||
|| !strcmp (str, "width")
|
||||
|| !strcmp (str, "height")
|
||||
|| !strcmp (str, "pixel-aspect-ratio")
|
||||
|| !strcmp (str, "framerate"))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_clapper_base_import_fixate_caps (GstBaseTransform *bt,
|
||||
GstPadDirection direction, GstCaps *caps, GstCaps *othercaps)
|
||||
{
|
||||
GstCaps *fixated;
|
||||
|
||||
fixated = (!gst_caps_is_any (caps))
|
||||
? gst_caps_fixate (gst_caps_ref (caps))
|
||||
: gst_caps_copy (caps);
|
||||
|
||||
if (direction == GST_PAD_SINK) {
|
||||
guint i, n = gst_caps_get_size (fixated);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
GstCapsFeatures *features;
|
||||
GstStructure *structure;
|
||||
gboolean had_overlay_comp;
|
||||
|
||||
features = gst_caps_get_features (fixated, i);
|
||||
had_overlay_comp = gst_caps_features_contains (features,
|
||||
GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION);
|
||||
|
||||
features = gst_caps_features_new (GST_CAPS_FEATURE_CLAPPER_GDK_MEMORY, NULL);
|
||||
if (had_overlay_comp)
|
||||
gst_caps_features_add (features, GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION);
|
||||
|
||||
gst_caps_set_features (fixated, i, features);
|
||||
|
||||
/* Remove fields that do not apply to our memory */
|
||||
if ((structure = gst_caps_get_structure (fixated, i))) {
|
||||
gst_structure_filter_and_map_in_place (structure,
|
||||
(GstStructureFilterMapFunc) _structure_filter_cb, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
GST_DEBUG ("Fixated %s caps: %" GST_PTR_FORMAT,
|
||||
(direction == GST_PAD_SRC) ? "sink" : "src", fixated);
|
||||
|
||||
return fixated;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_base_import_set_caps (GstBaseTransform *bt,
|
||||
GstCaps *incaps, GstCaps *outcaps)
|
||||
{
|
||||
GstClapperBaseImport *self = GST_CLAPPER_BASE_IMPORT_CAST (bt);
|
||||
gboolean has_sink_info, has_src_info;
|
||||
|
||||
if ((has_sink_info = gst_video_info_from_caps (&self->in_info, incaps)))
|
||||
GST_INFO_OBJECT (self, "Set sink caps: %" GST_PTR_FORMAT, incaps);
|
||||
if ((has_src_info = gst_video_info_from_caps (&self->out_info, outcaps)))
|
||||
GST_INFO_OBJECT (self, "Set src caps: %" GST_PTR_FORMAT, outcaps);
|
||||
|
||||
return (has_sink_info && has_src_info);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_base_import_import_propose_allocation (GstBaseTransform *bt,
|
||||
GstQuery *decide_query, GstQuery *query)
|
||||
{
|
||||
GstClapperBaseImport *self = GST_CLAPPER_BASE_IMPORT_CAST (bt);
|
||||
GstClapperBaseImportClass *bi_class = GST_CLAPPER_BASE_IMPORT_GET_CLASS (self);
|
||||
GstBufferPool *pool = NULL;
|
||||
GstCaps *caps;
|
||||
GstVideoInfo info;
|
||||
guint size;
|
||||
gboolean need_pool;
|
||||
|
||||
if (!GST_BASE_TRANSFORM_CLASS (parent_class)->propose_allocation (bt,
|
||||
decide_query, query))
|
||||
return FALSE;
|
||||
|
||||
/* Passthrough, nothing to do */
|
||||
if (!decide_query)
|
||||
return TRUE;
|
||||
|
||||
gst_query_parse_allocation (query, &caps, &need_pool);
|
||||
|
||||
if (!caps) {
|
||||
GST_DEBUG_OBJECT (self, "No caps specified");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gst_video_info_from_caps (&info, caps)) {
|
||||
GST_DEBUG_OBJECT (self, "Invalid caps specified");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Normal size of a frame */
|
||||
size = GST_VIDEO_INFO_SIZE (&info);
|
||||
|
||||
if (need_pool) {
|
||||
GstStructure *config = NULL;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Need to create upstream pool");
|
||||
pool = bi_class->create_upstream_pool (self, &config);
|
||||
|
||||
if (pool) {
|
||||
/* If we did not get config, use default one */
|
||||
if (!config)
|
||||
config = gst_buffer_pool_get_config (pool);
|
||||
|
||||
gst_buffer_pool_config_set_params (config, caps, size, 2, 0);
|
||||
|
||||
if (!gst_buffer_pool_set_config (pool, config)) {
|
||||
gst_object_unref (pool);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Failed to set config");
|
||||
return FALSE;
|
||||
}
|
||||
} else if (config) {
|
||||
GST_WARNING_OBJECT (self, "Got pool config without a pool to apply it!");
|
||||
gst_structure_free (config);
|
||||
}
|
||||
}
|
||||
|
||||
gst_query_add_allocation_pool (query, pool, size, 2, 0);
|
||||
if (pool)
|
||||
gst_object_unref (pool);
|
||||
|
||||
gst_query_add_allocation_meta (query,
|
||||
GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL);
|
||||
gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_base_import_decide_allocation (GstBaseTransform *bt, GstQuery *query)
|
||||
{
|
||||
GstClapperBaseImport *self = GST_CLAPPER_BASE_IMPORT_CAST (bt);
|
||||
GstBufferPool *pool = NULL;
|
||||
GstCaps *caps;
|
||||
GstVideoInfo info;
|
||||
guint size = 0, min = 0, max = 0;
|
||||
gboolean update_pool, need_pool = TRUE;
|
||||
|
||||
gst_query_parse_allocation (query, &caps, NULL);
|
||||
|
||||
if (!caps) {
|
||||
GST_DEBUG_OBJECT (self, "No caps specified");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gst_video_info_from_caps (&info, caps)) {
|
||||
GST_DEBUG_OBJECT (self, "Invalid caps specified");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((update_pool = gst_query_get_n_allocation_pools (query) > 0)) {
|
||||
gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
|
||||
if (pool) {
|
||||
if ((need_pool = !GST_IS_CLAPPER_GDK_BUFFER_POOL (pool)))
|
||||
gst_clear_object (&pool);
|
||||
}
|
||||
} else {
|
||||
size = GST_VIDEO_INFO_SIZE (&info);
|
||||
}
|
||||
|
||||
if (need_pool) {
|
||||
GstStructure *config;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Creating new downstream pool");
|
||||
|
||||
pool = gst_clapper_gdk_buffer_pool_new ();
|
||||
config = gst_buffer_pool_get_config (pool);
|
||||
|
||||
gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
|
||||
gst_buffer_pool_config_set_params (config, caps, size, min, max);
|
||||
|
||||
if (!gst_buffer_pool_set_config (pool, config)) {
|
||||
gst_object_unref (pool);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Failed to set config");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (update_pool)
|
||||
gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
|
||||
else
|
||||
gst_query_add_allocation_pool (query, pool, size, min, max);
|
||||
|
||||
if (pool)
|
||||
gst_object_unref (pool);
|
||||
|
||||
return GST_BASE_TRANSFORM_CLASS (parent_class)->decide_allocation (bt, query);
|
||||
}
|
||||
|
||||
static GstBufferPool *
|
||||
gst_clapper_base_import_create_upstream_pool (GstClapperBaseImport *self, GstStructure **config)
|
||||
{
|
||||
GST_FIXME_OBJECT (self, "Need to create upstream buffer pool");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_base_import_class_init (GstClapperBaseImportClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
GstElementClass *gstelement_class = (GstElementClass *) klass;
|
||||
GstBaseTransformClass *gstbasetransform_class = (GstBaseTransformClass *) klass;
|
||||
GstClapperBaseImportClass *bi_class = (GstClapperBaseImportClass *) klass;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperbaseimport", 0,
|
||||
"Clapper Base Import");
|
||||
|
||||
gobject_class->finalize = gst_clapper_base_import_finalize;
|
||||
|
||||
gstelement_class->change_state = gst_clapper_base_import_change_state;
|
||||
|
||||
gstbasetransform_class->passthrough_on_same_caps = TRUE;
|
||||
gstbasetransform_class->transform_ip_on_passthrough = FALSE;
|
||||
gstbasetransform_class->start = gst_clapper_base_import_start;
|
||||
gstbasetransform_class->stop = gst_clapper_base_import_stop;
|
||||
gstbasetransform_class->transform_caps = gst_clapper_base_import_transform_caps;
|
||||
gstbasetransform_class->fixate_caps = gst_clapper_base_import_fixate_caps;
|
||||
gstbasetransform_class->set_caps = gst_clapper_base_import_set_caps;
|
||||
gstbasetransform_class->propose_allocation = gst_clapper_base_import_import_propose_allocation;
|
||||
gstbasetransform_class->decide_allocation = gst_clapper_base_import_decide_allocation;
|
||||
|
||||
bi_class->create_upstream_pool = gst_clapper_base_import_create_upstream_pool;
|
||||
}
|
||||
|
||||
/*
|
||||
* Maps input video frame and output memory from in/out buffers
|
||||
* using flags passed to this method.
|
||||
*
|
||||
* Remember to unmap both using `gst_video_frame_unmap` and
|
||||
* `gst_memory_unmap` when done with the data.
|
||||
*/
|
||||
gboolean
|
||||
gst_clapper_base_import_map_buffers (GstClapperBaseImport *self,
|
||||
GstBuffer *in_buf, GstBuffer *out_buf, GstMapFlags in_flags, GstMapFlags out_flags,
|
||||
GstVideoFrame *frame, GstMapInfo *info, GstMemory **mem)
|
||||
{
|
||||
GST_LOG_OBJECT (self, "Transforming from %" GST_PTR_FORMAT
|
||||
" into %" GST_PTR_FORMAT, in_buf, out_buf);
|
||||
|
||||
if (G_UNLIKELY (!gst_video_frame_map (frame, &self->in_info, in_buf, in_flags))) {
|
||||
GST_ERROR_OBJECT (self, "Could not map input buffer for reading");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*mem = gst_buffer_peek_memory (out_buf, 0);
|
||||
|
||||
if (G_UNLIKELY (!gst_memory_map (*mem, info, out_flags))) {
|
||||
GST_ERROR_OBJECT (self, "Could not map output memory for writing");
|
||||
gst_video_frame_unmap (frame);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
69
lib/gst/plugin/gstclapperbaseimport.h
vendored
Normal file
69
lib/gst/plugin/gstclapperbaseimport.h
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gst/base/gstbasetransform.h>
|
||||
#include <gst/video/video.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_CLAPPER_BASE_IMPORT (gst_clapper_base_import_get_type())
|
||||
#define GST_IS_CLAPPER_BASE_IMPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_CLAPPER_BASE_IMPORT))
|
||||
#define GST_IS_CLAPPER_BASE_IMPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_CLAPPER_BASE_IMPORT))
|
||||
#define GST_CLAPPER_BASE_IMPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_CLAPPER_BASE_IMPORT, GstClapperBaseImportClass))
|
||||
#define GST_CLAPPER_BASE_IMPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_CLAPPER_BASE_IMPORT, GstClapperBaseImport))
|
||||
#define GST_CLAPPER_BASE_IMPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_CLAPPER_BASE_IMPORT, GstClapperBaseImportClass))
|
||||
#define GST_CLAPPER_BASE_IMPORT_CAST(obj) ((GstClapperBaseImport *)(obj))
|
||||
|
||||
#define GST_CLAPPER_BASE_IMPORT_GET_LOCK(obj) (&GST_CLAPPER_BASE_IMPORT_CAST(obj)->lock)
|
||||
#define GST_CLAPPER_BASE_IMPORT_LOCK(obj) g_mutex_lock (GST_CLAPPER_BASE_IMPORT_GET_LOCK(obj))
|
||||
#define GST_CLAPPER_BASE_IMPORT_UNLOCK(obj) g_mutex_unlock (GST_CLAPPER_BASE_IMPORT_GET_LOCK(obj))
|
||||
|
||||
typedef struct _GstClapperBaseImport GstClapperBaseImport;
|
||||
typedef struct _GstClapperBaseImportClass GstClapperBaseImportClass;
|
||||
|
||||
#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GstClapperBaseImport, gst_object_unref)
|
||||
#endif
|
||||
|
||||
struct _GstClapperBaseImport
|
||||
{
|
||||
GstBaseTransform parent;
|
||||
|
||||
GMutex lock;
|
||||
|
||||
GstVideoInfo in_info, out_info;
|
||||
};
|
||||
|
||||
struct _GstClapperBaseImportClass
|
||||
{
|
||||
GstBaseTransformClass parent_class;
|
||||
|
||||
GstBufferPool * (* create_upstream_pool) (GstClapperBaseImport *bi,
|
||||
GstStructure **config);
|
||||
};
|
||||
|
||||
GType gst_clapper_base_import_get_type (void);
|
||||
|
||||
gboolean gst_clapper_base_import_map_buffers (GstClapperBaseImport *bi,
|
||||
GstBuffer *in_buf, GstBuffer *out_buf, GstMapFlags in_flags, GstMapFlags out_flags,
|
||||
GstVideoFrame *frame, GstMapInfo *info, GstMemory **mem);
|
||||
|
||||
G_END_DECLS
|
173
lib/gst/plugin/gstclappergdkbufferpool.c
vendored
Normal file
173
lib/gst/plugin/gstclappergdkbufferpool.c
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstclappergdkbufferpool.h"
|
||||
|
||||
#define GST_CAT_DEFAULT gst_clapper_gdk_buffer_pool_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
#define parent_class gst_clapper_gdk_buffer_pool_parent_class
|
||||
G_DEFINE_TYPE (GstClapperGdkBufferPool, gst_clapper_gdk_buffer_pool, GST_TYPE_BUFFER_POOL);
|
||||
|
||||
static void
|
||||
gst_clapper_gdk_buffer_pool_init (GstClapperGdkBufferPool *pool)
|
||||
{
|
||||
}
|
||||
|
||||
static const gchar **
|
||||
gst_clapper_gdk_buffer_pool_get_options (GstBufferPool *pool)
|
||||
{
|
||||
static const gchar *options[] = {
|
||||
GST_BUFFER_POOL_OPTION_VIDEO_META,
|
||||
NULL
|
||||
};
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_gdk_buffer_pool_set_config (GstBufferPool *pool, GstStructure *config)
|
||||
{
|
||||
GstClapperGdkBufferPool *self = GST_CLAPPER_GDK_BUFFER_POOL_CAST (pool);
|
||||
GstCaps *caps = NULL;
|
||||
guint size, min_buffers, max_buffers;
|
||||
GstVideoInfo info;
|
||||
GstClapperGdkMemory *clapper_mem;
|
||||
|
||||
if (!gst_buffer_pool_config_get_params (config, &caps, &size,
|
||||
&min_buffers, &max_buffers)) {
|
||||
GST_WARNING_OBJECT (self, "Invalid buffer pool config");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!caps || !gst_video_info_from_caps (&info, caps)) {
|
||||
GST_WARNING_OBJECT (pool, "Could not parse caps into video info");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gst_clear_object (&self->allocator);
|
||||
self->allocator = GST_CLAPPER_GDK_ALLOCATOR_CAST (
|
||||
gst_allocator_find (GST_CLAPPER_GDK_MEMORY_TYPE_NAME));
|
||||
|
||||
if (G_UNLIKELY (!self->allocator)) {
|
||||
GST_ERROR_OBJECT (self, "ClapperGdkAllocator is unavailable");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
clapper_mem = GST_CLAPPER_GDK_MEMORY_CAST (
|
||||
gst_clapper_gdk_allocator_alloc (self->allocator, &info));
|
||||
if (G_UNLIKELY (!clapper_mem)) {
|
||||
GST_ERROR_OBJECT (self, "Cannot create ClapperGdkMemory");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gst_buffer_pool_config_set_params (config, caps,
|
||||
GST_VIDEO_INFO_SIZE (&clapper_mem->info), min_buffers, max_buffers);
|
||||
gst_memory_unref (GST_MEMORY_CAST (clapper_mem));
|
||||
|
||||
self->info = info;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Set buffer pool config: %" GST_PTR_FORMAT, config);
|
||||
|
||||
return GST_BUFFER_POOL_CLASS (parent_class)->set_config (pool, config);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_clapper_gdk_buffer_pool_alloc (GstBufferPool *pool, GstBuffer **buffer,
|
||||
GstBufferPoolAcquireParams *params)
|
||||
{
|
||||
GstClapperGdkBufferPool *self = GST_CLAPPER_GDK_BUFFER_POOL_CAST (pool);
|
||||
GstMemory *mem;
|
||||
GstClapperGdkMemory *clapper_mem;
|
||||
|
||||
mem = gst_clapper_gdk_allocator_alloc (self->allocator, &self->info);
|
||||
if (G_UNLIKELY (!mem)) {
|
||||
GST_ERROR_OBJECT (self, "Cannot create ClapperGdkMemory");
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
clapper_mem = GST_CLAPPER_GDK_MEMORY_CAST (mem);
|
||||
|
||||
*buffer = gst_buffer_new ();
|
||||
gst_buffer_append_memory (*buffer, mem);
|
||||
|
||||
gst_buffer_add_video_meta_full (*buffer, GST_VIDEO_FRAME_FLAG_NONE,
|
||||
GST_VIDEO_INFO_FORMAT (&self->info), GST_VIDEO_INFO_WIDTH (&self->info),
|
||||
GST_VIDEO_INFO_HEIGHT (&self->info), GST_VIDEO_INFO_N_PLANES (&self->info),
|
||||
clapper_mem->info.offset, clapper_mem->info.stride);
|
||||
|
||||
GST_TRACE_OBJECT (self, "Allocated %" GST_PTR_FORMAT, *buffer);
|
||||
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gdk_buffer_reset_buffer (GstBufferPool *pool, GstBuffer *buffer)
|
||||
{
|
||||
GstClapperGdkMemory *clapper_mem;
|
||||
|
||||
GST_TRACE ("Reset %" GST_PTR_FORMAT, buffer);
|
||||
|
||||
clapper_mem = GST_CLAPPER_GDK_MEMORY_CAST (gst_buffer_peek_memory (buffer, 0));
|
||||
g_clear_object (&clapper_mem->texture);
|
||||
|
||||
return GST_BUFFER_POOL_CLASS (parent_class)->reset_buffer (pool, buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gdk_buffer_pool_dispose (GObject *object)
|
||||
{
|
||||
GstClapperGdkBufferPool *self = GST_CLAPPER_GDK_BUFFER_POOL_CAST (object);
|
||||
|
||||
gst_clear_object (&self->allocator);
|
||||
|
||||
GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gdk_buffer_pool_class_init (GstClapperGdkBufferPoolClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
GstBufferPoolClass *bufferpool_class = (GstBufferPoolClass *) klass;
|
||||
|
||||
gobject_class->dispose = gst_clapper_gdk_buffer_pool_dispose;
|
||||
|
||||
bufferpool_class->get_options = gst_clapper_gdk_buffer_pool_get_options;
|
||||
bufferpool_class->set_config = gst_clapper_gdk_buffer_pool_set_config;
|
||||
bufferpool_class->alloc_buffer = gst_clapper_gdk_buffer_pool_alloc;
|
||||
bufferpool_class->reset_buffer = gst_clapper_gdk_buffer_reset_buffer;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clappergdkbufferpool", 0,
|
||||
"Clapper Gdk Buffer Pool");
|
||||
}
|
||||
|
||||
GstBufferPool *
|
||||
gst_clapper_gdk_buffer_pool_new (void)
|
||||
{
|
||||
GstClapperGdkBufferPool *self;
|
||||
|
||||
self = g_object_new (GST_TYPE_CLAPPER_GDK_BUFFER_POOL, NULL);
|
||||
gst_object_ref_sink (self);
|
||||
|
||||
return GST_BUFFER_POOL_CAST (self);
|
||||
}
|
44
lib/gst/plugin/gstclappergdkbufferpool.h
vendored
Normal file
44
lib/gst/plugin/gstclappergdkbufferpool.h
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gst/gstbufferpool.h>
|
||||
#include <gst/video/video.h>
|
||||
|
||||
#include "gstclappergdkmemory.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_CLAPPER_GDK_BUFFER_POOL (gst_clapper_gdk_buffer_pool_get_type())
|
||||
G_DECLARE_FINAL_TYPE (GstClapperGdkBufferPool, gst_clapper_gdk_buffer_pool, GST, CLAPPER_GDK_BUFFER_POOL, GstBufferPool)
|
||||
|
||||
#define GST_CLAPPER_GDK_BUFFER_POOL_CAST(obj) ((GstClapperGdkBufferPool *)(obj))
|
||||
|
||||
struct _GstClapperGdkBufferPool
|
||||
{
|
||||
GstBufferPool parent;
|
||||
|
||||
GstClapperGdkAllocator *allocator;
|
||||
GstVideoInfo info;
|
||||
};
|
||||
|
||||
GstBufferPool * gst_clapper_gdk_buffer_pool_new (void);
|
||||
|
||||
G_END_DECLS
|
141
lib/gst/plugin/gstclappergdkmemory.c
vendored
Normal file
141
lib/gst/plugin/gstclappergdkmemory.c
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstclappergdkmemory.h"
|
||||
#include "gstgtkutils.h"
|
||||
|
||||
#define GST_CAT_DEFAULT gst_clapper_gdk_allocator_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
static GstAllocator *_gst_clapper_gdk_allocator = NULL;
|
||||
|
||||
#define parent_class gst_clapper_gdk_allocator_parent_class
|
||||
G_DEFINE_TYPE (GstClapperGdkAllocator, gst_clapper_gdk_allocator, GST_TYPE_ALLOCATOR);
|
||||
|
||||
static void
|
||||
gst_clapper_gdk_allocator_free (GstAllocator *self, GstMemory *memory)
|
||||
{
|
||||
GstClapperGdkMemory *mem = GST_CLAPPER_GDK_MEMORY_CAST (memory);
|
||||
|
||||
GST_TRACE_OBJECT (self, "Freeing ClapperGdkMemory: %" GST_PTR_FORMAT, mem);
|
||||
|
||||
g_clear_object (&mem->texture);
|
||||
g_free (mem);
|
||||
}
|
||||
|
||||
static gpointer
|
||||
gst_clapper_gdk_mem_map_full (GstMemory *memory, GstMapInfo *info, gsize maxsize)
|
||||
{
|
||||
GstClapperGdkMemory *mem = GST_CLAPPER_GDK_MEMORY_CAST (memory);
|
||||
|
||||
return &mem->texture;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gdk_mem_unmap_full (GstMemory *memory, GstMapInfo *info)
|
||||
{
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
static GstMemory *
|
||||
gst_clapper_gdk_mem_copy (GstMemory *memory, gssize offset, gssize size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GstMemory *
|
||||
gst_clapper_gdk_mem_share (GstMemory *memory, gssize offset, gssize size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_gdk_mem_is_span (GstMemory *mem1, GstMemory *mem2, gsize *offset)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gdk_allocator_init (GstClapperGdkAllocator *self)
|
||||
{
|
||||
GstAllocator *alloc = GST_ALLOCATOR_CAST (self);
|
||||
|
||||
alloc->mem_type = GST_CLAPPER_GDK_MEMORY_TYPE_NAME;
|
||||
alloc->mem_map_full = gst_clapper_gdk_mem_map_full;
|
||||
alloc->mem_unmap_full = gst_clapper_gdk_mem_unmap_full;
|
||||
alloc->mem_copy = gst_clapper_gdk_mem_copy;
|
||||
alloc->mem_share = gst_clapper_gdk_mem_share;
|
||||
alloc->mem_is_span = gst_clapper_gdk_mem_is_span;
|
||||
|
||||
GST_OBJECT_FLAG_SET (self, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gdk_allocator_class_init (GstClapperGdkAllocatorClass *klass)
|
||||
{
|
||||
GstAllocatorClass *allocator_class = (GstAllocatorClass *) klass;
|
||||
|
||||
allocator_class->alloc = NULL;
|
||||
allocator_class->free = GST_DEBUG_FUNCPTR (gst_clapper_gdk_allocator_free);
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clappergdkallocator", 0,
|
||||
"Clapper Gdk Allocator");
|
||||
}
|
||||
|
||||
void
|
||||
gst_clapper_gdk_memory_init_once (void)
|
||||
{
|
||||
static gsize _alloc_init = 0;
|
||||
|
||||
if (g_once_init_enter (&_alloc_init)) {
|
||||
_gst_clapper_gdk_allocator = GST_ALLOCATOR_CAST (
|
||||
g_object_new (GST_TYPE_CLAPPER_GDK_ALLOCATOR, NULL));
|
||||
gst_object_ref_sink (_gst_clapper_gdk_allocator);
|
||||
|
||||
gst_allocator_register (GST_CLAPPER_GDK_MEMORY_TYPE_NAME, _gst_clapper_gdk_allocator);
|
||||
g_once_init_leave (&_alloc_init, 1);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_is_clapper_gdk_memory (GstMemory *memory)
|
||||
{
|
||||
return (memory != NULL && memory->allocator != NULL
|
||||
&& GST_IS_CLAPPER_GDK_ALLOCATOR (memory->allocator));
|
||||
}
|
||||
|
||||
GstMemory *
|
||||
gst_clapper_gdk_allocator_alloc (GstClapperGdkAllocator *self, const GstVideoInfo *info)
|
||||
{
|
||||
GstClapperGdkMemory *mem;
|
||||
|
||||
mem = g_new0 (GstClapperGdkMemory, 1);
|
||||
mem->info = *info;
|
||||
|
||||
gst_memory_init (GST_MEMORY_CAST (mem), 0, GST_ALLOCATOR_CAST (self),
|
||||
NULL, GST_VIDEO_INFO_SIZE (info), 0, 0, GST_VIDEO_INFO_SIZE (info));
|
||||
|
||||
GST_TRACE_OBJECT (self, "Allocated new ClapperGdkMemory: %" GST_PTR_FORMAT, mem);
|
||||
|
||||
return GST_MEMORY_CAST (mem);
|
||||
}
|
67
lib/gst/plugin/gstclappergdkmemory.h
vendored
Normal file
67
lib/gst/plugin/gstclappergdkmemory.h
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gst/gstmemory.h>
|
||||
#include <gst/gstallocator.h>
|
||||
#include <gst/video/video.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_CLAPPER_GDK_ALLOCATOR (gst_clapper_gdk_allocator_get_type())
|
||||
G_DECLARE_FINAL_TYPE (GstClapperGdkAllocator, gst_clapper_gdk_allocator, GST, CLAPPER_GDK_ALLOCATOR, GstAllocator)
|
||||
|
||||
#define GST_CLAPPER_GDK_ALLOCATOR_CAST(obj) ((GstClapperGdkAllocator *)(obj))
|
||||
#define GST_CLAPPER_GDK_MEMORY_CAST(mem) ((GstClapperGdkMemory *)(mem))
|
||||
|
||||
#define GST_CLAPPER_GDK_MEMORY_TYPE_NAME "gst.clapper.gdk.memory"
|
||||
|
||||
#define GST_CAPS_FEATURE_CLAPPER_GDK_MEMORY "memory:ClapperGdkMemory"
|
||||
|
||||
#define GST_CLAPPER_GDK_MEMORY_FORMATS \
|
||||
"RGBA64_LE, RGBA64_BE, ABGR, BGRA, " \
|
||||
"ARGB, RGBA, BGRx, RGBx, BGR, RGB" \
|
||||
|
||||
/* Formats that `GdkGLTexture` supports */
|
||||
#define GST_CLAPPER_GDK_GL_TEXTURE_FORMATS \
|
||||
"RGBA64_LE, RGBA64_BE, RGBA, RGBx, RGB" \
|
||||
|
||||
typedef struct _GstClapperGdkMemory GstClapperGdkMemory;
|
||||
struct _GstClapperGdkMemory
|
||||
{
|
||||
GstMemory mem;
|
||||
|
||||
GdkTexture *texture;
|
||||
GstVideoInfo info;
|
||||
};
|
||||
|
||||
struct _GstClapperGdkAllocator
|
||||
{
|
||||
GstAllocator parent;
|
||||
};
|
||||
|
||||
void gst_clapper_gdk_memory_init_once (void);
|
||||
|
||||
gboolean gst_is_clapper_gdk_memory (GstMemory *memory);
|
||||
|
||||
GstMemory * gst_clapper_gdk_allocator_alloc (GstClapperGdkAllocator *allocator, const GstVideoInfo *info);
|
||||
|
||||
G_END_DECLS
|
414
lib/gst/plugin/gstclapperglbaseimport.c
vendored
Normal file
414
lib/gst/plugin/gstclapperglbaseimport.c
vendored
Normal file
@@ -0,0 +1,414 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gst/gl/gstglfuncs.h>
|
||||
|
||||
#include "gstclapperglbaseimport.h"
|
||||
#include "gstgtkutils.h"
|
||||
|
||||
#if GST_CLAPPER_GL_HAVE_WAYLAND
|
||||
#include <gdk/wayland/gdkwayland.h>
|
||||
#include <gst/gl/wayland/gstgldisplay_wayland.h>
|
||||
#endif
|
||||
|
||||
#if GST_CLAPPER_GL_HAVE_X11
|
||||
#include <gdk/x11/gdkx.h>
|
||||
#endif
|
||||
|
||||
#if GST_CLAPPER_GL_HAVE_X11_GLX
|
||||
#include <gst/gl/x11/gstgldisplay_x11.h>
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_HAVE_X11_EGL
|
||||
#include <gst/gl/egl/gstgldisplay_egl.h>
|
||||
#endif
|
||||
|
||||
#define GST_CAT_DEFAULT gst_clapper_gl_base_import_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
#define parent_class gst_clapper_gl_base_import_parent_class
|
||||
G_DEFINE_TYPE (GstClapperGLBaseImport, gst_clapper_gl_base_import, GST_TYPE_CLAPPER_BASE_IMPORT);
|
||||
|
||||
static void
|
||||
gst_clapper_gl_base_import_init (GstClapperGLBaseImport *self)
|
||||
{
|
||||
g_mutex_init (&self->lock);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_base_import_finalize (GObject *object)
|
||||
{
|
||||
GstClapperGLBaseImport *self = GST_CLAPPER_GL_BASE_IMPORT_CAST (object);
|
||||
|
||||
g_clear_object (&self->gdk_context);
|
||||
gst_clear_object (&self->gst_context);
|
||||
gst_clear_object (&self->wrapped_context);
|
||||
gst_clear_object (&self->gst_display);
|
||||
|
||||
g_mutex_clear (&self->lock);
|
||||
|
||||
GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
|
||||
}
|
||||
|
||||
static GstGLContext *
|
||||
wrap_current_gl (GstGLDisplay *display, GdkGLAPI gdk_gl_api, GstGLPlatform platform)
|
||||
{
|
||||
GstGLAPI gst_gl_api = GST_GL_API_NONE;
|
||||
|
||||
switch (gdk_gl_api) {
|
||||
case GDK_GL_API_GL:
|
||||
gst_gl_api = GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
|
||||
break;
|
||||
case GDK_GL_API_GLES:
|
||||
gst_gl_api = GST_GL_API_GLES2;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
if (gst_gl_api != GST_GL_API_NONE) {
|
||||
guintptr gl_handle;
|
||||
|
||||
gst_gl_display_filter_gl_api (display, gst_gl_api);
|
||||
|
||||
if ((gl_handle = gst_gl_context_get_current_gl_context (platform)))
|
||||
return gst_gl_context_new_wrapped (display, gl_handle, platform, gst_gl_api);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
retrieve_gl_context_on_main (GstClapperGLBaseImport *self)
|
||||
{
|
||||
GstClapperGLBaseImportClass *gl_bi_class = GST_CLAPPER_GL_BASE_IMPORT_GET_CLASS (self);
|
||||
GdkDisplay *gdk_display;
|
||||
GdkGLContext *gdk_context;
|
||||
GError *error = NULL;
|
||||
GdkGLAPI gdk_gl_api;
|
||||
GstGLPlatform platform = GST_GL_PLATFORM_NONE;
|
||||
gint gl_major = 0, gl_minor = 0;
|
||||
|
||||
if (!gtk_init_check ()) {
|
||||
GST_ERROR_OBJECT (self, "Could not ensure GTK initialization");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gdk_display = gdk_display_get_default ();
|
||||
|
||||
if (!(gdk_context = gdk_display_create_gl_context (gdk_display, &error))) {
|
||||
GST_ERROR_OBJECT (self, "Error creating Gdk GL context: %s",
|
||||
error ? error->message : "No error set by Gdk");
|
||||
g_clear_error (&error);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gl_bi_class->gdk_context_realize (self, gdk_context)) {
|
||||
GST_ERROR_OBJECT (self, "Could not realize Gdk context: %" GST_PTR_FORMAT,
|
||||
gdk_context);
|
||||
g_object_unref (gdk_context);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
gdk_gl_api = gdk_gl_context_get_api (gdk_context);
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORT_LOCK (self);
|
||||
|
||||
self->gdk_context = gdk_context;
|
||||
|
||||
#if GST_CLAPPER_GL_HAVE_WAYLAND
|
||||
if (GDK_IS_WAYLAND_DISPLAY (gdk_display)) {
|
||||
struct wl_display *wayland_display =
|
||||
gdk_wayland_display_get_wl_display (gdk_display);
|
||||
self->gst_display = (GstGLDisplay *)
|
||||
gst_gl_display_wayland_new_with_display (wayland_display);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GST_CLAPPER_GL_HAVE_X11
|
||||
if (GDK_IS_X11_DISPLAY (gdk_display)) {
|
||||
gpointer display_ptr;
|
||||
#if GST_CLAPPER_GL_HAVE_X11_EGL
|
||||
display_ptr = gdk_x11_display_get_egl_display (gdk_display);
|
||||
if (display_ptr) {
|
||||
self->gst_display = (GstGLDisplay *)
|
||||
gst_gl_display_egl_new_with_egl_display (display_ptr);
|
||||
}
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_HAVE_X11_GLX
|
||||
if (!self->gst_display) {
|
||||
display_ptr = gdk_x11_display_get_xdisplay (gdk_display);
|
||||
self->gst_display = (GstGLDisplay *)
|
||||
gst_gl_display_x11_new_with_display (display_ptr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Fallback to generic display */
|
||||
if (G_UNLIKELY (!self->gst_display)) {
|
||||
GST_WARNING_OBJECT (self, "Unknown Gdk display!");
|
||||
self->gst_display = gst_gl_display_new ();
|
||||
}
|
||||
|
||||
#if GST_CLAPPER_GL_HAVE_WAYLAND
|
||||
if (GST_IS_GL_DISPLAY_WAYLAND (self->gst_display)) {
|
||||
platform = GST_GL_PLATFORM_EGL;
|
||||
GST_INFO_OBJECT (self, "Using EGL on Wayland");
|
||||
goto have_display;
|
||||
}
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_HAVE_X11_EGL
|
||||
if (GST_IS_GL_DISPLAY_EGL (self->gst_display)) {
|
||||
platform = GST_GL_PLATFORM_EGL;
|
||||
GST_INFO_OBJECT (self, "Using EGL on x11");
|
||||
goto have_display;
|
||||
}
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_HAVE_X11_GLX
|
||||
if (GST_IS_GL_DISPLAY_X11 (self->gst_display)) {
|
||||
platform = GST_GL_PLATFORM_GLX;
|
||||
GST_INFO_OBJECT (self, "Using GLX on x11");
|
||||
goto have_display;
|
||||
}
|
||||
#endif
|
||||
|
||||
g_clear_object (&self->gdk_context);
|
||||
gst_clear_object (&self->gst_display);
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORT_UNLOCK (self);
|
||||
|
||||
GST_ERROR_OBJECT (self, "Unsupported GL platform");
|
||||
return FALSE;
|
||||
|
||||
have_display:
|
||||
gdk_gl_context_make_current (self->gdk_context);
|
||||
|
||||
self->wrapped_context = wrap_current_gl (self->gst_display, gdk_gl_api, platform);
|
||||
if (!self->wrapped_context) {
|
||||
GST_ERROR ("Could not retrieve Gdk OpenGL context");
|
||||
gdk_gl_context_clear_current ();
|
||||
|
||||
g_clear_object (&self->gdk_context);
|
||||
gst_clear_object (&self->gst_display);
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORT_UNLOCK (self);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GST_INFO ("Retrieved Gdk OpenGL context %" GST_PTR_FORMAT, self->wrapped_context);
|
||||
gst_gl_context_activate (self->wrapped_context, TRUE);
|
||||
|
||||
if (!gst_gl_context_fill_info (self->wrapped_context, &error)) {
|
||||
GST_ERROR ("Failed to fill Gdk context info: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
|
||||
gst_gl_context_activate (self->wrapped_context, FALSE);
|
||||
|
||||
gst_clear_object (&self->wrapped_context);
|
||||
g_clear_object (&self->gdk_context);
|
||||
gst_clear_object (&self->gst_display);
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORT_UNLOCK (self);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gst_gl_context_get_gl_version (self->wrapped_context, &gl_major, &gl_minor);
|
||||
GST_INFO ("Using OpenGL%s %i.%i", (gdk_gl_api == GDK_GL_API_GLES) ? " ES" : "",
|
||||
gl_major, gl_minor);
|
||||
|
||||
/* Deactivate in both places */
|
||||
gst_gl_context_activate (self->wrapped_context, FALSE);
|
||||
gdk_gl_context_clear_current ();
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORT_UNLOCK (self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_gl_context (GstClapperGLBaseImport *self)
|
||||
{
|
||||
GstGLDisplay *gst_display = NULL;
|
||||
GstGLContext *gst_context = NULL;
|
||||
GError *error = NULL;
|
||||
gboolean has_gdk_contexts;
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORT_LOCK (self);
|
||||
has_gdk_contexts = (self->gdk_context && self->wrapped_context);
|
||||
GST_CLAPPER_GL_BASE_IMPORT_UNLOCK (self);
|
||||
|
||||
if (!has_gdk_contexts) {
|
||||
if (!(! !gst_gtk_invoke_on_main (
|
||||
(GThreadFunc) (GCallback) retrieve_gl_context_on_main, self))) {
|
||||
GST_ERROR_OBJECT (self, "Could not retrieve Gdk GL context");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORT_LOCK (self);
|
||||
|
||||
gst_display = gst_object_ref (self->gst_display);
|
||||
|
||||
/* GstGLDisplay operations require object lock to be held */
|
||||
GST_OBJECT_LOCK (gst_display);
|
||||
|
||||
if (!self->gst_context) {
|
||||
GST_TRACE_OBJECT (self, "Creating new GstGLContext");
|
||||
|
||||
if (!gst_gl_display_create_context (gst_display, self->wrapped_context,
|
||||
&self->gst_context, &error)) {
|
||||
GST_WARNING ("Could not create OpenGL context: %s",
|
||||
error ? error->message : "Unknown");
|
||||
g_clear_error (&error);
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORT_UNLOCK (self);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
gst_context = gst_object_ref (self->gst_context);
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORT_UNLOCK (self);
|
||||
|
||||
/* Calls `set_context` internally, so we cannot be locked here */
|
||||
gst_gl_display_add_context (gst_display, gst_context);
|
||||
gst_gl_element_propagate_display_context (GST_ELEMENT_CAST (self), gst_display);
|
||||
|
||||
GST_OBJECT_UNLOCK (gst_display);
|
||||
|
||||
gst_object_unref (gst_display);
|
||||
gst_object_unref (gst_context);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_base_import_set_context (GstElement *element, GstContext *context)
|
||||
{
|
||||
GstClapperGLBaseImport *self = GST_CLAPPER_GL_BASE_IMPORT_CAST (element);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Set context");
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORT_LOCK (self);
|
||||
gst_gl_handle_set_context (element, context, &self->gst_display,
|
||||
&self->wrapped_context);
|
||||
GST_CLAPPER_GL_BASE_IMPORT_UNLOCK (self);
|
||||
|
||||
GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_clapper_gl_base_import_change_state (GstElement *element, GstStateChange transition)
|
||||
{
|
||||
GstClapperGLBaseImport *self = GST_CLAPPER_GL_BASE_IMPORT_CAST (element);
|
||||
GstStateChangeReturn ret;
|
||||
|
||||
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
||||
if (ret == GST_STATE_CHANGE_FAILURE)
|
||||
return ret;
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||
if (!ensure_gl_context (self))
|
||||
return GST_STATE_CHANGE_FAILURE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_gl_base_import_query (GstBaseTransform *bt,
|
||||
GstPadDirection direction, GstQuery *query)
|
||||
{
|
||||
GstClapperGLBaseImport *self = GST_CLAPPER_GL_BASE_IMPORT_CAST (bt);
|
||||
gboolean res;
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_CONTEXT:
|
||||
GST_CLAPPER_GL_BASE_IMPORT_LOCK (self);
|
||||
res = gst_gl_handle_context_query (GST_ELEMENT_CAST (self), query,
|
||||
self->gst_display, self->gst_context, self->wrapped_context);
|
||||
GST_CLAPPER_GL_BASE_IMPORT_UNLOCK (self);
|
||||
break;
|
||||
default:
|
||||
res = GST_BASE_TRANSFORM_CLASS (parent_class)->query (bt, direction, query);
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_gl_base_import_gdk_context_realize (GstClapperGLBaseImport *self, GdkGLContext *gdk_context)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Realizing GdkGLContext with default implementation");
|
||||
|
||||
gdk_gl_context_set_allowed_apis (gdk_context, GDK_GL_API_GLES);
|
||||
if (!(success = gdk_gl_context_realize (gdk_context, &error))) {
|
||||
GST_WARNING_OBJECT (self, "Could not realize Gdk context with GLES: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
if (!success) {
|
||||
gdk_gl_context_set_allowed_apis (gdk_context, GDK_GL_API_GL);
|
||||
if (!(success = gdk_gl_context_realize (gdk_context, &error))) {
|
||||
GST_WARNING_OBJECT (self, "Could not realize Gdk context with GL: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_base_import_class_init (GstClapperGLBaseImportClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
GstElementClass *gstelement_class = (GstElementClass *) klass;
|
||||
GstBaseTransformClass *gstbasetransform_class = (GstBaseTransformClass *) klass;
|
||||
GstClapperGLBaseImportClass *gl_bi_class = (GstClapperGLBaseImportClass *) klass;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperglbaseimport", 0,
|
||||
"Clapper GL Base Import");
|
||||
|
||||
gobject_class->finalize = gst_clapper_gl_base_import_finalize;
|
||||
|
||||
gstelement_class->set_context = gst_clapper_gl_base_import_set_context;
|
||||
gstelement_class->change_state = gst_clapper_gl_base_import_change_state;
|
||||
|
||||
gstbasetransform_class->query = gst_clapper_gl_base_import_query;
|
||||
|
||||
gl_bi_class->gdk_context_realize = gst_clapper_gl_base_import_gdk_context_realize;
|
||||
}
|
75
lib/gst/plugin/gstclapperglbaseimport.h
vendored
Normal file
75
lib/gst/plugin/gstclapperglbaseimport.h
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gst/gl/gl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "gstclapperbaseimport.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_CLAPPER_GL_BASE_IMPORT (gst_clapper_gl_base_import_get_type())
|
||||
#define GST_IS_CLAPPER_GL_BASE_IMPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_CLAPPER_GL_BASE_IMPORT))
|
||||
#define GST_IS_CLAPPER_GL_BASE_IMPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_CLAPPER_GL_BASE_IMPORT))
|
||||
#define GST_CLAPPER_GL_BASE_IMPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_CLAPPER_GL_BASE_IMPORT, GstClapperGLBaseImportClass))
|
||||
#define GST_CLAPPER_GL_BASE_IMPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_CLAPPER_GL_BASE_IMPORT, GstClapperGLBaseImport))
|
||||
#define GST_CLAPPER_GL_BASE_IMPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_CLAPPER_GL_BASE_IMPORT, GstClapperGLBaseImportClass))
|
||||
#define GST_CLAPPER_GL_BASE_IMPORT_CAST(obj) ((GstClapperGLBaseImport *)(obj))
|
||||
|
||||
#define GST_CLAPPER_GL_BASE_IMPORT_GET_LOCK(obj) (&GST_CLAPPER_GL_BASE_IMPORT_CAST(obj)->lock)
|
||||
#define GST_CLAPPER_GL_BASE_IMPORT_LOCK(obj) g_mutex_lock (GST_CLAPPER_GL_BASE_IMPORT_GET_LOCK(obj))
|
||||
#define GST_CLAPPER_GL_BASE_IMPORT_UNLOCK(obj) g_mutex_unlock (GST_CLAPPER_GL_BASE_IMPORT_GET_LOCK(obj))
|
||||
|
||||
#define GST_CLAPPER_GL_HAVE_WAYLAND (GST_GL_HAVE_WINDOW_WAYLAND && defined (GDK_WINDOWING_WAYLAND))
|
||||
#define GST_CLAPPER_GL_HAVE_X11 (GST_GL_HAVE_WINDOW_X11 && defined (GDK_WINDOWING_X11))
|
||||
#define GST_CLAPPER_GL_HAVE_X11_GLX (GST_CLAPPER_GL_HAVE_X11 && GST_GL_HAVE_PLATFORM_GLX)
|
||||
#define GST_CLAPPER_GL_HAVE_X11_EGL (GST_CLAPPER_GL_HAVE_X11 && GST_GL_HAVE_PLATFORM_EGL)
|
||||
|
||||
typedef struct _GstClapperGLBaseImport GstClapperGLBaseImport;
|
||||
typedef struct _GstClapperGLBaseImportClass GstClapperGLBaseImportClass;
|
||||
|
||||
#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GstClapperGLBaseImport, gst_object_unref)
|
||||
#endif
|
||||
|
||||
struct _GstClapperGLBaseImport
|
||||
{
|
||||
GstClapperBaseImport parent;
|
||||
|
||||
GMutex lock;
|
||||
|
||||
GdkGLContext *gdk_context;
|
||||
GstGLContext *gst_context;
|
||||
GstGLContext *wrapped_context;
|
||||
GstGLDisplay *gst_display;
|
||||
};
|
||||
|
||||
struct _GstClapperGLBaseImportClass
|
||||
{
|
||||
GstClapperBaseImportClass parent_class;
|
||||
|
||||
gboolean (* gdk_context_realize) (GstClapperGLBaseImport *gl_bi,
|
||||
GdkGLContext *gdk_context);
|
||||
};
|
||||
|
||||
GType gst_clapper_gl_base_import_get_type (void);
|
||||
|
||||
G_END_DECLS
|
178
lib/gst/plugin/gstclapperglimport.c
vendored
Normal file
178
lib/gst/plugin/gstclapperglimport.c
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstclapperglimport.h"
|
||||
#include "gstclappergdkmemory.h"
|
||||
|
||||
#define GST_CAT_DEFAULT gst_clapper_gl_import_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
static GstStaticPadTemplate gst_clapper_gl_import_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS (
|
||||
GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_GL_MEMORY,
|
||||
"{ " GST_CLAPPER_GDK_GL_TEXTURE_FORMATS " }") ", "
|
||||
"texture-target = (string) { " GST_GL_TEXTURE_TARGET_2D_STR " }"
|
||||
"; "
|
||||
GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_GL_MEMORY ", "
|
||||
GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION,
|
||||
"{ " GST_CLAPPER_GDK_GL_TEXTURE_FORMATS " }") ", "
|
||||
"texture-target = (string) { " GST_GL_TEXTURE_TARGET_2D_STR " }"));
|
||||
|
||||
static GstStaticPadTemplate gst_clapper_gl_import_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS (
|
||||
GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_CLAPPER_GDK_MEMORY,
|
||||
"{ " GST_CLAPPER_GDK_GL_TEXTURE_FORMATS " }")
|
||||
"; "
|
||||
GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_CLAPPER_GDK_MEMORY ", "
|
||||
GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION,
|
||||
"{ " GST_CLAPPER_GDK_GL_TEXTURE_FORMATS " }")));
|
||||
|
||||
#define parent_class gst_clapper_gl_import_parent_class
|
||||
G_DEFINE_TYPE (GstClapperGLImport, gst_clapper_gl_import, GST_TYPE_CLAPPER_GL_BASE_IMPORT);
|
||||
GST_ELEMENT_REGISTER_DEFINE (clapperglimport, "clapperglimport", GST_RANK_NONE,
|
||||
GST_TYPE_CLAPPER_GL_IMPORT);
|
||||
|
||||
static GstBufferPool *
|
||||
gst_clapper_gl_import_create_upstream_pool (GstClapperBaseImport *bi, GstStructure **config)
|
||||
{
|
||||
GstClapperGLBaseImport *gl_bi = GST_CLAPPER_GL_BASE_IMPORT_CAST (bi);
|
||||
GstBufferPool *pool;
|
||||
GstGLContext *context;
|
||||
|
||||
GST_DEBUG_OBJECT (bi, "Creating new pool");
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORT_LOCK (gl_bi);
|
||||
context = gst_object_ref (gl_bi->gst_context);
|
||||
GST_CLAPPER_GL_BASE_IMPORT_UNLOCK (gl_bi);
|
||||
|
||||
pool = gst_gl_buffer_pool_new (context);
|
||||
gst_object_unref (context);
|
||||
|
||||
*config = gst_buffer_pool_get_config (pool);
|
||||
|
||||
gst_buffer_pool_config_add_option (*config, GST_BUFFER_POOL_OPTION_GL_SYNC_META);
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
static void
|
||||
video_frame_unmap_and_free (GstVideoFrame *frame)
|
||||
{
|
||||
gst_video_frame_unmap (frame);
|
||||
g_slice_free (GstVideoFrame, frame);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_clapper_gl_import_transform (GstBaseTransform *bt,
|
||||
GstBuffer *in_buf, GstBuffer *out_buf)
|
||||
{
|
||||
GstClapperGLBaseImport *gl_bi = GST_CLAPPER_GL_BASE_IMPORT_CAST (bt);
|
||||
GstClapperBaseImport *bi = GST_CLAPPER_BASE_IMPORT_CAST (bt);
|
||||
GstVideoFrame *frame;
|
||||
GstMapInfo info;
|
||||
GstMemory *memory;
|
||||
GstClapperGdkMemory *clapper_memory;
|
||||
GstGLSyncMeta *sync_meta;
|
||||
|
||||
frame = g_slice_new (GstVideoFrame);
|
||||
|
||||
if (!gst_clapper_base_import_map_buffers (bi, in_buf, out_buf,
|
||||
GST_MAP_READ | GST_MAP_GL, GST_MAP_WRITE, frame, &info, &memory)) {
|
||||
g_slice_free (GstVideoFrame, frame);
|
||||
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
clapper_memory = GST_CLAPPER_GDK_MEMORY_CAST (memory);
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORT_LOCK (gl_bi);
|
||||
|
||||
/* Must have context active here for both sync meta
|
||||
* and Gdk texture format auto-detection to work */
|
||||
gdk_gl_context_make_current (gl_bi->gdk_context);
|
||||
gst_gl_context_activate (gl_bi->wrapped_context, TRUE);
|
||||
|
||||
sync_meta = gst_buffer_get_gl_sync_meta (in_buf);
|
||||
|
||||
/* Wait for all previous OpenGL commands to complete,
|
||||
* before we start using the input texture */
|
||||
if (sync_meta) {
|
||||
gst_gl_sync_meta_set_sync_point (sync_meta, gl_bi->gst_context);
|
||||
gst_gl_sync_meta_wait (sync_meta, gl_bi->wrapped_context);
|
||||
}
|
||||
|
||||
/* Keep input data alive as long as necessary,
|
||||
* unmap only after texture is destroyed */
|
||||
clapper_memory->texture = gdk_gl_texture_new (
|
||||
gl_bi->gdk_context,
|
||||
*(guint *) GST_VIDEO_FRAME_PLANE_DATA (frame, 0),
|
||||
GST_VIDEO_FRAME_WIDTH (frame),
|
||||
GST_VIDEO_FRAME_HEIGHT (frame),
|
||||
(GDestroyNotify) video_frame_unmap_and_free,
|
||||
frame);
|
||||
|
||||
gst_gl_context_activate (gl_bi->wrapped_context, FALSE);
|
||||
gdk_gl_context_clear_current ();
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORT_UNLOCK (gl_bi);
|
||||
|
||||
gst_memory_unmap (memory, &info);
|
||||
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_import_init (GstClapperGLImport *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_import_class_init (GstClapperGLImportClass *klass)
|
||||
{
|
||||
GstElementClass *gstelement_class = (GstElementClass *) klass;
|
||||
GstBaseTransformClass *gstbasetransform_class = (GstBaseTransformClass *) klass;
|
||||
GstClapperBaseImportClass *bi_class = (GstClapperBaseImportClass *) klass;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperglimport", 0,
|
||||
"Clapper GL Import");
|
||||
|
||||
gstbasetransform_class->transform = gst_clapper_gl_import_transform;
|
||||
|
||||
bi_class->create_upstream_pool = gst_clapper_gl_import_create_upstream_pool;
|
||||
|
||||
gst_element_class_set_metadata (gstelement_class,
|
||||
"Clapper GL import",
|
||||
"Filter/Video", "Imports GL memory into ClapperGdkMemory",
|
||||
"Rafał Dzięgiel <rafostar.github@gmail.com>");
|
||||
|
||||
gst_element_class_add_static_pad_template (gstelement_class,
|
||||
&gst_clapper_gl_import_sink_template);
|
||||
gst_element_class_add_static_pad_template (gstelement_class,
|
||||
&gst_clapper_gl_import_src_template);
|
||||
}
|
38
lib/gst/plugin/gstclapperglimport.h
vendored
Normal file
38
lib/gst/plugin/gstclapperglimport.h
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gstclapperglbaseimport.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_CLAPPER_GL_IMPORT (gst_clapper_gl_import_get_type())
|
||||
G_DECLARE_FINAL_TYPE (GstClapperGLImport, gst_clapper_gl_import, GST, CLAPPER_GL_IMPORT, GstClapperGLBaseImport)
|
||||
|
||||
#define GST_CLAPPER_GL_IMPORT_CAST(obj) ((GstClapperGLImport *)(obj))
|
||||
|
||||
struct _GstClapperGLImport
|
||||
{
|
||||
GstClapperGLBaseImport parent;
|
||||
};
|
||||
|
||||
GST_ELEMENT_REGISTER_DECLARE (clapperglimport);
|
||||
|
||||
G_END_DECLS
|
128
lib/gst/plugin/gstclapperimport.c
vendored
Normal file
128
lib/gst/plugin/gstclapperimport.c
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstclapperimport.h"
|
||||
#include "gstclappergdkmemory.h"
|
||||
#include "gstgtkutils.h"
|
||||
|
||||
#define GST_CAT_DEFAULT gst_clapper_import_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
static GstStaticPadTemplate gst_clapper_import_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS (
|
||||
GST_VIDEO_CAPS_MAKE ("{ " GST_CLAPPER_GDK_MEMORY_FORMATS " }")));
|
||||
|
||||
static GstStaticPadTemplate gst_clapper_import_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS (
|
||||
GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_CLAPPER_GDK_MEMORY,
|
||||
"{ " GST_CLAPPER_GDK_MEMORY_FORMATS " }")));
|
||||
|
||||
#define parent_class gst_clapper_import_parent_class
|
||||
G_DEFINE_TYPE (GstClapperImport, gst_clapper_import, GST_TYPE_CLAPPER_BASE_IMPORT);
|
||||
GST_ELEMENT_REGISTER_DEFINE (clapperimport, "clapperimport", GST_RANK_NONE,
|
||||
GST_TYPE_CLAPPER_IMPORT);
|
||||
|
||||
static GstBufferPool *
|
||||
gst_clapper_import_create_upstream_pool (GstClapperBaseImport *bi, GstStructure **config)
|
||||
{
|
||||
GstClapperImport *self = GST_CLAPPER_IMPORT_CAST (bi);
|
||||
GstBufferPool *pool;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Creating new upstream pool");
|
||||
|
||||
pool = gst_video_buffer_pool_new ();
|
||||
*config = gst_buffer_pool_get_config (pool);
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
static void
|
||||
video_frame_unmap_and_free (GstVideoFrame *frame)
|
||||
{
|
||||
gst_video_frame_unmap (frame);
|
||||
g_slice_free (GstVideoFrame, frame);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_clapper_import_transform (GstBaseTransform *bt,
|
||||
GstBuffer *in_buf, GstBuffer *out_buf)
|
||||
{
|
||||
GstClapperBaseImport *bi = GST_CLAPPER_BASE_IMPORT_CAST (bt);
|
||||
GstVideoFrame *frame;
|
||||
GstMapInfo info;
|
||||
GstMemory *memory;
|
||||
|
||||
frame = g_slice_new (GstVideoFrame);
|
||||
|
||||
if (!gst_clapper_base_import_map_buffers (bi, in_buf, out_buf,
|
||||
GST_MAP_READ, GST_MAP_WRITE, frame, &info, &memory)) {
|
||||
g_slice_free (GstVideoFrame, frame);
|
||||
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
/* Keep frame data alive as long as necessary,
|
||||
* unmap only after bytes are destroyed */
|
||||
GST_CLAPPER_GDK_MEMORY_CAST (memory)->texture = gst_video_frame_into_gdk_texture (
|
||||
frame, (GDestroyNotify) video_frame_unmap_and_free);
|
||||
|
||||
gst_memory_unmap (memory, &info);
|
||||
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_import_init (GstClapperImport *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_import_class_init (GstClapperImportClass *klass)
|
||||
{
|
||||
GstElementClass *gstelement_class = (GstElementClass *) klass;
|
||||
GstBaseTransformClass *gstbasetransform_class = (GstBaseTransformClass *) klass;
|
||||
GstClapperBaseImportClass *bi_class = (GstClapperBaseImportClass *) klass;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperimport", 0,
|
||||
"Clapper Import");
|
||||
|
||||
gstbasetransform_class->transform = gst_clapper_import_transform;
|
||||
|
||||
bi_class->create_upstream_pool = gst_clapper_import_create_upstream_pool;
|
||||
|
||||
gst_element_class_set_metadata (gstelement_class,
|
||||
"Clapper import",
|
||||
"Filter/Video", "Imports RAW video data into ClapperGdkMemory",
|
||||
"Rafał Dzięgiel <rafostar.github@gmail.com>");
|
||||
|
||||
gst_element_class_add_static_pad_template (gstelement_class,
|
||||
&gst_clapper_import_sink_template);
|
||||
gst_element_class_add_static_pad_template (gstelement_class,
|
||||
&gst_clapper_import_src_template);
|
||||
}
|
38
lib/gst/plugin/gstclapperimport.h
vendored
Normal file
38
lib/gst/plugin/gstclapperimport.h
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gstclapperbaseimport.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_CLAPPER_IMPORT (gst_clapper_import_get_type())
|
||||
G_DECLARE_FINAL_TYPE (GstClapperImport, gst_clapper_import, GST, CLAPPER_IMPORT, GstClapperBaseImport)
|
||||
|
||||
#define GST_CLAPPER_IMPORT_CAST(obj) ((GstClapperImport *)(obj))
|
||||
|
||||
struct _GstClapperImport
|
||||
{
|
||||
GstClapperBaseImport parent;
|
||||
};
|
||||
|
||||
GST_ELEMENT_REGISTER_DECLARE (clapperimport);
|
||||
|
||||
G_END_DECLS
|
635
lib/gst/plugin/gstclapperpaintable.c
vendored
Normal file
635
lib/gst/plugin/gstclapperpaintable.c
vendored
Normal file
@@ -0,0 +1,635 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstclapperpaintable.h"
|
||||
#include "gstclappergdkmemory.h"
|
||||
#include "gstgtkutils.h"
|
||||
|
||||
#define DEFAULT_PAR_N 1
|
||||
#define DEFAULT_PAR_D 1
|
||||
|
||||
#define GST_CAT_DEFAULT gst_clapper_paintable_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GdkTexture *texture;
|
||||
GstVideoOverlayRectangle *rectangle;
|
||||
|
||||
gint x, y;
|
||||
guint width, height;
|
||||
|
||||
gboolean used;
|
||||
} GstClapperGdkOverlay;
|
||||
|
||||
static void
|
||||
gst_clapper_gdk_overlay_free (GstClapperGdkOverlay *overlay)
|
||||
{
|
||||
GST_TRACE ("Freeing overlay: %" GST_PTR_FORMAT, overlay);
|
||||
|
||||
g_object_unref (overlay->texture);
|
||||
gst_video_overlay_rectangle_unref (overlay->rectangle);
|
||||
g_slice_free (GstClapperGdkOverlay, overlay);
|
||||
}
|
||||
|
||||
static void gst_clapper_paintable_iface_init (GdkPaintableInterface *iface);
|
||||
static void gst_clapper_paintable_dispose (GObject *object);
|
||||
static void gst_clapper_paintable_finalize (GObject *object);
|
||||
|
||||
#define parent_class gst_clapper_paintable_parent_class
|
||||
G_DEFINE_TYPE_WITH_CODE (GstClapperPaintable, gst_clapper_paintable, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
|
||||
gst_clapper_paintable_iface_init));
|
||||
|
||||
static void
|
||||
gst_clapper_paintable_class_init (GstClapperPaintableClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperpaintable", 0,
|
||||
"Clapper Paintable");
|
||||
|
||||
gobject_class->dispose = gst_clapper_paintable_dispose;
|
||||
gobject_class->finalize = gst_clapper_paintable_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_paintable_init (GstClapperPaintable *self)
|
||||
{
|
||||
self->par_n = DEFAULT_PAR_N;
|
||||
self->par_d = DEFAULT_PAR_D;
|
||||
|
||||
g_mutex_init (&self->lock);
|
||||
gst_video_info_init (&self->v_info);
|
||||
g_weak_ref_init (&self->widget, NULL);
|
||||
|
||||
self->overlays = g_ptr_array_new_with_free_func (
|
||||
(GDestroyNotify) gst_clapper_gdk_overlay_free);
|
||||
|
||||
gdk_rgba_parse (&self->bg, "black");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_paintable_dispose (GObject *object)
|
||||
{
|
||||
GstClapperPaintable *self = GST_CLAPPER_PAINTABLE (object);
|
||||
|
||||
GST_CLAPPER_PAINTABLE_LOCK (self);
|
||||
|
||||
if (self->draw_id > 0) {
|
||||
g_source_remove (self->draw_id);
|
||||
self->draw_id = 0;
|
||||
}
|
||||
|
||||
GST_CLAPPER_PAINTABLE_UNLOCK (self);
|
||||
|
||||
GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_paintable_finalize (GObject *object)
|
||||
{
|
||||
GstClapperPaintable *self = GST_CLAPPER_PAINTABLE (object);
|
||||
|
||||
GST_TRACE ("Finalize");
|
||||
|
||||
GST_CLAPPER_PAINTABLE_LOCK (self);
|
||||
|
||||
g_weak_ref_clear (&self->widget);
|
||||
|
||||
gst_clear_buffer (&self->pending_buffer);
|
||||
gst_clear_buffer (&self->buffer);
|
||||
|
||||
g_ptr_array_unref (self->overlays);
|
||||
|
||||
GST_CLAPPER_PAINTABLE_UNLOCK (self);
|
||||
|
||||
g_mutex_clear (&self->lock);
|
||||
|
||||
GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
calculate_display_par (GstClapperPaintable *self, GstVideoInfo *info)
|
||||
{
|
||||
gint width, height, par_n, par_d, req_par_n, req_par_d;
|
||||
gboolean success;
|
||||
|
||||
width = GST_VIDEO_INFO_WIDTH (info);
|
||||
height = GST_VIDEO_INFO_HEIGHT (info);
|
||||
|
||||
/* Cannot apply aspect ratio if there is no video */
|
||||
if (width == 0 || height == 0)
|
||||
return FALSE;
|
||||
|
||||
par_n = GST_VIDEO_INFO_PAR_N (info);
|
||||
par_d = GST_VIDEO_INFO_PAR_D (info);
|
||||
|
||||
req_par_n = self->par_n;
|
||||
req_par_d = self->par_d;
|
||||
|
||||
if (par_n == 0)
|
||||
par_n = 1;
|
||||
|
||||
/* Use defaults if user set zero */
|
||||
if (req_par_n == 0 || req_par_d == 0) {
|
||||
req_par_n = DEFAULT_PAR_N;
|
||||
req_par_d = DEFAULT_PAR_D;
|
||||
}
|
||||
|
||||
GST_LOG_OBJECT (self, "PAR: %u/%u, DAR: %u/%u", par_n, par_d, req_par_n, req_par_d);
|
||||
|
||||
if (!(success = gst_video_calculate_display_ratio (&self->display_ratio_num,
|
||||
&self->display_ratio_den, width, height, par_n, par_d,
|
||||
req_par_n, req_par_d))) {
|
||||
GST_ERROR_OBJECT (self, "Could not calculate display ratio values");
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
invalidate_paintable_size_internal (GstClapperPaintable *self)
|
||||
{
|
||||
gint video_width, video_height;
|
||||
guint display_ratio_num, display_ratio_den;
|
||||
|
||||
GST_CLAPPER_PAINTABLE_LOCK (self);
|
||||
|
||||
video_width = GST_VIDEO_INFO_WIDTH (&self->v_info);
|
||||
video_height = GST_VIDEO_INFO_HEIGHT (&self->v_info);
|
||||
|
||||
display_ratio_num = self->display_ratio_num;
|
||||
display_ratio_den = self->display_ratio_den;
|
||||
|
||||
GST_CLAPPER_PAINTABLE_UNLOCK (self);
|
||||
|
||||
if (video_height % display_ratio_den == 0) {
|
||||
GST_LOG ("Keeping video height");
|
||||
|
||||
self->display_width = (guint)
|
||||
gst_util_uint64_scale_int (video_height, display_ratio_num, display_ratio_den);
|
||||
self->display_height = video_height;
|
||||
} else if (video_width % display_ratio_num == 0) {
|
||||
GST_LOG ("Keeping video width");
|
||||
|
||||
self->display_width = video_width;
|
||||
self->display_height = (guint)
|
||||
gst_util_uint64_scale_int (video_width, display_ratio_den, display_ratio_num);
|
||||
} else {
|
||||
GST_LOG ("Approximating while keeping video height");
|
||||
|
||||
self->display_width = (guint)
|
||||
gst_util_uint64_scale_int (video_height, display_ratio_num, display_ratio_den);
|
||||
self->display_height = video_height;
|
||||
}
|
||||
|
||||
self->display_aspect_ratio = ((gdouble) self->display_width
|
||||
/ (gdouble) self->display_height);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Invalidate paintable size, display: %dx%d",
|
||||
self->display_width, self->display_height);
|
||||
gdk_paintable_invalidate_size ((GdkPaintable *) self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
invalidate_paintable_size_on_main_cb (GstClapperPaintable *self)
|
||||
{
|
||||
GST_CLAPPER_PAINTABLE_LOCK (self);
|
||||
self->draw_id = 0;
|
||||
GST_CLAPPER_PAINTABLE_UNLOCK (self);
|
||||
|
||||
invalidate_paintable_size_internal (self);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
comp_frame_unmap_and_free (GstVideoFrame *frame)
|
||||
{
|
||||
gst_video_frame_unmap (frame);
|
||||
g_slice_free (GstVideoFrame, frame);
|
||||
}
|
||||
|
||||
static GstClapperGdkOverlay *
|
||||
_get_cached_overlay (GPtrArray *overlays, GstVideoOverlayRectangle *rectangle, guint *index)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < overlays->len; i++) {
|
||||
GstClapperGdkOverlay *overlay = g_ptr_array_index (overlays, i);
|
||||
|
||||
if (overlay->rectangle != rectangle)
|
||||
continue;
|
||||
|
||||
*index = i;
|
||||
return overlay;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_paintable_prepare_overlays (GstClapperPaintable *self)
|
||||
{
|
||||
GstVideoOverlayCompositionMeta *comp_meta;
|
||||
guint num_overlays, i;
|
||||
|
||||
/* As long as this is called from main thread, no need to lock here */
|
||||
if (G_UNLIKELY (!self->buffer)
|
||||
|| !(comp_meta = gst_buffer_get_video_overlay_composition_meta (self->buffer))) {
|
||||
guint n_pending = self->overlays->len;
|
||||
|
||||
/* Remove all cached overlays if new buffer does not have any */
|
||||
if (n_pending > 0) {
|
||||
GST_TRACE ("No overlays in buffer, removing all cached ones");
|
||||
g_ptr_array_remove_range (self->overlays, 0, n_pending);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
GST_LOG_OBJECT (self, "Preparing overlays...");
|
||||
|
||||
/* Mark all old overlays as unused */
|
||||
for (i = 0; i < self->overlays->len; i++) {
|
||||
GstClapperGdkOverlay *overlay = g_ptr_array_index (self->overlays, i);
|
||||
overlay->used = FALSE;
|
||||
}
|
||||
|
||||
num_overlays = gst_video_overlay_composition_n_rectangles (comp_meta->overlay);
|
||||
|
||||
for (i = 0; i < num_overlays; i++) {
|
||||
GdkTexture *texture;
|
||||
GstBuffer *comp_buffer;
|
||||
GstVideoFrame *comp_frame;
|
||||
GstVideoMeta *vmeta;
|
||||
GstVideoInfo vinfo;
|
||||
GstVideoOverlayRectangle *rectangle;
|
||||
GstClapperGdkOverlay *overlay;
|
||||
GstVideoOverlayFormatFlags flags, alpha_flags = 0;
|
||||
gint comp_x, comp_y;
|
||||
guint comp_width, comp_height, cached_index;
|
||||
|
||||
rectangle = gst_video_overlay_composition_get_rectangle (comp_meta->overlay, i);
|
||||
|
||||
if ((overlay = _get_cached_overlay (self->overlays, rectangle, &cached_index))) {
|
||||
overlay->used = TRUE;
|
||||
|
||||
/* Place overlay at expected position */
|
||||
if (i != cached_index) {
|
||||
GST_LOG ("Rearranging overlay position: %u => %u", cached_index, i);
|
||||
|
||||
overlay = g_ptr_array_steal_index_fast (self->overlays, cached_index);
|
||||
g_ptr_array_insert (self->overlays, i, overlay);
|
||||
}
|
||||
|
||||
GST_TRACE ("Reusing cached overlay: %" GST_PTR_FORMAT, overlay);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (!gst_video_overlay_rectangle_get_render_rectangle (rectangle,
|
||||
&comp_x, &comp_y, &comp_width, &comp_height))) {
|
||||
GST_WARNING ("Invalid overlay rectangle dimensions: %" GST_PTR_FORMAT, rectangle);
|
||||
continue;
|
||||
}
|
||||
|
||||
flags = gst_video_overlay_rectangle_get_flags (rectangle);
|
||||
|
||||
if (flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA)
|
||||
alpha_flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA;
|
||||
|
||||
comp_buffer = gst_video_overlay_rectangle_get_pixels_unscaled_argb (rectangle, alpha_flags);
|
||||
comp_frame = g_slice_new (GstVideoFrame);
|
||||
|
||||
/* Update overlay video info from video meta */
|
||||
if ((vmeta = gst_buffer_get_video_meta (comp_buffer))) {
|
||||
gst_video_info_set_format (&vinfo, vmeta->format, vmeta->width, vmeta->height);
|
||||
vinfo.stride[0] = vmeta->stride[0];
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (!gst_video_frame_map (comp_frame, &vinfo, comp_buffer, GST_MAP_READ))) {
|
||||
g_slice_free (GstVideoFrame, comp_frame);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((texture = gst_video_frame_into_gdk_texture (
|
||||
comp_frame, (GDestroyNotify) comp_frame_unmap_and_free))) {
|
||||
overlay = g_slice_new (GstClapperGdkOverlay);
|
||||
overlay->texture = texture;
|
||||
overlay->rectangle = gst_video_overlay_rectangle_ref (rectangle);
|
||||
overlay->x = comp_x;
|
||||
overlay->y = comp_y;
|
||||
overlay->width = comp_width;
|
||||
overlay->height = comp_height;
|
||||
overlay->used = TRUE;
|
||||
|
||||
GST_TRACE ("Created overlay: %"
|
||||
GST_PTR_FORMAT ", x: %i, y: %i, width: %u, height: %u",
|
||||
overlay, overlay->x, overlay->y, overlay->width, overlay->height);
|
||||
|
||||
g_ptr_array_insert (self->overlays, i, overlay);
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove all overlays that are not going to be used */
|
||||
for (i = self->overlays->len; i > 0; i--) {
|
||||
GstClapperGdkOverlay *overlay = g_ptr_array_index (self->overlays, i - 1);
|
||||
|
||||
if (!overlay->used) {
|
||||
GST_TRACE ("Removing unused cached overlay: %" GST_PTR_FORMAT, overlay);
|
||||
g_ptr_array_remove (self->overlays, overlay);
|
||||
}
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (num_overlays != self->overlays->len)) {
|
||||
GST_WARNING_OBJECT (self, "Some overlays could not be prepared, %u != %u",
|
||||
num_overlays, self->overlays->len);
|
||||
}
|
||||
|
||||
GST_LOG_OBJECT (self, "Prepared overlays: %u", self->overlays->len);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_paintable_on_main_cb (GstClapperPaintable *self)
|
||||
{
|
||||
gboolean size_changed;
|
||||
|
||||
GST_CLAPPER_PAINTABLE_LOCK (self);
|
||||
|
||||
/* Check if we will need to invalidate size */
|
||||
if ((size_changed = self->pending_resize))
|
||||
self->pending_resize = FALSE;
|
||||
|
||||
gst_clear_buffer (&self->buffer);
|
||||
self->buffer = self->pending_buffer;
|
||||
self->pending_buffer = NULL;
|
||||
|
||||
self->draw_id = 0;
|
||||
|
||||
GST_CLAPPER_PAINTABLE_UNLOCK (self);
|
||||
|
||||
gst_clapper_paintable_prepare_overlays (self);
|
||||
|
||||
if (size_changed)
|
||||
invalidate_paintable_size_internal (self);
|
||||
|
||||
GST_LOG_OBJECT (self, "Invalidate paintable contents");
|
||||
gdk_paintable_invalidate_contents ((GdkPaintable *) self);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
GstClapperPaintable *
|
||||
gst_clapper_paintable_new (void)
|
||||
{
|
||||
return g_object_new (GST_TYPE_CLAPPER_PAINTABLE, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gst_clapper_paintable_set_widget (GstClapperPaintable *self, GtkWidget *widget)
|
||||
{
|
||||
g_weak_ref_set (&self->widget, widget);
|
||||
}
|
||||
|
||||
void
|
||||
gst_clapper_paintable_set_buffer (GstClapperPaintable *self, GstBuffer *buffer)
|
||||
{
|
||||
GST_CLAPPER_PAINTABLE_LOCK (self);
|
||||
|
||||
if (self->draw_id > 0) {
|
||||
GST_CLAPPER_PAINTABLE_UNLOCK (self);
|
||||
GST_TRACE ("Already have pending buffer, skipping %" GST_PTR_FORMAT, buffer);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
gst_buffer_replace (&self->pending_buffer, buffer);
|
||||
self->draw_id = g_idle_add_full (G_PRIORITY_DEFAULT,
|
||||
(GSourceFunc) update_paintable_on_main_cb, self, NULL);
|
||||
|
||||
GST_CLAPPER_PAINTABLE_UNLOCK (self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_clapper_paintable_set_video_info (GstClapperPaintable *self, GstVideoInfo *v_info)
|
||||
{
|
||||
GST_CLAPPER_PAINTABLE_LOCK (self);
|
||||
|
||||
if (gst_video_info_is_equal (&self->v_info, v_info)) {
|
||||
GST_CLAPPER_PAINTABLE_UNLOCK (self);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Reject info if values would cause integer overflow */
|
||||
if (G_UNLIKELY (!calculate_display_par (self, v_info))) {
|
||||
GST_CLAPPER_PAINTABLE_UNLOCK (self);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
self->pending_resize = TRUE;
|
||||
self->v_info = *v_info;
|
||||
|
||||
GST_CLAPPER_PAINTABLE_UNLOCK (self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gst_clapper_paintable_set_pixel_aspect_ratio (GstClapperPaintable *self,
|
||||
gint par_n, gint par_d)
|
||||
{
|
||||
gboolean success;
|
||||
|
||||
GST_CLAPPER_PAINTABLE_LOCK (self);
|
||||
|
||||
/* No change */
|
||||
if (self->par_n == par_n && self->par_d == par_d) {
|
||||
GST_CLAPPER_PAINTABLE_UNLOCK (self);
|
||||
return;
|
||||
}
|
||||
|
||||
self->par_n = par_n;
|
||||
self->par_d = par_d;
|
||||
|
||||
/* Check if we can accept new values. This will update
|
||||
* display `ratio_num` and `ratio_den` only when successful */
|
||||
success = calculate_display_par (self, &self->v_info);
|
||||
|
||||
/* If paintable update is queued, wait for it, otherwise invalidate
|
||||
* size only for change to be applied even when paused */
|
||||
if (!success || self->draw_id > 0) {
|
||||
GST_CLAPPER_PAINTABLE_UNLOCK (self);
|
||||
return;
|
||||
}
|
||||
|
||||
self->draw_id = g_idle_add_full (G_PRIORITY_DEFAULT,
|
||||
(GSourceFunc) invalidate_paintable_size_on_main_cb, self, NULL);
|
||||
|
||||
GST_CLAPPER_PAINTABLE_UNLOCK (self);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* GdkPaintableInterface
|
||||
*/
|
||||
static void
|
||||
gst_clapper_paintable_snapshot_internal (GstClapperPaintable *self,
|
||||
GdkSnapshot *snapshot, gdouble width, gdouble height,
|
||||
gint widget_width, gint widget_height)
|
||||
{
|
||||
GstMemory *memory;
|
||||
GstMapInfo info;
|
||||
gfloat scale_x, scale_y;
|
||||
guint i;
|
||||
|
||||
scale_x = (gfloat) width / self->display_width;
|
||||
scale_y = (gfloat) height / self->display_height;
|
||||
|
||||
/* Apply black borders when keeping aspect ratio */
|
||||
if (scale_x == scale_y || abs (scale_x - scale_y) <= FLT_EPSILON) {
|
||||
if (widget_height - height > 0) {
|
||||
gdouble bar_height = (widget_height - height) / 2;
|
||||
|
||||
gtk_snapshot_append_color (snapshot, &self->bg, &GRAPHENE_RECT_INIT (0, 0, width, -bar_height));
|
||||
gtk_snapshot_append_color (snapshot, &self->bg, &GRAPHENE_RECT_INIT (0, height, width, bar_height + 0.5));
|
||||
} else if (widget_width - width > 0) {
|
||||
gdouble bar_width = (widget_width - width) / 2;
|
||||
|
||||
gtk_snapshot_append_color (snapshot, &self->bg, &GRAPHENE_RECT_INIT (0, 0, -bar_width, height));
|
||||
gtk_snapshot_append_color (snapshot, &self->bg, &GRAPHENE_RECT_INIT (width, 0, bar_width + 0.5, height));
|
||||
}
|
||||
}
|
||||
|
||||
/* Buffer is accessed only from main thread, so no locking required */
|
||||
if (!self->buffer) {
|
||||
gtk_snapshot_append_color (snapshot, &self->bg, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
return;
|
||||
}
|
||||
|
||||
GST_TRACE ("Snapshot %" GST_PTR_FORMAT, self->buffer);
|
||||
|
||||
memory = gst_buffer_peek_memory (self->buffer, 0);
|
||||
|
||||
/* If we cannot map, just draw black */
|
||||
if (G_UNLIKELY (!gst_memory_map (memory, &info, GST_MAP_READ))) {
|
||||
gtk_snapshot_append_color (snapshot, &self->bg, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
GST_WARNING_OBJECT (self, "Could not map %" GST_PTR_FORMAT, self->buffer);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_snapshot_append_texture (snapshot,
|
||||
GST_CLAPPER_GDK_MEMORY_CAST (memory)->texture,
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gst_memory_unmap (memory, &info);
|
||||
|
||||
/* FIXME: Draw black BG here when import format has-alpha */
|
||||
//gtk_snapshot_append_color (snapshot, &self->bg, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
|
||||
/* Finally append prepared overlays */
|
||||
for (i = 0; i < self->overlays->len; i++) {
|
||||
GstClapperGdkOverlay *overlay = g_ptr_array_index (self->overlays, i);
|
||||
|
||||
gtk_snapshot_append_texture (snapshot, overlay->texture,
|
||||
&GRAPHENE_RECT_INIT (overlay->x * scale_x, overlay->y * scale_y,
|
||||
overlay->width * scale_x, overlay->height * scale_y));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_paintable_snapshot (GdkPaintable *paintable,
|
||||
GdkSnapshot *snapshot, gdouble width, gdouble height)
|
||||
{
|
||||
GstClapperPaintable *self = GST_CLAPPER_PAINTABLE_CAST (paintable);
|
||||
GtkWidget *widget;
|
||||
gint widget_width = 0, widget_height = 0;
|
||||
|
||||
if ((widget = g_weak_ref_get (&self->widget))) {
|
||||
widget_width = gtk_widget_get_width (widget);
|
||||
widget_height = gtk_widget_get_height (widget);
|
||||
|
||||
g_object_unref (widget);
|
||||
}
|
||||
|
||||
gst_clapper_paintable_snapshot_internal (self, snapshot,
|
||||
width, height, widget_width, widget_height);
|
||||
}
|
||||
|
||||
static GdkPaintable *
|
||||
gst_clapper_paintable_get_current_image (GdkPaintable *paintable)
|
||||
{
|
||||
GstClapperPaintable *self = GST_CLAPPER_PAINTABLE_CAST (paintable);
|
||||
|
||||
if (self->buffer) {
|
||||
GtkSnapshot *snapshot;
|
||||
GdkPaintable *ret;
|
||||
|
||||
snapshot = gtk_snapshot_new ();
|
||||
|
||||
/* Snapshot without widget size in order to get
|
||||
* paintable without black borders */
|
||||
gst_clapper_paintable_snapshot_internal (self, snapshot,
|
||||
self->display_width, self->display_height, 0, 0);
|
||||
|
||||
if ((ret = gtk_snapshot_free_to_paintable (snapshot, NULL)))
|
||||
return ret;
|
||||
}
|
||||
|
||||
return gdk_paintable_new_empty (0, 0);
|
||||
}
|
||||
|
||||
static gint
|
||||
gst_clapper_paintable_get_intrinsic_width (GdkPaintable *paintable)
|
||||
{
|
||||
GstClapperPaintable *self = GST_CLAPPER_PAINTABLE_CAST (paintable);
|
||||
|
||||
return self->display_width;
|
||||
}
|
||||
|
||||
static gint
|
||||
gst_clapper_paintable_get_intrinsic_height (GdkPaintable *paintable)
|
||||
{
|
||||
GstClapperPaintable *self = GST_CLAPPER_PAINTABLE_CAST (paintable);
|
||||
|
||||
return self->display_height;
|
||||
}
|
||||
|
||||
static gdouble
|
||||
gst_clapper_paintable_get_intrinsic_aspect_ratio (GdkPaintable *paintable)
|
||||
{
|
||||
GstClapperPaintable *self = GST_CLAPPER_PAINTABLE_CAST (paintable);
|
||||
|
||||
return self->display_aspect_ratio;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_paintable_iface_init (GdkPaintableInterface *iface)
|
||||
{
|
||||
iface->snapshot = gst_clapper_paintable_snapshot;
|
||||
iface->get_current_image = gst_clapper_paintable_get_current_image;
|
||||
iface->get_intrinsic_width = gst_clapper_paintable_get_intrinsic_width;
|
||||
iface->get_intrinsic_height = gst_clapper_paintable_get_intrinsic_height;
|
||||
iface->get_intrinsic_aspect_ratio = gst_clapper_paintable_get_intrinsic_aspect_ratio;
|
||||
}
|
74
lib/gst/plugin/gstclapperpaintable.h
vendored
Normal file
74
lib/gst/plugin/gstclapperpaintable.h
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/video.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_CLAPPER_PAINTABLE (gst_clapper_paintable_get_type())
|
||||
G_DECLARE_FINAL_TYPE (GstClapperPaintable, gst_clapper_paintable, GST, CLAPPER_PAINTABLE, GObject)
|
||||
|
||||
#define GST_CLAPPER_PAINTABLE_CAST(obj) ((GstClapperPaintable *)(obj))
|
||||
|
||||
#define GST_CLAPPER_PAINTABLE_GET_LOCK(obj) (&GST_CLAPPER_PAINTABLE_CAST(obj)->lock)
|
||||
#define GST_CLAPPER_PAINTABLE_LOCK(obj) g_mutex_lock (GST_CLAPPER_PAINTABLE_GET_LOCK(obj))
|
||||
#define GST_CLAPPER_PAINTABLE_UNLOCK(obj) g_mutex_unlock (GST_CLAPPER_PAINTABLE_GET_LOCK(obj))
|
||||
|
||||
struct _GstClapperPaintable
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
GMutex lock;
|
||||
|
||||
GstBuffer *pending_buffer, *buffer;
|
||||
GPtrArray *overlays;
|
||||
GstVideoInfo v_info;
|
||||
|
||||
GdkRGBA bg;
|
||||
|
||||
GWeakRef widget;
|
||||
|
||||
/* Sink properties */
|
||||
gint par_n, par_d;
|
||||
|
||||
/* Resize */
|
||||
gboolean pending_resize;
|
||||
guint display_ratio_num;
|
||||
guint display_ratio_den;
|
||||
|
||||
/* GdkPaintableInterface */
|
||||
gint display_width;
|
||||
gint display_height;
|
||||
gdouble display_aspect_ratio;
|
||||
|
||||
/* Pending draw signal id */
|
||||
guint draw_id;
|
||||
};
|
||||
|
||||
GstClapperPaintable * gst_clapper_paintable_new (void);
|
||||
void gst_clapper_paintable_set_widget (GstClapperPaintable *paintable, GtkWidget *widget);
|
||||
void gst_clapper_paintable_set_buffer (GstClapperPaintable *paintable, GstBuffer *buffer);
|
||||
gboolean gst_clapper_paintable_set_video_info (GstClapperPaintable *paintable, GstVideoInfo *v_info);
|
||||
void gst_clapper_paintable_set_pixel_aspect_ratio (GstClapperPaintable *paintable, gint par_n, gint par_d);
|
||||
|
||||
G_END_DECLS
|
838
lib/gst/plugin/gstclappersink.c
vendored
Normal file
838
lib/gst/plugin/gstclappersink.c
vendored
Normal file
@@ -0,0 +1,838 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstclappersink.h"
|
||||
#include "gstclappergdkmemory.h"
|
||||
#include "gstclappergdkbufferpool.h"
|
||||
#include "gstgtkutils.h"
|
||||
|
||||
#define DEFAULT_FORCE_ASPECT_RATIO TRUE
|
||||
#define DEFAULT_PAR_N 1
|
||||
#define DEFAULT_PAR_D 1
|
||||
#define DEFAULT_KEEP_LAST_FRAME FALSE
|
||||
|
||||
#define WINDOW_CSS_CLASS_NAME "clappersinkwindow"
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_WIDGET,
|
||||
PROP_FORCE_ASPECT_RATIO,
|
||||
PROP_PIXEL_ASPECT_RATIO,
|
||||
PROP_KEEP_LAST_FRAME,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
#define GST_CAT_DEFAULT gst_clapper_sink_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
static GstStaticPadTemplate gst_clapper_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS (
|
||||
GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_CLAPPER_GDK_MEMORY,
|
||||
"{ " GST_CLAPPER_GDK_MEMORY_FORMATS " }")
|
||||
"; "
|
||||
GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_CLAPPER_GDK_MEMORY ", "
|
||||
GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION,
|
||||
"{ " GST_CLAPPER_GDK_MEMORY_FORMATS " }")));
|
||||
|
||||
static void gst_clapper_sink_navigation_interface_init (
|
||||
GstNavigationInterface *iface);
|
||||
|
||||
#define parent_class gst_clapper_sink_parent_class
|
||||
G_DEFINE_TYPE_WITH_CODE (GstClapperSink, gst_clapper_sink, GST_TYPE_VIDEO_SINK,
|
||||
G_IMPLEMENT_INTERFACE (GST_TYPE_NAVIGATION,
|
||||
gst_clapper_sink_navigation_interface_init));
|
||||
GST_ELEMENT_REGISTER_DEFINE (clappersink, "clappersink", GST_RANK_NONE,
|
||||
GST_TYPE_CLAPPER_SINK);
|
||||
|
||||
static void
|
||||
window_clear_no_lock (GstClapperSink *self)
|
||||
{
|
||||
if (!self->window)
|
||||
return;
|
||||
|
||||
GST_TRACE_OBJECT (self, "Window clear");
|
||||
|
||||
if (self->window_destroy_id) {
|
||||
g_signal_handler_disconnect (self->window, self->window_destroy_id);
|
||||
self->window_destroy_id = 0;
|
||||
}
|
||||
self->window = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
widget_clear_no_lock (GstClapperSink *self)
|
||||
{
|
||||
if (!self->widget)
|
||||
return;
|
||||
|
||||
GST_TRACE_OBJECT (self, "Widget clear");
|
||||
|
||||
if (self->widget_destroy_id) {
|
||||
g_signal_handler_disconnect (self->widget, self->widget_destroy_id);
|
||||
self->widget_destroy_id = 0;
|
||||
}
|
||||
g_clear_object (&self->widget);
|
||||
}
|
||||
|
||||
static void
|
||||
widget_destroy_cb (GtkWidget *widget, GstClapperSink *self)
|
||||
{
|
||||
GST_CLAPPER_SINK_LOCK (self);
|
||||
widget_clear_no_lock (self);
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
}
|
||||
|
||||
static void
|
||||
window_destroy_cb (GtkWidget *window, GstClapperSink *self)
|
||||
{
|
||||
GST_DEBUG_OBJECT (self, "Window destroy");
|
||||
|
||||
GST_CLAPPER_SINK_LOCK (self);
|
||||
|
||||
widget_clear_no_lock (self);
|
||||
window_clear_no_lock (self);
|
||||
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
}
|
||||
|
||||
static void
|
||||
calculate_stream_coords (GstClapperSink *self, GtkWidget *widget,
|
||||
gdouble x, gdouble y, gdouble *stream_x, gdouble *stream_y)
|
||||
{
|
||||
GstVideoRectangle result;
|
||||
gint scaled_width, scaled_height, scale_factor;
|
||||
gint video_width, video_height;
|
||||
gboolean force_aspect_ratio;
|
||||
|
||||
GST_CLAPPER_SINK_LOCK (self);
|
||||
|
||||
video_width = GST_VIDEO_INFO_WIDTH (&self->v_info);
|
||||
video_height = GST_VIDEO_INFO_HEIGHT (&self->v_info);
|
||||
force_aspect_ratio = self->force_aspect_ratio;
|
||||
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
|
||||
scale_factor = gtk_widget_get_scale_factor (widget);
|
||||
scaled_width = gtk_widget_get_width (widget) * scale_factor;
|
||||
scaled_height = gtk_widget_get_height (widget) * scale_factor;
|
||||
|
||||
if (force_aspect_ratio) {
|
||||
GstVideoRectangle src, dst;
|
||||
|
||||
src.x = 0;
|
||||
src.y = 0;
|
||||
src.w = gdk_paintable_get_intrinsic_width ((GdkPaintable *) self->paintable);
|
||||
src.h = gdk_paintable_get_intrinsic_height ((GdkPaintable *) self->paintable);
|
||||
|
||||
dst.x = 0;
|
||||
dst.y = 0;
|
||||
dst.w = scaled_width;
|
||||
dst.h = scaled_height;
|
||||
|
||||
gst_video_center_rect (&src, &dst, &result, TRUE);
|
||||
} else {
|
||||
result.x = 0;
|
||||
result.y = 0;
|
||||
result.w = scaled_width;
|
||||
result.h = scaled_height;
|
||||
}
|
||||
|
||||
/* Display coordinates to stream coordinates */
|
||||
*stream_x = (result.w > 0)
|
||||
? (x - result.x) / result.w * video_width
|
||||
: 0;
|
||||
*stream_y = (result.h > 0)
|
||||
? (y - result.y) / result.h * video_height
|
||||
: 0;
|
||||
|
||||
/* Clip to stream size */
|
||||
*stream_x = CLAMP (*stream_x, 0, video_width);
|
||||
*stream_y = CLAMP (*stream_y, 0, video_height);
|
||||
|
||||
GST_LOG ("Transform coords %fx%f => %fx%f", x, y, *stream_x, *stream_y);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_sink_widget_motion_event (GtkEventControllerMotion *motion,
|
||||
gdouble x, gdouble y, GstClapperSink *self)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
gdouble stream_x, stream_y;
|
||||
|
||||
if ((x == self->last_pos_x && y == self->last_pos_y)
|
||||
|| GST_STATE (self) < GST_STATE_PLAYING)
|
||||
return;
|
||||
|
||||
self->last_pos_x = x;
|
||||
self->last_pos_y = y;
|
||||
|
||||
widget = gtk_event_controller_get_widget ((GtkEventController *) motion);
|
||||
calculate_stream_coords (self, widget, x, y, &stream_x, &stream_y);
|
||||
GST_LOG ("Event \"mouse-move\", x: %f, y: %f", stream_x, stream_y);
|
||||
|
||||
gst_navigation_send_mouse_event ((GstNavigation *) self, "mouse-move",
|
||||
0, stream_x, stream_y);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_sink_widget_button_event (GtkGestureClick *click,
|
||||
gint n_press, gdouble x, gdouble y, GstClapperSink *self)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GdkEvent *event;
|
||||
gdouble stream_x, stream_y;
|
||||
GdkEventType event_type;
|
||||
const gchar *event_name;
|
||||
|
||||
if (GST_STATE (self) < GST_STATE_PLAYING)
|
||||
return;
|
||||
|
||||
event = gtk_event_controller_get_current_event ((GtkEventController *) click);
|
||||
event_type = gdk_event_get_event_type (event);
|
||||
|
||||
/* FIXME: Touchscreen handling should probably use new touch events from GStreamer 1.22 */
|
||||
event_name = (event_type == GDK_BUTTON_PRESS || event_type == GDK_TOUCH_BEGIN)
|
||||
? "mouse-button-press"
|
||||
: (event_type == GDK_BUTTON_RELEASE || event_type == GDK_TOUCH_END)
|
||||
? "mouse-button-release"
|
||||
: NULL;
|
||||
|
||||
/* Can be NULL on touch */
|
||||
if (!event_name)
|
||||
return;
|
||||
|
||||
widget = gtk_event_controller_get_widget ((GtkEventController *) click);
|
||||
calculate_stream_coords (self, widget, x, y, &stream_x, &stream_y);
|
||||
GST_LOG ("Event \"%s\", x: %f, y: %f", event_name, stream_x, stream_y);
|
||||
|
||||
/* Gesture is set to handle only primary button, so we do not have to check */
|
||||
gst_navigation_send_mouse_event ((GstNavigation *) self, event_name,
|
||||
1, stream_x, stream_y);
|
||||
}
|
||||
|
||||
/* Must call from main thread only with a lock */
|
||||
static GtkWidget *
|
||||
gst_clapper_sink_get_widget (GstClapperSink *self)
|
||||
{
|
||||
if (G_UNLIKELY (!self->widget)) {
|
||||
GtkEventController *controller;
|
||||
GtkGesture *gesture;
|
||||
|
||||
/* Make sure GTK is initialized */
|
||||
if (!gtk_init_check ()) {
|
||||
GST_ERROR_OBJECT (self, "Could not ensure GTK initialization");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self->widget = gtk_picture_new ();
|
||||
|
||||
/* Otherwise widget in grid will appear as a 1x1px
|
||||
* video which might be misleading for users */
|
||||
gtk_widget_set_hexpand (self->widget, TRUE);
|
||||
gtk_widget_set_vexpand (self->widget, TRUE);
|
||||
|
||||
gtk_widget_set_focusable (self->widget, TRUE);
|
||||
gtk_widget_set_can_focus (self->widget, TRUE);
|
||||
|
||||
controller = gtk_event_controller_motion_new ();
|
||||
g_signal_connect (controller, "motion",
|
||||
G_CALLBACK (gst_clapper_sink_widget_motion_event), self);
|
||||
gtk_widget_add_controller (self->widget, controller);
|
||||
|
||||
gesture = gtk_gesture_click_new ();
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), 1);
|
||||
g_signal_connect (gesture, "pressed",
|
||||
G_CALLBACK (gst_clapper_sink_widget_button_event), self);
|
||||
g_signal_connect (gesture, "released",
|
||||
G_CALLBACK (gst_clapper_sink_widget_button_event), self);
|
||||
gtk_widget_add_controller (self->widget, GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
/* TODO: Implement touch events once we depend on GStreamer 1.22 */
|
||||
|
||||
/* Take floating ref */
|
||||
g_object_ref_sink (self->widget);
|
||||
|
||||
/* Set back pointer */
|
||||
gst_clapper_paintable_set_widget (self->paintable, self->widget);
|
||||
|
||||
/* Set earlier remembered property */
|
||||
gtk_picture_set_keep_aspect_ratio (GTK_PICTURE (self->widget),
|
||||
self->force_aspect_ratio);
|
||||
|
||||
gtk_picture_set_paintable (GTK_PICTURE (self->widget), GDK_PAINTABLE (self->paintable));
|
||||
|
||||
self->widget_destroy_id = g_signal_connect (self->widget,
|
||||
"destroy", G_CALLBACK (widget_destroy_cb), self);
|
||||
}
|
||||
|
||||
return self->widget;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
gst_clapper_sink_obtain_widget (GstClapperSink *self)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
GST_CLAPPER_SINK_LOCK (self);
|
||||
widget = gst_clapper_sink_get_widget (self);
|
||||
if (widget)
|
||||
g_object_ref (widget);
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_sink_get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
GstClapperSink *self = GST_CLAPPER_SINK_CAST (object);
|
||||
|
||||
GST_CLAPPER_SINK_LOCK (self);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_WIDGET:
|
||||
if (self->widget) {
|
||||
g_value_set_object (value, self->widget);
|
||||
} else {
|
||||
GtkWidget *widget;
|
||||
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
widget = gst_gtk_invoke_on_main ((GThreadFunc) gst_clapper_sink_obtain_widget, self);
|
||||
GST_CLAPPER_SINK_LOCK (self);
|
||||
|
||||
g_value_set_object (value, widget);
|
||||
g_object_unref (widget);
|
||||
}
|
||||
break;
|
||||
case PROP_FORCE_ASPECT_RATIO:
|
||||
g_value_set_boolean (value, self->force_aspect_ratio);
|
||||
break;
|
||||
case PROP_PIXEL_ASPECT_RATIO:
|
||||
gst_value_set_fraction (value, self->par_n, self->par_d);
|
||||
break;
|
||||
case PROP_KEEP_LAST_FRAME:
|
||||
g_value_set_boolean (value, self->keep_last_frame);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_sink_set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
GstClapperSink *self = GST_CLAPPER_SINK_CAST (object);
|
||||
|
||||
GST_CLAPPER_SINK_LOCK (self);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_FORCE_ASPECT_RATIO:
|
||||
self->force_aspect_ratio = g_value_get_boolean (value);
|
||||
|
||||
if (self->widget) {
|
||||
gtk_picture_set_keep_aspect_ratio (GTK_PICTURE (self->widget),
|
||||
self->force_aspect_ratio);
|
||||
}
|
||||
break;
|
||||
case PROP_PIXEL_ASPECT_RATIO:
|
||||
self->par_n = gst_value_get_fraction_numerator (value);
|
||||
self->par_d = gst_value_get_fraction_denominator (value);
|
||||
|
||||
gst_clapper_paintable_set_pixel_aspect_ratio (self->paintable,
|
||||
self->par_n, self->par_d);
|
||||
break;
|
||||
case PROP_KEEP_LAST_FRAME:
|
||||
self->keep_last_frame = g_value_get_boolean (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_sink_navigation_send_event (GstNavigation *navigation,
|
||||
GstStructure *structure)
|
||||
{
|
||||
GstClapperSink *sink = GST_CLAPPER_SINK_CAST (navigation);
|
||||
GstEvent *event;
|
||||
|
||||
GST_TRACE_OBJECT (sink, "Navigation event: %" GST_PTR_FORMAT, structure);
|
||||
event = gst_event_new_navigation (structure);
|
||||
|
||||
if (G_LIKELY (event)) {
|
||||
GstPad *pad;
|
||||
|
||||
pad = gst_pad_get_peer (GST_VIDEO_SINK_PAD (sink));
|
||||
|
||||
if (G_LIKELY (pad)) {
|
||||
if (!gst_pad_send_event (pad, gst_event_ref (event))) {
|
||||
/* If upstream didn't handle the event we'll post a message with it
|
||||
* for the application in case it wants to do something with it */
|
||||
gst_element_post_message (GST_ELEMENT_CAST (sink),
|
||||
gst_navigation_message_new_event (GST_OBJECT_CAST (sink), event));
|
||||
}
|
||||
gst_object_unref (pad);
|
||||
}
|
||||
gst_event_unref (event);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_sink_propose_allocation (GstBaseSink *bsink, GstQuery *query)
|
||||
{
|
||||
GstClapperSink *self = GST_CLAPPER_SINK_CAST (bsink);
|
||||
GstBufferPool *pool = NULL;
|
||||
GstCaps *caps;
|
||||
GstVideoInfo info;
|
||||
guint size;
|
||||
gboolean need_pool;
|
||||
|
||||
gst_query_parse_allocation (query, &caps, &need_pool);
|
||||
|
||||
if (!caps) {
|
||||
GST_DEBUG_OBJECT (self, "No caps specified");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gst_video_info_from_caps (&info, caps)) {
|
||||
GST_DEBUG_OBJECT (self, "Invalid caps specified");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Normal size of a frame */
|
||||
size = GST_VIDEO_INFO_SIZE (&info);
|
||||
|
||||
if (need_pool) {
|
||||
GstStructure *config;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Creating new pool");
|
||||
|
||||
pool = gst_clapper_gdk_buffer_pool_new ();
|
||||
config = gst_buffer_pool_get_config (pool);
|
||||
|
||||
gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
|
||||
gst_buffer_pool_config_set_params (config, caps, size, 2, 0);
|
||||
|
||||
if (!gst_buffer_pool_set_config (pool, config)) {
|
||||
gst_object_unref (pool);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Failed to set config");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
gst_query_add_allocation_pool (query, pool, size, 2, 0);
|
||||
if (pool)
|
||||
gst_object_unref (pool);
|
||||
|
||||
gst_query_add_allocation_meta (query,
|
||||
GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL);
|
||||
|
||||
/* We also support various metadata */
|
||||
gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_sink_start_on_main (GstClapperSink *self)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
GST_CLAPPER_SINK_LOCK (self);
|
||||
|
||||
/* Make sure widget is created */
|
||||
if (!(widget = gst_clapper_sink_get_widget (self))) {
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* When no toplevel window, make our own */
|
||||
if (G_UNLIKELY (!gtk_widget_get_root (widget) && !self->window)) {
|
||||
GtkWidget *toplevel, *parent;
|
||||
GtkCssProvider *provider;
|
||||
gchar *win_title;
|
||||
|
||||
if ((parent = gtk_widget_get_parent (widget))) {
|
||||
GtkWidget *temp_parent;
|
||||
|
||||
while ((temp_parent = gtk_widget_get_parent (parent)))
|
||||
parent = temp_parent;
|
||||
}
|
||||
toplevel = (parent) ? parent : widget;
|
||||
|
||||
self->window = (GtkWindow *) gtk_window_new ();
|
||||
gtk_widget_add_css_class (GTK_WIDGET (self->window), WINDOW_CSS_CLASS_NAME);
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_data (provider,
|
||||
"." WINDOW_CSS_CLASS_NAME " { background: none; }", -1);
|
||||
gtk_style_context_add_provider_for_display (
|
||||
gdk_display_get_default (), GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
g_object_unref (provider);
|
||||
|
||||
win_title = g_strdup_printf ("Clapper Sink - GTK %u.%u.%u Window",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
|
||||
gtk_window_set_default_size (self->window, 640, 480);
|
||||
gtk_window_set_title (self->window, win_title);
|
||||
gtk_window_set_child (self->window, toplevel);
|
||||
|
||||
g_free (win_title);
|
||||
|
||||
self->window_destroy_id = g_signal_connect (self->window,
|
||||
"destroy", G_CALLBACK (window_destroy_cb), self);
|
||||
}
|
||||
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
window_present_on_main_idle (GtkWindow *window)
|
||||
{
|
||||
GST_INFO ("Presenting window");
|
||||
gtk_window_present (window);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_sink_start (GstBaseSink *bsink)
|
||||
{
|
||||
GstClapperSink *self = GST_CLAPPER_SINK_CAST (bsink);
|
||||
|
||||
GST_INFO_OBJECT (self, "Start");
|
||||
|
||||
if (G_UNLIKELY (!(! !gst_gtk_invoke_on_main ((GThreadFunc) (GCallback)
|
||||
gst_clapper_sink_start_on_main, self)))) {
|
||||
GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND,
|
||||
("GtkWidget could not be created"), (NULL));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_sink_stop_on_main (GstClapperSink *self)
|
||||
{
|
||||
GtkWindow *window = NULL;
|
||||
|
||||
GST_CLAPPER_SINK_LOCK (self);
|
||||
if (self->window)
|
||||
window = g_object_ref (self->window);
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
|
||||
if (window) {
|
||||
gtk_window_destroy (window);
|
||||
g_object_unref (window);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_sink_stop (GstBaseSink *bsink)
|
||||
{
|
||||
GstClapperSink *self = GST_CLAPPER_SINK_CAST (bsink);
|
||||
gboolean has_window;
|
||||
|
||||
GST_INFO_OBJECT (self, "Stop");
|
||||
|
||||
GST_CLAPPER_SINK_LOCK (self);
|
||||
has_window = (self->window != NULL);
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
|
||||
if (G_UNLIKELY (has_window)) {
|
||||
return (! !gst_gtk_invoke_on_main ((GThreadFunc) (GCallback)
|
||||
gst_clapper_sink_stop_on_main, self));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_clapper_sink_change_state (GstElement *element, GstStateChange transition)
|
||||
{
|
||||
GstClapperSink *self = GST_CLAPPER_SINK_CAST (element);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Changing state: %s => %s",
|
||||
gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)),
|
||||
gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition)));
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||
GST_CLAPPER_SINK_LOCK (self);
|
||||
if (!self->keep_last_frame)
|
||||
gst_clapper_paintable_set_buffer (self->paintable, NULL);
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
break;
|
||||
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
||||
GST_CLAPPER_SINK_LOCK (self);
|
||||
if (G_UNLIKELY (self->window && !self->presented_window)) {
|
||||
g_idle_add_full (G_PRIORITY_DEFAULT,
|
||||
(GSourceFunc) window_present_on_main_idle,
|
||||
g_object_ref (self->window), (GDestroyNotify) g_object_unref);
|
||||
self->presented_window = TRUE;
|
||||
}
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_sink_get_times (GstBaseSink *bsink, GstBuffer *buffer,
|
||||
GstClockTime *start, GstClockTime *end)
|
||||
{
|
||||
if (!GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
|
||||
return;
|
||||
|
||||
*start = GST_BUFFER_TIMESTAMP (buffer);
|
||||
|
||||
if (GST_BUFFER_DURATION_IS_VALID (buffer)) {
|
||||
*end = *start + GST_BUFFER_DURATION (buffer);
|
||||
} else {
|
||||
GstClapperSink *self = GST_CLAPPER_SINK_CAST (bsink);
|
||||
gint fps_n, fps_d;
|
||||
|
||||
GST_CLAPPER_SINK_LOCK (self);
|
||||
fps_n = GST_VIDEO_INFO_FPS_N (&self->v_info);
|
||||
fps_d = GST_VIDEO_INFO_FPS_D (&self->v_info);
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
|
||||
if (fps_n > 0)
|
||||
*end = *start + gst_util_uint64_scale_int (GST_SECOND, fps_d, fps_n);
|
||||
}
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_clapper_sink_get_caps (GstBaseSink *bsink, GstCaps *filter)
|
||||
{
|
||||
GstCaps *result, *tmp;
|
||||
|
||||
tmp = gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD (bsink));
|
||||
|
||||
if (filter) {
|
||||
GST_DEBUG ("Intersecting with filter caps: %" GST_PTR_FORMAT, filter);
|
||||
result = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST);
|
||||
gst_caps_unref (tmp);
|
||||
} else {
|
||||
result = tmp;
|
||||
}
|
||||
GST_DEBUG ("Returning caps: %" GST_PTR_FORMAT, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_sink_set_caps (GstBaseSink *bsink, GstCaps *caps)
|
||||
{
|
||||
GstClapperSink *self = GST_CLAPPER_SINK_CAST (bsink);
|
||||
gboolean res;
|
||||
|
||||
GST_INFO_OBJECT (self, "Set caps: %" GST_PTR_FORMAT, caps);
|
||||
GST_CLAPPER_SINK_LOCK (self);
|
||||
|
||||
if (!gst_video_info_from_caps (&self->v_info, caps)) {
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (!self->widget)) {
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND,
|
||||
("Output widget was destroyed"), (NULL));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
res = gst_clapper_paintable_set_video_info (self->paintable, &self->v_info);
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_clapper_sink_show_frame (GstVideoSink *vsink, GstBuffer *buffer)
|
||||
{
|
||||
GstClapperSink *self = GST_CLAPPER_SINK_CAST (vsink);
|
||||
|
||||
GST_TRACE ("Got %" GST_PTR_FORMAT, buffer);
|
||||
GST_CLAPPER_SINK_LOCK (self);
|
||||
|
||||
if (G_UNLIKELY (!self->widget)) {
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND,
|
||||
("Output widget was destroyed"), (NULL));
|
||||
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
gst_clapper_paintable_set_buffer (self->paintable, buffer);
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_sink_init (GstClapperSink *self)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
|
||||
gobject_class = (GObjectClass *) GST_CLAPPER_SINK_GET_CLASS (self);
|
||||
|
||||
/* HACK: install here instead of class init to avoid GStreamer
|
||||
* plugin scanner GObject type conflicts with older GTK versions */
|
||||
if (!g_object_class_find_property (gobject_class, "widget")) {
|
||||
g_object_class_install_property (gobject_class, PROP_WIDGET,
|
||||
g_param_spec_object ("widget", "GTK Widget",
|
||||
"The GtkWidget to place in the widget hierarchy",
|
||||
GTK_TYPE_WIDGET, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
self->force_aspect_ratio = DEFAULT_FORCE_ASPECT_RATIO;
|
||||
self->par_n = DEFAULT_PAR_N;
|
||||
self->par_d = DEFAULT_PAR_D;
|
||||
self->keep_last_frame = DEFAULT_KEEP_LAST_FRAME;
|
||||
|
||||
g_mutex_init (&self->lock);
|
||||
gst_video_info_init (&self->v_info);
|
||||
|
||||
self->paintable = gst_clapper_paintable_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_sink_dispose (GObject *object)
|
||||
{
|
||||
GstClapperSink *self = GST_CLAPPER_SINK_CAST (object);
|
||||
|
||||
GST_CLAPPER_SINK_LOCK (self);
|
||||
|
||||
window_clear_no_lock (self);
|
||||
widget_clear_no_lock (self);
|
||||
|
||||
g_clear_object (&self->paintable);
|
||||
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
|
||||
GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_sink_finalize (GObject *object)
|
||||
{
|
||||
GstClapperSink *self = GST_CLAPPER_SINK_CAST (object);
|
||||
|
||||
GST_TRACE ("Finalize");
|
||||
|
||||
g_mutex_clear (&self->lock);
|
||||
|
||||
GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_sink_class_init (GstClapperSinkClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
GstElementClass *gstelement_class = (GstElementClass *) klass;
|
||||
GstBaseSinkClass *gstbasesink_class = (GstBaseSinkClass *) klass;
|
||||
GstVideoSinkClass *gstvideosink_class = (GstVideoSinkClass *) klass;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clappersink", 0,
|
||||
"Clapper Sink");
|
||||
|
||||
gobject_class->get_property = gst_clapper_sink_get_property;
|
||||
gobject_class->set_property = gst_clapper_sink_set_property;
|
||||
gobject_class->dispose = gst_clapper_sink_dispose;
|
||||
gobject_class->finalize = gst_clapper_sink_finalize;
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_FORCE_ASPECT_RATIO,
|
||||
g_param_spec_boolean ("force-aspect-ratio", "Force aspect ratio",
|
||||
"When enabled, scaling will respect original aspect ratio",
|
||||
DEFAULT_FORCE_ASPECT_RATIO,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_PIXEL_ASPECT_RATIO,
|
||||
gst_param_spec_fraction ("pixel-aspect-ratio", "Pixel Aspect Ratio",
|
||||
"The pixel aspect ratio of the device",
|
||||
DEFAULT_PAR_N, DEFAULT_PAR_D,
|
||||
G_MAXINT, 1, 1, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_KEEP_LAST_FRAME,
|
||||
g_param_spec_boolean ("keep-last-frame", "Keep last frame",
|
||||
"Keep showing last video frame after playback instead of black screen",
|
||||
DEFAULT_KEEP_LAST_FRAME,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
gstelement_class->change_state = gst_clapper_sink_change_state;
|
||||
|
||||
gstbasesink_class->get_caps = gst_clapper_sink_get_caps;
|
||||
gstbasesink_class->set_caps = gst_clapper_sink_set_caps;
|
||||
gstbasesink_class->get_times = gst_clapper_sink_get_times;
|
||||
gstbasesink_class->propose_allocation = gst_clapper_sink_propose_allocation;
|
||||
gstbasesink_class->start = gst_clapper_sink_start;
|
||||
gstbasesink_class->stop = gst_clapper_sink_stop;
|
||||
|
||||
gstvideosink_class->show_frame = gst_clapper_sink_show_frame;
|
||||
|
||||
gst_element_class_set_metadata (gstelement_class,
|
||||
"Clapper video sink",
|
||||
"Sink/Video", "A GTK4 video sink used by Clapper media player",
|
||||
"Rafał Dzięgiel <rafostar.github@gmail.com>");
|
||||
|
||||
gst_element_class_add_static_pad_template (gstelement_class,
|
||||
&gst_clapper_sink_template);
|
||||
}
|
||||
|
||||
/*
|
||||
* GstNavigationInterface
|
||||
*/
|
||||
static void
|
||||
gst_clapper_sink_navigation_interface_init (GstNavigationInterface *iface)
|
||||
{
|
||||
/* TODO: Port to "send_event_simple" once we depend on GStreamer 1.22 */
|
||||
iface->send_event = gst_clapper_sink_navigation_send_event;
|
||||
}
|
70
lib/gst/plugin/gstclappersink.h
vendored
Normal file
70
lib/gst/plugin/gstclappersink.h
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/gstvideosink.h>
|
||||
#include <gst/video/video.h>
|
||||
|
||||
#include "gstclapperpaintable.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_CLAPPER_SINK (gst_clapper_sink_get_type())
|
||||
G_DECLARE_FINAL_TYPE (GstClapperSink, gst_clapper_sink, GST, CLAPPER_SINK, GstVideoSink)
|
||||
|
||||
#define GST_CLAPPER_SINK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_CLAPPER_SINK, GstClapperSinkClass))
|
||||
#define GST_CLAPPER_SINK_CAST(obj) ((GstClapperSink *)(obj))
|
||||
|
||||
#define GST_CLAPPER_SINK_GET_LOCK(obj) (&GST_CLAPPER_SINK_CAST(obj)->lock)
|
||||
#define GST_CLAPPER_SINK_LOCK(obj) g_mutex_lock (GST_CLAPPER_SINK_GET_LOCK(obj))
|
||||
#define GST_CLAPPER_SINK_UNLOCK(obj) g_mutex_unlock (GST_CLAPPER_SINK_GET_LOCK(obj))
|
||||
|
||||
struct _GstClapperSink
|
||||
{
|
||||
GstVideoSink parent;
|
||||
|
||||
GMutex lock;
|
||||
|
||||
GstClapperPaintable *paintable;
|
||||
GstVideoInfo v_info;
|
||||
|
||||
GtkWidget *widget;
|
||||
GtkWindow *window;
|
||||
|
||||
gboolean presented_window;
|
||||
|
||||
/* Properties */
|
||||
gboolean force_aspect_ratio;
|
||||
gint par_n, par_d;
|
||||
gboolean keep_last_frame;
|
||||
|
||||
/* Position coords */
|
||||
gdouble last_pos_x;
|
||||
gdouble last_pos_y;
|
||||
|
||||
gulong widget_destroy_id;
|
||||
gulong window_destroy_id;
|
||||
};
|
||||
|
||||
GST_ELEMENT_REGISTER_DECLARE (clappersink);
|
||||
|
||||
G_END_DECLS
|
131
lib/gst/plugin/gstgtkutils.c
vendored
Normal file
131
lib/gst/plugin/gstgtkutils.c
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2015 Matthew Waters <matthew@centricular.com>
|
||||
* Copyright (C) 2015 Thibault Saunier <tsaunier@gnome.org>
|
||||
* Copyright (C) 2022 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "gstgtkutils.h"
|
||||
|
||||
struct invoke_context
|
||||
{
|
||||
GThreadFunc func;
|
||||
gpointer data;
|
||||
GMutex lock;
|
||||
GCond cond;
|
||||
gboolean fired;
|
||||
|
||||
gpointer res;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
gst_gtk_invoke_func (struct invoke_context *info)
|
||||
{
|
||||
g_mutex_lock (&info->lock);
|
||||
info->res = info->func (info->data);
|
||||
info->fired = TRUE;
|
||||
g_cond_signal (&info->cond);
|
||||
g_mutex_unlock (&info->lock);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
gpointer
|
||||
gst_gtk_invoke_on_main (GThreadFunc func, gpointer data)
|
||||
{
|
||||
GMainContext *main_context = g_main_context_default ();
|
||||
struct invoke_context info;
|
||||
|
||||
g_mutex_init (&info.lock);
|
||||
g_cond_init (&info.cond);
|
||||
info.fired = FALSE;
|
||||
info.func = func;
|
||||
info.data = data;
|
||||
|
||||
g_main_context_invoke (main_context, (GSourceFunc) gst_gtk_invoke_func,
|
||||
&info);
|
||||
|
||||
g_mutex_lock (&info.lock);
|
||||
while (!info.fired)
|
||||
g_cond_wait (&info.cond, &info.lock);
|
||||
g_mutex_unlock (&info.lock);
|
||||
|
||||
g_mutex_clear (&info.lock);
|
||||
g_cond_clear (&info.cond);
|
||||
|
||||
return info.res;
|
||||
}
|
||||
|
||||
/* For use with `GdkMemoryTexture` only! */
|
||||
GdkMemoryFormat
|
||||
gst_video_format_to_gdk_memory_format (GstVideoFormat format)
|
||||
{
|
||||
switch (format) {
|
||||
case GST_VIDEO_FORMAT_RGBA64_LE:
|
||||
case GST_VIDEO_FORMAT_RGBA64_BE:
|
||||
return GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
|
||||
case GST_VIDEO_FORMAT_RGBA:
|
||||
return GDK_MEMORY_R8G8B8A8;
|
||||
case GST_VIDEO_FORMAT_BGRA:
|
||||
return GDK_MEMORY_B8G8R8A8;
|
||||
case GST_VIDEO_FORMAT_ARGB:
|
||||
return GDK_MEMORY_A8R8G8B8;
|
||||
case GST_VIDEO_FORMAT_ABGR:
|
||||
return GDK_MEMORY_A8B8G8R8;
|
||||
case GST_VIDEO_FORMAT_RGBx:
|
||||
return GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
|
||||
case GST_VIDEO_FORMAT_BGRx:
|
||||
return GDK_MEMORY_B8G8R8A8_PREMULTIPLIED;
|
||||
case GST_VIDEO_FORMAT_RGB:
|
||||
return GDK_MEMORY_R8G8B8;
|
||||
case GST_VIDEO_FORMAT_BGR:
|
||||
return GDK_MEMORY_B8G8R8;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* This should never happen as long as above switch statement
|
||||
* is updated when new formats are added to caps */
|
||||
g_assert_not_reached ();
|
||||
|
||||
/* Fallback format */
|
||||
return GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
|
||||
}
|
||||
|
||||
GdkTexture *
|
||||
gst_video_frame_into_gdk_texture (GstVideoFrame *frame, GDestroyNotify free_func)
|
||||
{
|
||||
GdkTexture *texture;
|
||||
GBytes *bytes;
|
||||
|
||||
bytes = g_bytes_new_with_free_func (
|
||||
GST_VIDEO_FRAME_PLANE_DATA (frame, 0),
|
||||
GST_VIDEO_FRAME_HEIGHT (frame) * GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0),
|
||||
free_func, frame);
|
||||
|
||||
texture = gdk_memory_texture_new (
|
||||
GST_VIDEO_FRAME_WIDTH (frame),
|
||||
GST_VIDEO_FRAME_HEIGHT (frame),
|
||||
gst_video_format_to_gdk_memory_format (GST_VIDEO_FRAME_FORMAT (frame)),
|
||||
bytes,
|
||||
GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0));
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
return texture;
|
||||
}
|
33
lib/gst/plugin/gstgtkutils.h
vendored
Normal file
33
lib/gst/plugin/gstgtkutils.h
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2015 Matthew Waters <matthew@centricular.com>
|
||||
* Copyright (C) 2015 Thibault Saunier <tsaunier@gnome.org>
|
||||
* Copyright (C) 2022 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gst/video/video.h>
|
||||
|
||||
gpointer gst_gtk_invoke_on_main (GThreadFunc func, gpointer data);
|
||||
|
||||
GdkMemoryFormat gst_video_format_to_gdk_memory_format (GstVideoFormat format);
|
||||
|
||||
GdkTexture * gst_video_frame_into_gdk_texture (GstVideoFrame *frame, GDestroyNotify free_func);
|
46
lib/gst/plugin/gstplugin.c
vendored
Normal file
46
lib/gst/plugin/gstplugin.c
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstclapperimport.h"
|
||||
#include "gstclapperglimport.h"
|
||||
#include "gstclappersink.h"
|
||||
#include "gstclappergdkmemory.h"
|
||||
|
||||
static gboolean
|
||||
plugin_init (GstPlugin *plugin)
|
||||
{
|
||||
gboolean res = FALSE;
|
||||
|
||||
res |= GST_ELEMENT_REGISTER (clapperimport, plugin);
|
||||
res |= GST_ELEMENT_REGISTER (clapperglimport, plugin);
|
||||
res |= GST_ELEMENT_REGISTER (clappersink, plugin);
|
||||
|
||||
if (res)
|
||||
gst_clapper_gdk_memory_init_once ();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR,
|
||||
clapper, "Clapper elements", plugin_init, VERSION, "LGPL",
|
||||
GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
|
69
lib/gst/plugin/meson.build
vendored
Normal file
69
lib/gst/plugin/meson.build
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
gst_plugins_libdir = join_paths(prefix, libdir, 'gstreamer-1.0')
|
||||
|
||||
gst_clapper_plugin_args = [
|
||||
'-DHAVE_CONFIG_H',
|
||||
'-DGST_USE_UNSTABLE_API',
|
||||
]
|
||||
gst_clapper_plugin_deps = [
|
||||
gtk4_dep,
|
||||
gst_dep,
|
||||
gstbase_dep,
|
||||
gstvideo_dep,
|
||||
gstallocators_dep,
|
||||
]
|
||||
|
||||
if get_option('default_library') == 'static'
|
||||
gst_clapper_plugin_args += ['-DGST_STATIC_COMPILATION']
|
||||
endif
|
||||
|
||||
gst_clapper_plugin_option = get_option('gst-plugin')
|
||||
if gst_clapper_plugin_option.disabled()
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
foreach dep : gst_clapper_plugin_deps
|
||||
if not dep.found()
|
||||
if gst_clapper_plugin_option.enabled()
|
||||
error('GStreamer plugin was enabled, but required dependencies were not found')
|
||||
endif
|
||||
subdir_done()
|
||||
endif
|
||||
endforeach
|
||||
|
||||
if not have_gtk_gl_windowing
|
||||
if gst_clapper_plugin_option.enabled()
|
||||
error('GTK4 widget requires GL windowing')
|
||||
else
|
||||
subdir_done()
|
||||
endif
|
||||
endif
|
||||
|
||||
if not gtk4_dep.version().version_compare('>=4.6.0')
|
||||
if gst_clapper_plugin_option.enabled()
|
||||
error('GTK4 version on this system is too old, plugin needs 4.6.0+')
|
||||
else
|
||||
subdir_done()
|
||||
endif
|
||||
endif
|
||||
|
||||
gst_clapper_plugin_sources = [
|
||||
'gstclappergdkmemory.c',
|
||||
'gstclappergdkbufferpool.c',
|
||||
'gstclapperbaseimport.c',
|
||||
'gstclapperglbaseimport.c',
|
||||
'gstclapperimport.c',
|
||||
'gstclapperglimport.c',
|
||||
'gstclappersink.c',
|
||||
'gstclapperpaintable.c',
|
||||
'gstgtkutils.c',
|
||||
'gstplugin.c',
|
||||
]
|
||||
|
||||
library('gstclapper',
|
||||
gst_clapper_plugin_sources,
|
||||
c_args: gst_clapper_plugin_args,
|
||||
include_directories: configinc,
|
||||
dependencies: gst_clapper_plugin_deps + gtk_deps,
|
||||
install: true,
|
||||
install_dir: gst_plugins_libdir,
|
||||
)
|
49
lib/meson.build
vendored
49
lib/meson.build
vendored
@@ -1,5 +1,5 @@
|
||||
glib_req = '>= 2.56.0'
|
||||
gst_req = '>= 1.18.0'
|
||||
gst_req = '>= 1.20.0'
|
||||
|
||||
api_version = '1.0'
|
||||
libversion = meson.project_version()
|
||||
@@ -132,7 +132,7 @@ cdata.set('SIZEOF_SHORT', cc.sizeof('short'))
|
||||
cdata.set('SIZEOF_VOIDP', cc.sizeof('void*'))
|
||||
|
||||
cdata.set_quoted('VERSION', libversion)
|
||||
cdata.set_quoted('PACKAGE', 'gst-plugins-clapper')
|
||||
cdata.set_quoted('PACKAGE', 'clapper')
|
||||
cdata.set_quoted('PACKAGE_VERSION', libversion)
|
||||
cdata.set_quoted('PACKAGE_BUGREPORT', 'https://github.com/Rafostar/clapper/issues/new')
|
||||
cdata.set_quoted('PACKAGE_NAME', 'GStreamer Clapper Libs')
|
||||
@@ -184,7 +184,7 @@ foreach extra_arg : warning_flags
|
||||
endif
|
||||
endforeach
|
||||
|
||||
cdata.set_quoted('GST_PACKAGE_NAME', 'GStreamer Plugins Clapper')
|
||||
cdata.set_quoted('GST_PACKAGE_NAME', 'gst-plugin-clapper')
|
||||
cdata.set_quoted('GST_PACKAGE_ORIGIN', 'https://github.com/Rafostar/clapper')
|
||||
|
||||
# Mandatory GST deps
|
||||
@@ -200,6 +200,8 @@ gsttag_dep = dependency('gstreamer-tag-1.0', version: gst_req,
|
||||
fallback: ['gst-plugins-base', 'tag_dep'])
|
||||
gstvideo_dep = dependency('gstreamer-video-1.0', version: gst_req,
|
||||
fallback: ['gst-plugins-base', 'video_dep'])
|
||||
gstallocators_dep = dependency('gstreamer-allocators-1.0', version: gst_req,
|
||||
fallback : ['gst-plugins-base', 'allocators_dep'])
|
||||
|
||||
# GStreamer OpenGL
|
||||
gstgl_dep = dependency('gstreamer-gl-1.0', version: gst_req,
|
||||
@@ -247,24 +249,53 @@ libm = cc.find_library('m', required: false)
|
||||
glib_dep = dependency('glib-2.0', version: glib_req, fallback: ['glib', 'libglib_dep'])
|
||||
gmodule_dep = dependency('gmodule-2.0', fallback: ['glib', 'libgmodule_dep'])
|
||||
gio_dep = dependency('gio-2.0', fallback: ['glib', 'libgio_dep'])
|
||||
giounix_dep = dependency('gio-unix-2.0', version: glib_req, fallback: ['glib', 'libgiounix_dep'])
|
||||
|
||||
cdata.set('DISABLE_ORC', 1)
|
||||
cdata.set('GST_ENABLE_EXTRA_CHECKS', get_option('devel-checks'))
|
||||
cdata.set_quoted('GST_PACKAGE_RELEASE_DATETIME', 'Unknown')
|
||||
|
||||
configinc = include_directories('.')
|
||||
libsinc = include_directories('gst')
|
||||
|
||||
gir = find_program('g-ir-scanner', required: true)
|
||||
if not gir.found()
|
||||
error('Clapper requires GI bindings to be compiled')
|
||||
endif
|
||||
|
||||
gir = find_program('g-ir-scanner')
|
||||
gir_init_section = ['--add-init-section=extern void gst_init(gint*,gchar**);' + \
|
||||
'g_setenv("GST_REGISTRY_1.0", "@0@", TRUE);'.format(meson.current_build_dir() + '/gir_empty_registry.reg') + \
|
||||
'g_setenv("GST_PLUGIN_PATH_1_0", "", TRUE);' + \
|
||||
'g_setenv("GST_PLUGIN_SYSTEM_PATH_1_0", "", TRUE);' + \
|
||||
'gst_init(NULL,NULL);', '--quiet'
|
||||
]
|
||||
|
||||
gtk_deps = [gstgl_dep, gstglproto_dep]
|
||||
have_gtk_gl_windowing = false
|
||||
|
||||
gtk4_dep = dependency('gtk4', required: true)
|
||||
|
||||
if not gtk4_dep.version().version_compare('>=4.0.0')
|
||||
error('GTK4 version on this system is too old')
|
||||
endif
|
||||
|
||||
if gst_gl_have_window_x11 and (gst_gl_have_platform_egl or gst_gl_have_platform_glx)
|
||||
gtk_x11_dep = dependency('gtk4-x11', required: false)
|
||||
if gtk_x11_dep.found()
|
||||
gtk_deps += gtk_x11_dep
|
||||
if gst_gl_have_platform_glx
|
||||
gtk_deps += gstglx11_dep
|
||||
endif
|
||||
have_gtk_gl_windowing = true
|
||||
endif
|
||||
endif
|
||||
|
||||
if gst_gl_have_window_wayland and gst_gl_have_platform_egl
|
||||
gtk_wayland_dep = dependency('gtk4-wayland', required: false)
|
||||
if gtk_wayland_dep.found()
|
||||
gtk_deps += [gtk_wayland_dep, gstglwayland_dep]
|
||||
have_gtk_gl_windowing = true
|
||||
endif
|
||||
endif
|
||||
|
||||
if gst_gl_have_platform_egl
|
||||
gtk_deps += gstglegl_dep
|
||||
endif
|
||||
|
||||
subdir('gst')
|
||||
configure_file(output: 'config.h', configuration: cdata)
|
||||
|
@@ -1,5 +1,5 @@
|
||||
project('com.github.rafostar.Clapper', 'c', 'cpp',
|
||||
version: '0.4.0',
|
||||
version: '0.4.1',
|
||||
meson_version: '>= 0.50.0',
|
||||
license: 'GPL-3.0-or-later',
|
||||
default_options: [
|
||||
@@ -19,7 +19,7 @@ datadir = join_paths(get_option('prefix'), get_option('datadir'))
|
||||
pkglibdir = join_paths(libdir, meson.project_name())
|
||||
pkgdatadir = join_paths(datadir, meson.project_name())
|
||||
|
||||
if get_option('lib')
|
||||
if get_option('lib') or not get_option('gst-plugin').disabled()
|
||||
subdir('lib')
|
||||
endif
|
||||
|
||||
|
@@ -8,6 +8,11 @@ option('lib',
|
||||
value: true,
|
||||
description: 'Build GstClapper lib'
|
||||
)
|
||||
option('gst-plugin',
|
||||
type: 'feature',
|
||||
value: 'enabled',
|
||||
description: 'Build GStreamer plugin (includes GTK video sink element)'
|
||||
)
|
||||
option('devel-checks',
|
||||
type: 'boolean',
|
||||
value: false,
|
||||
|
@@ -3,6 +3,10 @@
|
||||
"runtime": "org.gnome.Platform",
|
||||
"runtime-version": "master",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"sdk-extensions": [
|
||||
"org.freedesktop.Sdk.Extension.rust-nightly",
|
||||
"org.freedesktop.Sdk.Extension.llvm13"
|
||||
],
|
||||
"command": "com.github.rafostar.Clapper",
|
||||
"finish-args": [
|
||||
"--share=ipc",
|
||||
@@ -19,10 +23,15 @@
|
||||
"--env=GST_PLUGIN_SYSTEM_PATH=/app/lib/gstreamer-1.0",
|
||||
"--env=GST_VAAPI_ALL_DRIVERS=1"
|
||||
],
|
||||
"build-options": {
|
||||
"append-path": "/usr/lib/sdk/rust-nightly/bin:/usr/lib/sdk/llvm13/bin",
|
||||
"prepend-ld-library-path": "/usr/lib/sdk/llvm13/lib"
|
||||
},
|
||||
"modules": [
|
||||
"flathub/shared-modules/gudev/gudev.json",
|
||||
"flathub/lib/libsass.json",
|
||||
"flathub/lib/sassc.json",
|
||||
"flathub/lib/libadwaita.json",
|
||||
"flathub/lib/liba52.json",
|
||||
"flathub/lib/libmpeg2.json",
|
||||
"flathub/lib/libdv.json",
|
||||
@@ -31,14 +40,9 @@
|
||||
"flathub/lib/libdvdnav.json",
|
||||
"flathub/lib/libass.json",
|
||||
"flathub/lib/ffmpeg.json",
|
||||
"testing/gstreamer-1.0/gstreamer.json",
|
||||
"testing/gstreamer-1.0/gst-plugins-base.json",
|
||||
"testing/gstreamer-1.0/gst-plugins-good.json",
|
||||
"testing/gstreamer-1.0/gst-plugins-bad.json",
|
||||
"testing/gstreamer-1.0/gst-plugins-ugly.json",
|
||||
"testing/gstreamer-1.0/gst-libav.json",
|
||||
"testing/gstreamer-1.0/gstreamer-vaapi.json",
|
||||
"testing/libadwaita.json",
|
||||
"testing/gstreamer.json",
|
||||
"testing/gst-plugins-rs.json",
|
||||
"testing/gtuber.json",
|
||||
{
|
||||
"name": "clapper",
|
||||
"buildsystem": "meson",
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"app-id": "com.github.rafostar.Clapper",
|
||||
"runtime": "org.gnome.Platform",
|
||||
"runtime-version": "40",
|
||||
"runtime-version": "42",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"command": "com.github.rafostar.Clapper",
|
||||
"finish-args": [
|
||||
@@ -20,7 +20,6 @@
|
||||
"--env=GST_VAAPI_ALL_DRIVERS=1"
|
||||
],
|
||||
"modules": [
|
||||
"flathub/lib/glib-networking.json",
|
||||
"flathub/shared-modules/gudev/gudev.json",
|
||||
"flathub/lib/pango.json",
|
||||
"flathub/lib/libsass.json",
|
||||
@@ -35,14 +34,9 @@
|
||||
"flathub/lib/ffmpeg.json",
|
||||
"flathub/lib/uchardet.json",
|
||||
"flathub/gstreamer-1.0/gstreamer.json",
|
||||
"flathub/gstreamer-1.0/gst-plugins-base.json",
|
||||
"flathub/gstreamer-1.0/gst-plugins-good.json",
|
||||
"flathub/gstreamer-1.0/gst-plugins-bad.json",
|
||||
"flathub/gstreamer-1.0/gst-plugins-ugly.json",
|
||||
"flathub/gstreamer-1.0/gst-libav.json",
|
||||
"flathub/gstreamer-1.0/gstreamer-vaapi.json",
|
||||
"flathub/lib/gtk4.json",
|
||||
"testing/libadwaita.json",
|
||||
"testing/gtk4.json",
|
||||
"flathub/lib/libadwaita.json",
|
||||
"testing/gtuber.json",
|
||||
{
|
||||
"name": "clapper",
|
||||
"buildsystem": "meson",
|
||||
|
Submodule pkgs/flatpak/flathub updated: 57f18006bc...4f3bee93b7
23
pkgs/flatpak/testing/gst-plugins-rs.json
Normal file
23
pkgs/flatpak/testing/gst-plugins-rs.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "gst-plugins-rs",
|
||||
"buildsystem": "simple",
|
||||
"build-options": {
|
||||
"build-args": [
|
||||
"--share=network"
|
||||
],
|
||||
"env": {
|
||||
"CARGO_HOME": "/run/build/gst-plugins-rs/cargo"
|
||||
}
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git",
|
||||
"branch": "main"
|
||||
}
|
||||
],
|
||||
"build-commands": [
|
||||
"cargo install cargo-c",
|
||||
"cargo cinstall --prefix=/app -p gst-plugin-dav1d"
|
||||
]
|
||||
}
|
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"name": "gst-libav",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"-Ddoc=disabled",
|
||||
"-Dtests=disabled"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.freedesktop.org/gstreamer/gst-libav.git",
|
||||
"branch": "master"
|
||||
}
|
||||
]
|
||||
}
|
@@ -1,28 +0,0 @@
|
||||
{
|
||||
"name": "gst-plugins-bad",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"-Ddoc=disabled",
|
||||
"-Dexamples=disabled",
|
||||
"-Dtests=disabled",
|
||||
"-Dnls=disabled",
|
||||
"-Dgobject-cast-checks=disabled",
|
||||
"-Dglib-asserts=disabled",
|
||||
"-Dglib-checks=disabled",
|
||||
"-Dextra-checks=disabled",
|
||||
|
||||
"-Dvulkan=disabled",
|
||||
"-Dwebrtc=disabled",
|
||||
"-Dwasapi=disabled",
|
||||
"-Dwasapi2=disabled",
|
||||
"-Dwinks=disabled",
|
||||
"-Dwinscreencap=disabled"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad.git",
|
||||
"branch": "master"
|
||||
}
|
||||
]
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"name": "gst-plugins-base",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"--wrap-mode=nofallback",
|
||||
|
||||
"-Ddoc=disabled",
|
||||
"-Dexamples=disabled",
|
||||
"-Dtests=disabled",
|
||||
"-Dnls=disabled",
|
||||
"-Dgobject-cast-checks=disabled",
|
||||
"-Dglib-asserts=disabled",
|
||||
"-Dglib-checks=disabled",
|
||||
|
||||
"-Dgl_api=opengl,gles2",
|
||||
"-Dgl_platform=egl,glx"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.freedesktop.org/gstreamer/gst-plugins-base.git",
|
||||
"branch": "master"
|
||||
}
|
||||
]
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"name": "gst-plugins-good",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"-Ddoc=disabled",
|
||||
"-Dexamples=disabled",
|
||||
"-Dtests=disabled",
|
||||
"-Dnls=disabled",
|
||||
"-Dgobject-cast-checks=disabled",
|
||||
"-Dglib-asserts=disabled",
|
||||
"-Dglib-checks=disabled",
|
||||
|
||||
"-Dgtk3=disabled"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.freedesktop.org/gstreamer/gst-plugins-good.git",
|
||||
"branch": "master"
|
||||
}
|
||||
]
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"name": "gst-plugins-ugly",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"-Ddoc=disabled",
|
||||
"-Dnls=disabled",
|
||||
"-Dtests=disabled",
|
||||
"-Dgobject-cast-checks=disabled",
|
||||
"-Dglib-asserts=disabled",
|
||||
"-Dglib-checks=disabled",
|
||||
|
||||
"-Dmpeg2dec=enabled"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.freedesktop.org/gstreamer/gst-plugins-ugly.git",
|
||||
"branch": "master"
|
||||
}
|
||||
]
|
||||
}
|
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"name": "gstreamer-vaapi",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"-Ddoc=disabled",
|
||||
"-Dexamples=disabled",
|
||||
"-Dtests=disabled"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi.git",
|
||||
"branch": "master"
|
||||
}
|
||||
]
|
||||
}
|
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"name": "gstreamer",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"-Ddoc=disabled",
|
||||
"-Dgtk_doc=disabled",
|
||||
"-Dexamples=disabled",
|
||||
"-Dtests=disabled",
|
||||
"-Dbenchmarks=disabled",
|
||||
"-Dnls=disabled",
|
||||
"-Dgobject-cast-checks=disabled",
|
||||
"-Dglib-asserts=disabled",
|
||||
"-Dglib-checks=disabled",
|
||||
"-Dextra-checks=disabled"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.freedesktop.org/gstreamer/gstreamer.git",
|
||||
"branch": "master"
|
||||
}
|
||||
]
|
||||
}
|
56
pkgs/flatpak/testing/gstreamer.json
Normal file
56
pkgs/flatpak/testing/gstreamer.json
Normal file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"name": "gstreamer",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"--wrap-mode=nodownload",
|
||||
|
||||
"-Dbase=enabled",
|
||||
"-Dgood=enabled",
|
||||
"-Dbad=enabled",
|
||||
"-Dugly=enabled",
|
||||
"-Dlibav=enabled",
|
||||
"-Dvaapi=enabled",
|
||||
"-Dsharp=disabled",
|
||||
"-Drs=disabled",
|
||||
"-Dpython=disabled",
|
||||
"-Ddevtools=disabled",
|
||||
"-Dges=disabled",
|
||||
"-Drtsp_server=disabled",
|
||||
"-Dgst-examples=disabled",
|
||||
"-Dqt5=disabled",
|
||||
"-Dtests=disabled",
|
||||
"-Dexamples=disabled",
|
||||
"-Dintrospection=enabled",
|
||||
"-Ddoc=disabled",
|
||||
"-Dgtk_doc=disabled",
|
||||
"-Dgpl=enabled",
|
||||
|
||||
"-Dgstreamer:benchmarks=disabled",
|
||||
|
||||
"-Dgst-plugins-base:gl_api=opengl,gles2",
|
||||
"-Dgst-plugins-base:gl_platform=egl,glx",
|
||||
|
||||
"-Dgst-plugins-good:gtk3=disabled",
|
||||
|
||||
"-Dgst-plugins-bad:vulkan=disabled",
|
||||
"-Dgst-plugins-bad:webrtc=disabled",
|
||||
"-Dgst-plugins-bad:wasapi=disabled",
|
||||
"-Dgst-plugins-bad:wasapi2=disabled",
|
||||
"-Dgst-plugins-bad:winks=disabled",
|
||||
"-Dgst-plugins-bad:winscreencap=disabled",
|
||||
"-Dgst-plugins-bad:assrender=enabled",
|
||||
"-Dgst-plugins-bad:nvcodec=enabled",
|
||||
"-Dgst-plugins-bad:v4l2codecs=enabled",
|
||||
"-Dgst-plugins-bad:va=enabled",
|
||||
|
||||
"-Dgst-plugins-ugly:mpeg2dec=enabled"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.freedesktop.org/gstreamer/gstreamer.git",
|
||||
"branch": "main",
|
||||
"disable-submodules": true
|
||||
}
|
||||
]
|
||||
}
|
31
pkgs/flatpak/testing/gtk4-popover-unrealize.patch
Normal file
31
pkgs/flatpak/testing/gtk4-popover-unrealize.patch
Normal file
@@ -0,0 +1,31 @@
|
||||
From b413ee2c7d458c7005d3d3d1da8822cd86893ac0 Mon Sep 17 00:00:00 2001
|
||||
From: Rafostar <40623528+Rafostar@users.noreply.github.com>
|
||||
Date: Fri, 4 Dec 2020 19:25:34 +0100
|
||||
Subject: [PATCH] popover: Call unrealize on hide
|
||||
|
||||
When popover is shown "realize" method is called which creates a new
|
||||
surface for popup. Unfortunately this causes performance drop on Wayland until that
|
||||
surface is destroyed what happens inside "unrealize" method during popover destruction.
|
||||
|
||||
This commit changes default behavior in a way that surface will be destroyed
|
||||
when popover is closed and app will ragain the performance it lost when
|
||||
popover was shown.
|
||||
---
|
||||
gtk/gtkpopover.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/gtk/gtkpopover.c b/gtk/gtkpopover.c
|
||||
index 504dcd6cc1..a7a764d483 100644
|
||||
--- a/gtk/gtkpopover.c
|
||||
+++ b/gtk/gtkpopover.c
|
||||
@@ -951,6 +951,7 @@ gtk_popover_hide (GtkWidget *widget)
|
||||
|
||||
gtk_popover_set_mnemonics_visible (GTK_POPOVER (widget), FALSE);
|
||||
_gtk_widget_set_visible_flag (widget, FALSE);
|
||||
+ gtk_widget_unrealize (widget);
|
||||
gtk_widget_unmap (widget);
|
||||
g_signal_emit (widget, signals[CLOSED], 0);
|
||||
}
|
||||
--
|
||||
GitLab
|
||||
|
37
pkgs/flatpak/testing/gtk4.json
Normal file
37
pkgs/flatpak/testing/gtk4.json
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "gtk",
|
||||
"buildsystem": "meson",
|
||||
"build-options": {
|
||||
"build-args": [
|
||||
"--share=network"
|
||||
]
|
||||
},
|
||||
"config-opts": [
|
||||
"--buildtype=release",
|
||||
|
||||
"-Dwin32-backend=false",
|
||||
"-Dmacos-backend=false",
|
||||
"-Dmedia-ffmpeg=disabled",
|
||||
"-Dprint-cups=disabled",
|
||||
"-Dintrospection=enabled",
|
||||
"-Ddemos=false",
|
||||
"-Dbuild-examples=false",
|
||||
"-Dbuild-tests=false"
|
||||
],
|
||||
"cleanup": [
|
||||
"/bin/gtk4-builder-tool",
|
||||
"/bin/gtk4-encode-symbolic-svg"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.gnome.org/GNOME/gtk.git",
|
||||
"tag": "4.6.2",
|
||||
"commit": "aec7ca82007dbe07faee6be084d20758ebac2b91"
|
||||
},
|
||||
{
|
||||
"type": "patch",
|
||||
"path": "gtk4-popover-unrealize.patch"
|
||||
}
|
||||
]
|
||||
}
|
20
pkgs/flatpak/testing/gtuber.json
Normal file
20
pkgs/flatpak/testing/gtuber.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "gtuber",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"-Dintrospection=disabled",
|
||||
"-Dvapi=disabled",
|
||||
"-Dgst-gtuber=enabled"
|
||||
],
|
||||
"cleanup": [
|
||||
"/include",
|
||||
"/lib/pkgconfig"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/Rafostar/gtuber.git",
|
||||
"branch": "main"
|
||||
}
|
||||
]
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"name": "libadwaita",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"--buildtype=release",
|
||||
"--wrap-mode=nofallback",
|
||||
"-Dintrospection=enabled",
|
||||
"-Dvapi=false",
|
||||
"-Dgtk_doc=false",
|
||||
"-Dtests=false",
|
||||
"-Dexamples=false"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.gnome.org/GNOME/libadwaita.git",
|
||||
"tag": "1.0.0-alpha.2",
|
||||
"commit": "f5932ab4250c8e709958c6e75a1a4941a5f0f386"
|
||||
}
|
||||
]
|
||||
}
|
3
pkgs/rpm/.gitignore
vendored
3
pkgs/rpm/.gitignore
vendored
@@ -1,3 +0,0 @@
|
||||
.osc/
|
||||
clapper/
|
||||
.lock
|
@@ -1 +0,0 @@
|
||||
addFilter("explicit-lib-dependency")
|
@@ -1,184 +0,0 @@
|
||||
#
|
||||
# spec file for package clapper
|
||||
#
|
||||
# Copyright (C) 2020 sp1rit
|
||||
# Copyright (C) 2020-21 Rafostar
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
%define debug_package %{nil}
|
||||
|
||||
%global appname com.github.rafostar.Clapper
|
||||
%global gst_version 1.18.0
|
||||
%global gtk4_version 4.0.0
|
||||
%global meson_version 0.50
|
||||
%global glib2_version 2.56.0
|
||||
|
||||
Name: clapper
|
||||
Version: 0.4.0
|
||||
Release: 1%{?dist}
|
||||
Summary: Simple and modern GNOME media player
|
||||
|
||||
License: GPL-3.0
|
||||
URL: https://github.com/Rafostar/clapper
|
||||
BuildRoot: %{_builddir}/%{name}-%{version}-build
|
||||
Source0: _service
|
||||
|
||||
BuildRequires: meson >= %{meson_version}
|
||||
BuildRequires: gtk4-devel >= %{gtk4_version}
|
||||
BuildRequires: glib2-devel >= %{glib2_version}
|
||||
BuildRequires: gobject-introspection-devel
|
||||
BuildRequires: gjs
|
||||
BuildRequires: gcc-c++
|
||||
BuildRequires: desktop-file-utils
|
||||
BuildRequires: hicolor-icon-theme
|
||||
|
||||
Requires: gjs
|
||||
Requires: gtk4 >= %{gtk4_version}
|
||||
Requires: libadwaita
|
||||
Requires: hicolor-icon-theme
|
||||
|
||||
%if 0%{?suse_version}
|
||||
# SUSE recommends group tag, while Fedora discourages their use
|
||||
Group: Productivity/Multimedia/Video/Players
|
||||
|
||||
BuildRequires: update-desktop-files
|
||||
BuildRequires: gstreamer-devel >= %{gst_version}
|
||||
BuildRequires: gstreamer-plugins-base-devel >= %{gst_version}
|
||||
BuildRequires: Mesa-libGLESv2-devel
|
||||
BuildRequires: Mesa-libGLESv3-devel
|
||||
|
||||
Requires: gstreamer >= %{gst_version}
|
||||
Requires: gstreamer-plugins-base >= %{gst_version}
|
||||
Requires: gstreamer-plugins-good >= %{gst_version}
|
||||
Requires: gstreamer-plugins-bad >= %{gst_version}
|
||||
|
||||
# Popular video decoders
|
||||
Recommends: gstreamer-plugins-libav >= %{gst_version}
|
||||
|
||||
# CD Playback
|
||||
Suggests: gstreamer-plugins-ugly
|
||||
# Intel/AMD video acceleration
|
||||
Suggests: gstreamer-plugins-vaapi
|
||||
%else
|
||||
BuildRequires: glibc-all-langpacks
|
||||
BuildRequires: gstreamer1-devel >= %{gst_version}
|
||||
BuildRequires: gstreamer1-plugins-base-devel >= %{gst_version}
|
||||
BuildRequires: mesa-libGL-devel
|
||||
BuildRequires: mesa-libGLES-devel
|
||||
BuildRequires: mesa-libGLU-devel
|
||||
BuildRequires: mesa-libEGL-devel
|
||||
|
||||
Requires: gstreamer1 >= %{gst_version}
|
||||
Requires: gstreamer1-plugins-base >= %{gst_version}
|
||||
Requires: gstreamer1-plugins-good >= %{gst_version}
|
||||
Requires: gstreamer1-plugins-bad-free >= %{gst_version}
|
||||
|
||||
# ASS subtitles (assrender)
|
||||
Recommends: gstreamer1-plugins-bad-free-extras >= %{gst_version}
|
||||
|
||||
# CD Playback
|
||||
Suggests: gstreamer1-plugins-ugly-free
|
||||
# Intel/AMD video acceleration
|
||||
Suggests: gstreamer1-vaapi
|
||||
%endif
|
||||
|
||||
%description
|
||||
A GNOME media player built using GJS with GTK4 toolkit and powered by GStreamer with OpenGL rendering.
|
||||
|
||||
%prep
|
||||
%setup -q -n %{_sourcedir}/%{name}-%{version} -T -D
|
||||
|
||||
%build
|
||||
%meson
|
||||
%meson_build
|
||||
|
||||
%install
|
||||
%meson_install
|
||||
%if 0%{?suse_version}
|
||||
%suse_update_desktop_file %{appname}
|
||||
%endif
|
||||
|
||||
%check
|
||||
desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop
|
||||
|
||||
%files
|
||||
%license COPYING
|
||||
%doc README.md
|
||||
%{_bindir}/%{appname}*
|
||||
%{_bindir}/clapper
|
||||
%{_datadir}/%{appname}/
|
||||
%{_datadir}/icons/hicolor/*/apps/*.svg
|
||||
%{_datadir}/glib-2.0/schemas/%{appname}.gschema.xml
|
||||
%{_datadir}/mime/packages/%{appname}.xml
|
||||
%{_datadir}/applications/*.desktop
|
||||
%{_datadir}/metainfo/*.metainfo.xml
|
||||
%{_datadir}/gir-1.0/GstClapper-1.0.gir
|
||||
%{_datadir}/locale/*/LC_MESSAGES/%{appname}.mo
|
||||
%{_libdir}/%{appname}/
|
||||
|
||||
%changelog
|
||||
* Sun Sep 12 2021 Rafostar <rafostar.github@gmail.com> - 0.4.0-1
|
||||
- New version
|
||||
|
||||
* Thu Aug 26 2021 Rafostar <rafostar.github@gmail.com> - 0.3.0-4
|
||||
- Install translations
|
||||
|
||||
* Thu Aug 26 2021 Rafostar <rafostar.github@gmail.com> - 0.3.0-3
|
||||
- Install clapper symlink
|
||||
|
||||
* Mon Aug 23 2021 Rafostar <rafostar.github@gmail.com> - 0.3.0-2
|
||||
- Require libadwaita
|
||||
|
||||
* Fri Jun 18 2021 Rafostar <rafostar.github@gmail.com> - 0.3.0-1
|
||||
- New version
|
||||
|
||||
* Mon Apr 19 2021 Rafostar <rafostar.github@gmail.com> - 0.2.1-1
|
||||
- New version
|
||||
|
||||
* Tue Apr 13 2021 Rafostar <rafostar.github@gmail.com> - 0.2.0-1
|
||||
- New version
|
||||
|
||||
* Fri Feb 26 2021 Rafostar <rafostar.github@gmail.com> - 0.1.0-1
|
||||
- New version
|
||||
|
||||
* Sun Feb 7 2021 Rafostar <rafostar.github@gmail.com> - 0.0.0-10
|
||||
- Install gstclapper libs to app named subdirectory
|
||||
|
||||
* Fri Feb 5 2021 Rafostar <rafostar.github@gmail.com> - 0.0.0-9
|
||||
- Update build with gstclapper libs support
|
||||
|
||||
* Thu Jan 21 2021 Rafostar <rafostar.github@gmail.com> - 0.0.0-8
|
||||
- Use metainfo instead of deprecated appdata
|
||||
|
||||
* Mon Jan 18 2021 Rafostar <rafostar.github@gmail.com> - 0.0.0-7
|
||||
- Remove gjs-1.0 files
|
||||
|
||||
* Sun Dec 20 2020 Rafostar <rafostar.github@gmail.com> - 0.0.0-6
|
||||
- Include additional app binaries
|
||||
|
||||
* Sat Oct 31 2020 Rafostar <rafostar.github@gmail.com> - 0.0.0-5
|
||||
- Added metainfo
|
||||
|
||||
* Sun Oct 25 2020 Rafostar <rafostar.github@gmail.com> - 0.0.0-4
|
||||
- Added gschema
|
||||
|
||||
* Wed Oct 14 2020 Rafostar <rafostar.github@gmail.com> - 0.0.0-3
|
||||
- Update to GTK4
|
||||
|
||||
* Sat Sep 19 22:02:00 CEST 2020 sp1rit - 0.0.0-2
|
||||
- Added suse_update_desktop_file macro for SuSE packages
|
||||
|
||||
* Fri Sep 18 2020 Rafostar <rafostar.github@gmail.com> - 0.0.0-1
|
||||
- Initial package
|
@@ -1 +1 @@
|
||||
ca de it nl pl
|
||||
ca cs de es fr hu it nl pl pt pt_BR ru sv zh_CN
|
||||
|
35
po/af.po
35
po/af.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:31\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-14 15:25\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Afrikaans\n"
|
||||
"Language: af_ZA\n"
|
||||
@@ -18,11 +18,11 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgid "Open Files…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgid "Open URI…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
@@ -399,56 +399,61 @@ msgstr ""
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
|
35
po/ar.po
35
po/ar.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:31\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-14 15:25\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Arabic\n"
|
||||
"Language: ar_SA\n"
|
||||
@@ -18,11 +18,11 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgid "Open Files…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgid "Open URI…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
@@ -399,56 +399,61 @@ msgstr ""
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
|
39
po/ca.po
39
po/ca.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 20:37\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-14 16:21\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Catalan\n"
|
||||
"Language: ca_ES\n"
|
||||
@@ -18,12 +18,12 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgstr "Obre fitxers..."
|
||||
msgid "Open Files…"
|
||||
msgstr "Obre fitxers…"
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgstr "Obre l'URI..."
|
||||
msgid "Open URI…"
|
||||
msgstr "Obre l'URI…"
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
msgid "Preferences"
|
||||
@@ -399,56 +399,61 @@ msgstr "Cancel·la"
|
||||
msgid "Open"
|
||||
msgstr "Obre"
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr "Títol"
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr "Completat"
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr "Reprèn la reproducció?"
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr "Versió del GTK: %s"
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr "Versió del Adwaita: %s"
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr "Versió del GStreamer: %s"
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr "Versió del GJS: %s"
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr "Un reproductor multimèdia del GNOME que usa GStreamer"
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr "Ícar Nin Solana <icar.nin@protonmail.com>, 2021"
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr "Acaba a la/les %s"
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr "Sense determinar"
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr "Canals"
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr "Deshabilitat"
|
||||
|
||||
|
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: com.github.rafostar.Clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -18,11 +18,11 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgid "Open Files…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgid "Open URI…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
@@ -399,55 +399,60 @@ msgstr ""
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
267
po/cs.po
267
po/cs.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:31\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-19 20:57\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Czech\n"
|
||||
"Language: cs_CZ\n"
|
||||
@@ -18,437 +18,442 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgstr ""
|
||||
msgid "Open Files…"
|
||||
msgstr "Otevřít soubory…"
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgstr ""
|
||||
msgid "Open URI…"
|
||||
msgstr "Otevřít URI…"
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
msgid "Preferences"
|
||||
msgstr ""
|
||||
msgstr "Předvolby"
|
||||
|
||||
#: ui/clapper.ui:20
|
||||
msgid "Shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Klávesové zkratky"
|
||||
|
||||
#: ui/clapper.ui:26
|
||||
msgid "About Clapper"
|
||||
msgstr ""
|
||||
msgstr "O aplikaci Clapper"
|
||||
|
||||
#: ui/elapsed-time-button.ui:27
|
||||
msgid "Speed"
|
||||
msgstr ""
|
||||
msgstr "Rychlost"
|
||||
|
||||
#: ui/elapsed-time-button.ui:41 ui/preferences-window.ui:83
|
||||
#: ui/preferences-window.ui:215
|
||||
msgid "Normal"
|
||||
msgstr ""
|
||||
msgstr "Normální"
|
||||
|
||||
#: ui/help-overlay.ui:10 ui/preferences-window.ui:12
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
msgstr "Obecné"
|
||||
|
||||
#: ui/help-overlay.ui:13
|
||||
msgid "Show shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Zobrazit klávesové zkratky"
|
||||
|
||||
#: ui/help-overlay.ui:19
|
||||
msgid "Toggle fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Celá obrazovka"
|
||||
|
||||
#: ui/help-overlay.ui:20
|
||||
msgid "Double tap | Double click"
|
||||
msgstr ""
|
||||
msgstr "Dvojitým poklepáním | Dvojitým kliknutím"
|
||||
|
||||
#: ui/help-overlay.ui:26
|
||||
msgid "Leave fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Opustit režim celé obrazovky"
|
||||
|
||||
#: ui/help-overlay.ui:32
|
||||
msgid "Reveal OSD (fullscreen only)"
|
||||
msgstr ""
|
||||
msgstr "Odhalit OSD (pouze při zobrazení na celou obrazovku)"
|
||||
|
||||
#: ui/help-overlay.ui:33
|
||||
msgid "Tap"
|
||||
msgstr ""
|
||||
msgstr "Klepnutím"
|
||||
|
||||
#: ui/help-overlay.ui:39
|
||||
msgid "Quit"
|
||||
msgstr ""
|
||||
msgstr "Ukončit"
|
||||
|
||||
#: ui/help-overlay.ui:47
|
||||
msgid "Media"
|
||||
msgstr ""
|
||||
msgstr "Média"
|
||||
|
||||
#: ui/help-overlay.ui:50
|
||||
msgid "Open files"
|
||||
msgstr ""
|
||||
msgstr "Otevřít soubory"
|
||||
|
||||
#: ui/help-overlay.ui:56 src/dialogs.js:137
|
||||
msgid "Open URI"
|
||||
msgstr ""
|
||||
msgstr "Otevřít URI"
|
||||
|
||||
#: ui/help-overlay.ui:64
|
||||
msgid "Playlist"
|
||||
msgstr ""
|
||||
msgstr "Playlisty"
|
||||
|
||||
#: ui/help-overlay.ui:67
|
||||
msgid "Next item"
|
||||
msgstr ""
|
||||
msgstr "Další položka"
|
||||
|
||||
#: ui/help-overlay.ui:68
|
||||
msgid "Double tap (right side)"
|
||||
msgstr ""
|
||||
msgstr "Dvojité poklepání (pravá strana)"
|
||||
|
||||
#: ui/help-overlay.ui:74
|
||||
msgid "Previous item"
|
||||
msgstr ""
|
||||
msgstr "Předchozí položka"
|
||||
|
||||
#: ui/help-overlay.ui:75
|
||||
msgid "Double tap (left side)"
|
||||
msgstr ""
|
||||
msgstr "Dvojité poklepání (levá strana)"
|
||||
|
||||
#: ui/help-overlay.ui:81
|
||||
msgid "Change repeat mode"
|
||||
msgstr ""
|
||||
msgstr "Změnit režim opakování"
|
||||
|
||||
#: ui/help-overlay.ui:87
|
||||
msgid "Export to file"
|
||||
msgstr ""
|
||||
msgstr "Exportovat do souboru"
|
||||
|
||||
#: ui/help-overlay.ui:95 ui/preferences-window.ui:119
|
||||
msgid "Playback"
|
||||
msgstr ""
|
||||
msgstr "Přehrávání"
|
||||
|
||||
#: ui/help-overlay.ui:98
|
||||
msgid "Toggle play"
|
||||
msgstr ""
|
||||
msgstr "Přepnout přehrávání"
|
||||
|
||||
#: ui/help-overlay.ui:99
|
||||
msgid "Long press | Right click"
|
||||
msgstr ""
|
||||
msgstr "Dlouhým stisknutím | Klepnutím pravým tlačítkem"
|
||||
|
||||
#: ui/help-overlay.ui:105
|
||||
msgid "Seek forward"
|
||||
msgstr ""
|
||||
msgstr "Přetočit vpřed"
|
||||
|
||||
#: ui/help-overlay.ui:106
|
||||
msgid "Swipe right | Scroll right"
|
||||
msgstr ""
|
||||
msgstr "Přejetím vpravo | Scrollováním vpravo"
|
||||
|
||||
#: ui/help-overlay.ui:112
|
||||
msgid "Seek backward"
|
||||
msgstr ""
|
||||
msgstr "Přetočit zpět"
|
||||
|
||||
#: ui/help-overlay.ui:113
|
||||
msgid "Swipe left | Scroll left"
|
||||
msgstr ""
|
||||
msgstr "Přejetím vlevo | Scrollováním vlevo"
|
||||
|
||||
#: ui/help-overlay.ui:119
|
||||
msgid "Volume up"
|
||||
msgstr ""
|
||||
msgstr "Zesílit"
|
||||
|
||||
#: ui/help-overlay.ui:120
|
||||
msgid "Swipe up | Scroll up"
|
||||
msgstr ""
|
||||
msgstr "Přejetím nahoru | Scrollováním nahoru"
|
||||
|
||||
#: ui/help-overlay.ui:126
|
||||
msgid "Volume down"
|
||||
msgstr ""
|
||||
msgstr "Zeslabit"
|
||||
|
||||
#: ui/help-overlay.ui:127
|
||||
msgid "Swipe down | Scroll down"
|
||||
msgstr ""
|
||||
msgstr "Přejetím dolů | Scrollováním dolů"
|
||||
|
||||
#: ui/help-overlay.ui:133
|
||||
msgid "Toggle mute"
|
||||
msgstr ""
|
||||
msgstr "Vypnout/zapnout zvuk"
|
||||
|
||||
#: ui/help-overlay.ui:139
|
||||
msgid "Next chapter"
|
||||
msgstr ""
|
||||
msgstr "Další kapitola"
|
||||
|
||||
#: ui/help-overlay.ui:145
|
||||
msgid "Previous chapter"
|
||||
msgstr ""
|
||||
msgstr "Předchozí kapitola"
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:11
|
||||
msgid "Decoders"
|
||||
msgstr ""
|
||||
msgstr "Dekodéry"
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:18
|
||||
msgid "Return to the preferences"
|
||||
msgstr ""
|
||||
msgstr "Zpět do předvoleb"
|
||||
|
||||
#: ui/preferences-window.ui:16
|
||||
msgid "Behavior"
|
||||
msgstr ""
|
||||
msgstr "Chování"
|
||||
|
||||
#: ui/preferences-window.ui:19
|
||||
msgid "Auto fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Automaticky na celou obrazovku"
|
||||
|
||||
#: ui/preferences-window.ui:20
|
||||
msgid "Enter fullscreen when playlist is replaced except floating mode"
|
||||
msgstr ""
|
||||
msgstr "Přejít do režimu na celou obrazovku při nahrazení seznamu skladeb s výjimkou plovoucího režimu"
|
||||
|
||||
#: ui/preferences-window.ui:26
|
||||
msgid "Ask to resume recent media"
|
||||
msgstr ""
|
||||
msgstr "Zeptat se na obnovení nedávných médií"
|
||||
|
||||
#: ui/preferences-window.ui:32
|
||||
msgid "Float on all workspaces"
|
||||
msgstr ""
|
||||
msgstr "Plovoucí režim na všech pracovních plochách"
|
||||
|
||||
#: ui/preferences-window.ui:33
|
||||
msgid "This option only works on GNOME"
|
||||
msgstr ""
|
||||
msgstr "Tato možnost funguje pouze na GNOME"
|
||||
|
||||
#: ui/preferences-window.ui:39
|
||||
msgid "After playback"
|
||||
msgstr ""
|
||||
msgstr "Po skončení přehrávání"
|
||||
|
||||
#: ui/preferences-window.ui:44
|
||||
msgid "Do nothing"
|
||||
msgstr ""
|
||||
msgstr "Nedělat nic"
|
||||
|
||||
#: ui/preferences-window.ui:45
|
||||
msgid "Freeze last frame"
|
||||
msgstr ""
|
||||
msgstr "Zůstat na posledním snímku"
|
||||
|
||||
#: ui/preferences-window.ui:46
|
||||
msgid "Close the app"
|
||||
msgstr ""
|
||||
msgstr "Zavřít aplikaci"
|
||||
|
||||
#: ui/preferences-window.ui:56
|
||||
msgid "Volume"
|
||||
msgstr ""
|
||||
msgstr "Hlasitost"
|
||||
|
||||
#: ui/preferences-window.ui:59
|
||||
msgid "Custom initial value"
|
||||
msgstr ""
|
||||
msgstr "Vlastní počáteční hodnota"
|
||||
|
||||
#: ui/preferences-window.ui:60
|
||||
msgid "Set custom volume at startup instead of restoring it"
|
||||
msgstr ""
|
||||
msgstr "Nastavit vlastní hlasitost při spuštění namísto obnovení předchozí hodnoty"
|
||||
|
||||
#: ui/preferences-window.ui:64
|
||||
msgid "Volume percentage"
|
||||
msgstr ""
|
||||
msgstr "Procento hlasitosti"
|
||||
|
||||
#: ui/preferences-window.ui:75
|
||||
msgid "Seeking"
|
||||
msgstr ""
|
||||
msgstr "Přetáčení"
|
||||
|
||||
#: ui/preferences-window.ui:78
|
||||
msgid "Mode"
|
||||
msgstr ""
|
||||
msgstr "Režim"
|
||||
|
||||
#: ui/preferences-window.ui:84
|
||||
msgid "Accurate"
|
||||
msgstr ""
|
||||
msgstr "Přesný"
|
||||
|
||||
#: ui/preferences-window.ui:85
|
||||
msgid "Fast"
|
||||
msgstr ""
|
||||
msgstr "Rychlý"
|
||||
|
||||
#: ui/preferences-window.ui:93
|
||||
msgid "Unit"
|
||||
msgstr ""
|
||||
msgstr "Jednotka"
|
||||
|
||||
#: ui/preferences-window.ui:98
|
||||
msgid "Second"
|
||||
msgstr ""
|
||||
msgstr "Sekundy"
|
||||
|
||||
#: ui/preferences-window.ui:99
|
||||
msgid "Minute"
|
||||
msgstr ""
|
||||
msgstr "Minuty"
|
||||
|
||||
#: ui/preferences-window.ui:100
|
||||
msgid "Percentage"
|
||||
msgstr ""
|
||||
msgstr "Procenta"
|
||||
|
||||
#: ui/preferences-window.ui:108
|
||||
msgid "Value"
|
||||
msgstr ""
|
||||
msgstr "Hodnota"
|
||||
|
||||
#: ui/preferences-window.ui:123
|
||||
msgid "Audio"
|
||||
msgstr ""
|
||||
msgstr "Zvuk"
|
||||
|
||||
#: ui/preferences-window.ui:126
|
||||
msgid "Offset in milliseconds"
|
||||
msgstr ""
|
||||
msgstr "Posunutí v milisekundách"
|
||||
|
||||
#: ui/preferences-window.ui:133
|
||||
msgid "Only native audio formats"
|
||||
msgstr ""
|
||||
msgstr "Pouze nativní formáty zvuku"
|
||||
|
||||
#: ui/preferences-window.ui:141
|
||||
msgid "Subtitles"
|
||||
msgstr ""
|
||||
msgstr "Titulky"
|
||||
|
||||
#: ui/preferences-window.ui:144
|
||||
msgid "Default font"
|
||||
msgstr ""
|
||||
msgstr "Výchozí styl písma"
|
||||
|
||||
#: ui/preferences-window.ui:154
|
||||
msgid "Network"
|
||||
msgstr ""
|
||||
msgstr "Síť"
|
||||
|
||||
#: ui/preferences-window.ui:158
|
||||
msgid "Client"
|
||||
msgstr ""
|
||||
msgstr "Klient"
|
||||
|
||||
#: ui/preferences-window.ui:161
|
||||
msgid "Progressive download buffering"
|
||||
msgstr ""
|
||||
msgstr "Postupné stahování do vyrovnávací paměti"
|
||||
|
||||
#: ui/preferences-window.ui:169
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
msgstr "Server"
|
||||
|
||||
#: ui/preferences-window.ui:172
|
||||
msgid "Control player remotely"
|
||||
msgstr ""
|
||||
msgstr "Vzdáleně ovládat přehrávač"
|
||||
|
||||
#: ui/preferences-window.ui:176
|
||||
msgid "Listening port"
|
||||
msgstr ""
|
||||
msgstr "Naslouchat na portu"
|
||||
|
||||
#: ui/preferences-window.ui:183
|
||||
msgid "Run web application in background"
|
||||
msgstr ""
|
||||
msgstr "Spustit webovou aplikaci na pozadí"
|
||||
|
||||
#: ui/preferences-window.ui:184
|
||||
msgid "Requires GTK compiled with Broadway backend"
|
||||
msgstr ""
|
||||
msgstr "Vyžaduje GTK kompilovaný s Broadway backendem"
|
||||
|
||||
#: ui/preferences-window.ui:190
|
||||
msgid "Web application port"
|
||||
msgstr ""
|
||||
msgstr "Port webové aplikace"
|
||||
|
||||
#: ui/preferences-window.ui:204
|
||||
msgid "Prefer adaptive streaming"
|
||||
msgstr ""
|
||||
msgstr "Preferovat adaptivní streamování"
|
||||
|
||||
#: ui/preferences-window.ui:210
|
||||
msgid "Max quality"
|
||||
msgstr ""
|
||||
msgstr "Maximální kvalita"
|
||||
|
||||
#: ui/preferences-window.ui:228
|
||||
msgid "Tweaks"
|
||||
msgstr ""
|
||||
msgstr "Vylepšení"
|
||||
|
||||
#: ui/preferences-window.ui:232
|
||||
msgid "Appearance"
|
||||
msgstr ""
|
||||
msgstr "Vzhled"
|
||||
|
||||
#: ui/preferences-window.ui:235
|
||||
msgid "Dark theme"
|
||||
msgstr ""
|
||||
msgstr "Tmavý motiv"
|
||||
|
||||
#: ui/preferences-window.ui:241
|
||||
msgid "Render window shadows"
|
||||
msgstr ""
|
||||
msgstr "Vykreslovat stíny okna"
|
||||
|
||||
#: ui/preferences-window.ui:242
|
||||
msgid "Disable to increase performance when windowed"
|
||||
msgstr ""
|
||||
msgstr "Zakázat pro zvýšení výkonu"
|
||||
|
||||
#: ui/preferences-window.ui:253
|
||||
msgid "Plugin ranking"
|
||||
msgstr ""
|
||||
msgstr "Pořadí pluginů"
|
||||
|
||||
#: ui/preferences-window.ui:254
|
||||
msgid "Alter default ranks of GStreamer plugins"
|
||||
msgstr ""
|
||||
msgstr "Změna výchozího pořadí zásuvných modulů GStreameru"
|
||||
|
||||
#: ui/preferences-window.ui:259
|
||||
msgid "Use playbin3"
|
||||
msgstr ""
|
||||
msgstr "Použít playbin3"
|
||||
|
||||
#: ui/preferences-window.ui:260 ui/preferences-window.ui:269
|
||||
msgid "Requires player restart"
|
||||
msgstr ""
|
||||
msgstr "Vyžaduje restart přehrávače"
|
||||
|
||||
#: ui/preferences-window.ui:262 ui/preferences-window.ui:271
|
||||
msgid "Experimental"
|
||||
msgstr ""
|
||||
msgstr "Experimentální"
|
||||
|
||||
#: ui/preferences-window.ui:268
|
||||
msgid "Use PipeWire for audio output"
|
||||
msgstr ""
|
||||
msgstr "Použít PipeWire pro zvukový výstup"
|
||||
|
||||
#: src/buttons.js:201
|
||||
#, javascript-format
|
||||
msgid "Decoder: %s"
|
||||
msgstr ""
|
||||
msgstr "Dekodér: %s"
|
||||
|
||||
#: src/dialogs.js:152
|
||||
msgid "Enter or drop URI here"
|
||||
msgstr ""
|
||||
msgstr "Zde zadejte nebo přetáhněte URI"
|
||||
|
||||
#: src/dialogs.js:157
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "Zrušit"
|
||||
|
||||
#: src/dialogs.js:158
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
msgstr "Otevřít"
|
||||
|
||||
#: src/dialogs.js:226
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
msgid "Title"
|
||||
msgstr "Název"
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr "Přehráno"
|
||||
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr "Pokračovat v přehrávání?"
|
||||
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
msgstr "Verze GTK: %s"
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
msgstr "Verze Adwaita: %s"
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr "Verze GStreameru: %s"
|
||||
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr "Verze GJS: %s"
|
||||
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
msgstr "Přehrávač médií pro GNOME postavený na GStreameru"
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr "Vojtěch Perník <translations@pervoj.cz>"
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
msgstr "Končí v: %s"
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
msgstr "Neurčeno"
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
msgstr "Kanály"
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
msgstr "Vypnuto"
|
||||
|
||||
|
35
po/da.po
35
po/da.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:31\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-14 15:25\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Danish\n"
|
||||
"Language: da_DK\n"
|
||||
@@ -18,11 +18,11 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgid "Open Files…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgid "Open URI…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
@@ -399,56 +399,61 @@ msgstr ""
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
|
39
po/de.po
39
po/de.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-07 20:54\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-14 15:25\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: German\n"
|
||||
"Language: de_DE\n"
|
||||
@@ -18,12 +18,12 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgstr "Dateien öffnen..."
|
||||
msgid "Open Files…"
|
||||
msgstr "Dateien öffnen…"
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgstr "Webquelle öffnen..."
|
||||
msgid "Open URI…"
|
||||
msgstr "Webquelle öffnen…"
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
msgid "Preferences"
|
||||
@@ -399,56 +399,61 @@ msgstr "Abbrechen"
|
||||
msgid "Open"
|
||||
msgstr "Öffnen"
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr "Titel"
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr "Abgespielt"
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr "Wiedergabe fortfahren?"
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr "GTK Version: %s"
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr "Adwaita Version: %s"
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr "GStreamer Version: %s"
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr "GJS Version: %s"
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr "Ein von GStreamer betriebener GNOME Multimedia-Player"
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr "Ended um %s"
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr "Unbestimmet"
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr "Audio-Kanäle"
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr "Deaktiviert"
|
||||
|
||||
|
35
po/el.po
35
po/el.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:31\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-14 15:25\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Greek\n"
|
||||
"Language: el_GR\n"
|
||||
@@ -18,11 +18,11 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgid "Open Files…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgid "Open URI…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
@@ -399,56 +399,61 @@ msgstr ""
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
|
267
po/es.po
267
po/es.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:31\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2022-01-16 16:58\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Spanish\n"
|
||||
"Language: es_ES\n"
|
||||
@@ -18,437 +18,442 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgstr ""
|
||||
msgid "Open Files…"
|
||||
msgstr "Abrir archivos…"
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgstr ""
|
||||
msgid "Open URI…"
|
||||
msgstr "Abrir URI…"
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
msgid "Preferences"
|
||||
msgstr ""
|
||||
msgstr "Preferencias"
|
||||
|
||||
#: ui/clapper.ui:20
|
||||
msgid "Shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Atajos"
|
||||
|
||||
#: ui/clapper.ui:26
|
||||
msgid "About Clapper"
|
||||
msgstr ""
|
||||
msgstr "Acerca de Clapper"
|
||||
|
||||
#: ui/elapsed-time-button.ui:27
|
||||
msgid "Speed"
|
||||
msgstr ""
|
||||
msgstr "Velocidad"
|
||||
|
||||
#: ui/elapsed-time-button.ui:41 ui/preferences-window.ui:83
|
||||
#: ui/preferences-window.ui:215
|
||||
msgid "Normal"
|
||||
msgstr ""
|
||||
msgstr "Normal"
|
||||
|
||||
#: ui/help-overlay.ui:10 ui/preferences-window.ui:12
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
msgstr "General"
|
||||
|
||||
#: ui/help-overlay.ui:13
|
||||
msgid "Show shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Mostrar atajos"
|
||||
|
||||
#: ui/help-overlay.ui:19
|
||||
msgid "Toggle fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Fijar a pantalla completa"
|
||||
|
||||
#: ui/help-overlay.ui:20
|
||||
msgid "Double tap | Double click"
|
||||
msgstr ""
|
||||
msgstr "Doble toque | Doble clic "
|
||||
|
||||
#: ui/help-overlay.ui:26
|
||||
msgid "Leave fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Salir de pantalla completa"
|
||||
|
||||
#: ui/help-overlay.ui:32
|
||||
msgid "Reveal OSD (fullscreen only)"
|
||||
msgstr ""
|
||||
msgstr "Revelar OSD (solo pantalla completa)"
|
||||
|
||||
#: ui/help-overlay.ui:33
|
||||
msgid "Tap"
|
||||
msgstr ""
|
||||
msgstr "Tocar"
|
||||
|
||||
#: ui/help-overlay.ui:39
|
||||
msgid "Quit"
|
||||
msgstr ""
|
||||
msgstr "Renunciar"
|
||||
|
||||
#: ui/help-overlay.ui:47
|
||||
msgid "Media"
|
||||
msgstr ""
|
||||
msgstr "Media"
|
||||
|
||||
#: ui/help-overlay.ui:50
|
||||
msgid "Open files"
|
||||
msgstr ""
|
||||
msgstr "Abrir archivos"
|
||||
|
||||
#: ui/help-overlay.ui:56 src/dialogs.js:137
|
||||
msgid "Open URI"
|
||||
msgstr ""
|
||||
msgstr "Abrir URI"
|
||||
|
||||
#: ui/help-overlay.ui:64
|
||||
msgid "Playlist"
|
||||
msgstr ""
|
||||
msgstr "Lista de reproducción"
|
||||
|
||||
#: ui/help-overlay.ui:67
|
||||
msgid "Next item"
|
||||
msgstr ""
|
||||
msgstr "Elemento siguiente"
|
||||
|
||||
#: ui/help-overlay.ui:68
|
||||
msgid "Double tap (right side)"
|
||||
msgstr ""
|
||||
msgstr "Tocar doble (lado derecho)"
|
||||
|
||||
#: ui/help-overlay.ui:74
|
||||
msgid "Previous item"
|
||||
msgstr ""
|
||||
msgstr "Elemento anterior"
|
||||
|
||||
#: ui/help-overlay.ui:75
|
||||
msgid "Double tap (left side)"
|
||||
msgstr ""
|
||||
msgstr "Tocar doble (lado izquierdo)"
|
||||
|
||||
#: ui/help-overlay.ui:81
|
||||
msgid "Change repeat mode"
|
||||
msgstr ""
|
||||
msgstr "Cambiar a modo repetir"
|
||||
|
||||
#: ui/help-overlay.ui:87
|
||||
msgid "Export to file"
|
||||
msgstr ""
|
||||
msgstr "Exportar a archivo"
|
||||
|
||||
#: ui/help-overlay.ui:95 ui/preferences-window.ui:119
|
||||
msgid "Playback"
|
||||
msgstr ""
|
||||
msgstr "Reproducir"
|
||||
|
||||
#: ui/help-overlay.ui:98
|
||||
msgid "Toggle play"
|
||||
msgstr ""
|
||||
msgstr "Fijar a reproducir"
|
||||
|
||||
#: ui/help-overlay.ui:99
|
||||
msgid "Long press | Right click"
|
||||
msgstr ""
|
||||
msgstr "Pulsación larga | Clic derecho"
|
||||
|
||||
#: ui/help-overlay.ui:105
|
||||
msgid "Seek forward"
|
||||
msgstr ""
|
||||
msgstr "Buscar siguiente"
|
||||
|
||||
#: ui/help-overlay.ui:106
|
||||
msgid "Swipe right | Scroll right"
|
||||
msgstr ""
|
||||
msgstr "Deslizar a derecha | Desplazar a derecha"
|
||||
|
||||
#: ui/help-overlay.ui:112
|
||||
msgid "Seek backward"
|
||||
msgstr ""
|
||||
msgstr "Buscar anterior"
|
||||
|
||||
#: ui/help-overlay.ui:113
|
||||
msgid "Swipe left | Scroll left"
|
||||
msgstr ""
|
||||
msgstr "Deslizar a izquierda | Desplazar a izquierda"
|
||||
|
||||
#: ui/help-overlay.ui:119
|
||||
msgid "Volume up"
|
||||
msgstr ""
|
||||
msgstr "Volumen +"
|
||||
|
||||
#: ui/help-overlay.ui:120
|
||||
msgid "Swipe up | Scroll up"
|
||||
msgstr ""
|
||||
msgstr "Deslizar + | Desplazar +"
|
||||
|
||||
#: ui/help-overlay.ui:126
|
||||
msgid "Volume down"
|
||||
msgstr ""
|
||||
msgstr "Volumen -"
|
||||
|
||||
#: ui/help-overlay.ui:127
|
||||
msgid "Swipe down | Scroll down"
|
||||
msgstr ""
|
||||
msgstr "Deslizar - | Desplazar -"
|
||||
|
||||
#: ui/help-overlay.ui:133
|
||||
msgid "Toggle mute"
|
||||
msgstr ""
|
||||
msgstr "Fijar a mudo"
|
||||
|
||||
#: ui/help-overlay.ui:139
|
||||
msgid "Next chapter"
|
||||
msgstr ""
|
||||
msgstr "Capítulo siguiente"
|
||||
|
||||
#: ui/help-overlay.ui:145
|
||||
msgid "Previous chapter"
|
||||
msgstr ""
|
||||
msgstr "Capítulo anterior"
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:11
|
||||
msgid "Decoders"
|
||||
msgstr ""
|
||||
msgstr "Decodificadores"
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:18
|
||||
msgid "Return to the preferences"
|
||||
msgstr ""
|
||||
msgstr "Regresar a preferencias"
|
||||
|
||||
#: ui/preferences-window.ui:16
|
||||
msgid "Behavior"
|
||||
msgstr ""
|
||||
msgstr "Configuraciones"
|
||||
|
||||
#: ui/preferences-window.ui:19
|
||||
msgid "Auto fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Pantalla completa automática"
|
||||
|
||||
#: ui/preferences-window.ui:20
|
||||
msgid "Enter fullscreen when playlist is replaced except floating mode"
|
||||
msgstr ""
|
||||
msgstr "Entra a pantalla completa cuando se reemplaza la lista de reproducción, excepto en modo flotante"
|
||||
|
||||
#: ui/preferences-window.ui:26
|
||||
msgid "Ask to resume recent media"
|
||||
msgstr ""
|
||||
msgstr "Preguntar al reanudar los medios recientes"
|
||||
|
||||
#: ui/preferences-window.ui:32
|
||||
msgid "Float on all workspaces"
|
||||
msgstr ""
|
||||
msgstr "Flotar todos los espacios de trabajo"
|
||||
|
||||
#: ui/preferences-window.ui:33
|
||||
msgid "This option only works on GNOME"
|
||||
msgstr ""
|
||||
msgstr "Esta opción solo funciona en GNOME"
|
||||
|
||||
#: ui/preferences-window.ui:39
|
||||
msgid "After playback"
|
||||
msgstr ""
|
||||
msgstr "Después de reproducción "
|
||||
|
||||
#: ui/preferences-window.ui:44
|
||||
msgid "Do nothing"
|
||||
msgstr ""
|
||||
msgstr "Nada por hacer"
|
||||
|
||||
#: ui/preferences-window.ui:45
|
||||
msgid "Freeze last frame"
|
||||
msgstr ""
|
||||
msgstr "Detener último fotograma"
|
||||
|
||||
#: ui/preferences-window.ui:46
|
||||
msgid "Close the app"
|
||||
msgstr ""
|
||||
msgstr "Cerrar la aplicación"
|
||||
|
||||
#: ui/preferences-window.ui:56
|
||||
msgid "Volume"
|
||||
msgstr ""
|
||||
msgstr "Volumen"
|
||||
|
||||
#: ui/preferences-window.ui:59
|
||||
msgid "Custom initial value"
|
||||
msgstr ""
|
||||
msgstr "Valor inicial personalizado"
|
||||
|
||||
#: ui/preferences-window.ui:60
|
||||
msgid "Set custom volume at startup instead of restoring it"
|
||||
msgstr ""
|
||||
msgstr "Establece un volumen personalizado al inicio en lugar de restaurarlo"
|
||||
|
||||
#: ui/preferences-window.ui:64
|
||||
msgid "Volume percentage"
|
||||
msgstr ""
|
||||
msgstr "Porcentaje de volumen"
|
||||
|
||||
#: ui/preferences-window.ui:75
|
||||
msgid "Seeking"
|
||||
msgstr ""
|
||||
msgstr "Buscando"
|
||||
|
||||
#: ui/preferences-window.ui:78
|
||||
msgid "Mode"
|
||||
msgstr ""
|
||||
msgstr "Modo"
|
||||
|
||||
#: ui/preferences-window.ui:84
|
||||
msgid "Accurate"
|
||||
msgstr ""
|
||||
msgstr "Precisión"
|
||||
|
||||
#: ui/preferences-window.ui:85
|
||||
msgid "Fast"
|
||||
msgstr ""
|
||||
msgstr "Rápido"
|
||||
|
||||
#: ui/preferences-window.ui:93
|
||||
msgid "Unit"
|
||||
msgstr ""
|
||||
msgstr "Unidad"
|
||||
|
||||
#: ui/preferences-window.ui:98
|
||||
msgid "Second"
|
||||
msgstr ""
|
||||
msgstr "Segundo"
|
||||
|
||||
#: ui/preferences-window.ui:99
|
||||
msgid "Minute"
|
||||
msgstr ""
|
||||
msgstr "Minuto"
|
||||
|
||||
#: ui/preferences-window.ui:100
|
||||
msgid "Percentage"
|
||||
msgstr ""
|
||||
msgstr "Porcentaje"
|
||||
|
||||
#: ui/preferences-window.ui:108
|
||||
msgid "Value"
|
||||
msgstr ""
|
||||
msgstr "Valor"
|
||||
|
||||
#: ui/preferences-window.ui:123
|
||||
msgid "Audio"
|
||||
msgstr ""
|
||||
msgstr "Audio"
|
||||
|
||||
#: ui/preferences-window.ui:126
|
||||
msgid "Offset in milliseconds"
|
||||
msgstr ""
|
||||
msgstr "Compensación en milisegundos"
|
||||
|
||||
#: ui/preferences-window.ui:133
|
||||
msgid "Only native audio formats"
|
||||
msgstr ""
|
||||
msgstr "Solo formatos de audio nativos"
|
||||
|
||||
#: ui/preferences-window.ui:141
|
||||
msgid "Subtitles"
|
||||
msgstr ""
|
||||
msgstr "Subtítulos"
|
||||
|
||||
#: ui/preferences-window.ui:144
|
||||
msgid "Default font"
|
||||
msgstr ""
|
||||
msgstr "Fuente por defecto"
|
||||
|
||||
#: ui/preferences-window.ui:154
|
||||
msgid "Network"
|
||||
msgstr ""
|
||||
msgstr "Red"
|
||||
|
||||
#: ui/preferences-window.ui:158
|
||||
msgid "Client"
|
||||
msgstr ""
|
||||
msgstr "Cliente"
|
||||
|
||||
#: ui/preferences-window.ui:161
|
||||
msgid "Progressive download buffering"
|
||||
msgstr ""
|
||||
msgstr "Bajada progresiva de búfer"
|
||||
|
||||
#: ui/preferences-window.ui:169
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
msgstr "Servidor"
|
||||
|
||||
#: ui/preferences-window.ui:172
|
||||
msgid "Control player remotely"
|
||||
msgstr ""
|
||||
msgstr "Controlar el reproductor remotamente"
|
||||
|
||||
#: ui/preferences-window.ui:176
|
||||
msgid "Listening port"
|
||||
msgstr ""
|
||||
msgstr "Puerto de escucha"
|
||||
|
||||
#: ui/preferences-window.ui:183
|
||||
msgid "Run web application in background"
|
||||
msgstr ""
|
||||
msgstr "Ejecutar la aplicación web en modo demonio"
|
||||
|
||||
#: ui/preferences-window.ui:184
|
||||
msgid "Requires GTK compiled with Broadway backend"
|
||||
msgstr ""
|
||||
msgstr "Requiere GTK compilado con el backend de Broadway"
|
||||
|
||||
#: ui/preferences-window.ui:190
|
||||
msgid "Web application port"
|
||||
msgstr ""
|
||||
msgstr "Puerto de la aplicación web"
|
||||
|
||||
#: ui/preferences-window.ui:204
|
||||
msgid "Prefer adaptive streaming"
|
||||
msgstr ""
|
||||
msgstr "Preferir la transmisión adaptativa "
|
||||
|
||||
#: ui/preferences-window.ui:210
|
||||
msgid "Max quality"
|
||||
msgstr ""
|
||||
msgstr "Calidad máxima"
|
||||
|
||||
#: ui/preferences-window.ui:228
|
||||
msgid "Tweaks"
|
||||
msgstr ""
|
||||
msgstr "Retoques"
|
||||
|
||||
#: ui/preferences-window.ui:232
|
||||
msgid "Appearance"
|
||||
msgstr ""
|
||||
msgstr "Apariencia"
|
||||
|
||||
#: ui/preferences-window.ui:235
|
||||
msgid "Dark theme"
|
||||
msgstr ""
|
||||
msgstr "Tema oscuro"
|
||||
|
||||
#: ui/preferences-window.ui:241
|
||||
msgid "Render window shadows"
|
||||
msgstr ""
|
||||
msgstr "Renderizar sombras de ventana"
|
||||
|
||||
#: ui/preferences-window.ui:242
|
||||
msgid "Disable to increase performance when windowed"
|
||||
msgstr ""
|
||||
msgstr "Deshabilitado aumenta el rendimiento cuando se abre en ventana"
|
||||
|
||||
#: ui/preferences-window.ui:253
|
||||
msgid "Plugin ranking"
|
||||
msgstr ""
|
||||
msgstr "Rango de enchufes"
|
||||
|
||||
#: ui/preferences-window.ui:254
|
||||
msgid "Alter default ranks of GStreamer plugins"
|
||||
msgstr ""
|
||||
msgstr "Altera los rangos predeterminados de los enchufes de GStreamer"
|
||||
|
||||
#: ui/preferences-window.ui:259
|
||||
msgid "Use playbin3"
|
||||
msgstr ""
|
||||
msgstr "Usar Playbin3"
|
||||
|
||||
#: ui/preferences-window.ui:260 ui/preferences-window.ui:269
|
||||
msgid "Requires player restart"
|
||||
msgstr ""
|
||||
msgstr "Require reiniciar el reproductor"
|
||||
|
||||
#: ui/preferences-window.ui:262 ui/preferences-window.ui:271
|
||||
msgid "Experimental"
|
||||
msgstr ""
|
||||
msgstr "Experimental"
|
||||
|
||||
#: ui/preferences-window.ui:268
|
||||
msgid "Use PipeWire for audio output"
|
||||
msgstr ""
|
||||
msgstr "Usar PipeWire"
|
||||
|
||||
#: src/buttons.js:201
|
||||
#, javascript-format
|
||||
msgid "Decoder: %s"
|
||||
msgstr ""
|
||||
msgstr "Decodificador: %s"
|
||||
|
||||
#: src/dialogs.js:152
|
||||
msgid "Enter or drop URI here"
|
||||
msgstr ""
|
||||
msgstr "Introducir la URI"
|
||||
|
||||
#: src/dialogs.js:157
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "Cancelar"
|
||||
|
||||
#: src/dialogs.js:158
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
msgstr "Abrir"
|
||||
|
||||
#: src/dialogs.js:226
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
msgid "Title"
|
||||
msgstr "Título"
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr "Completado"
|
||||
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr "Resumir el reproductor?"
|
||||
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
msgstr "Versión GTK: %s"
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
msgstr "Versión LibAdwaita: %s"
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr "Versión GStreamer: %s"
|
||||
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr "Versión GJS: %s"
|
||||
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
msgstr "Un reproductor multimedia de GNOME impulsado por GStreamer"
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr "carlosgonz"
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
msgstr "Termina en: %s"
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
msgstr "Indeterminado"
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
msgstr "Canales"
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
msgstr "Deshabilitar"
|
||||
|
||||
|
459
po/eu.po
Normal file
459
po/eu.po
Normal file
@@ -0,0 +1,459 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2022-01-16 16:58\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Basque\n"
|
||||
"Language: eu_ES\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Crowdin-Project: clapper\n"
|
||||
"X-Crowdin-Project-ID: 473374\n"
|
||||
"X-Crowdin-Language: eu\n"
|
||||
"X-Crowdin-File: /master/po/com.github.rafostar.Clapper.pot\n"
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
msgid "Preferences"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:20
|
||||
msgid "Shortcuts"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:26
|
||||
msgid "About Clapper"
|
||||
msgstr ""
|
||||
|
||||
#: ui/elapsed-time-button.ui:27
|
||||
msgid "Speed"
|
||||
msgstr ""
|
||||
|
||||
#: ui/elapsed-time-button.ui:41 ui/preferences-window.ui:83
|
||||
#: ui/preferences-window.ui:215
|
||||
msgid "Normal"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:10 ui/preferences-window.ui:12
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:13
|
||||
msgid "Show shortcuts"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:19
|
||||
msgid "Toggle fullscreen"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:20
|
||||
msgid "Double tap | Double click"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:26
|
||||
msgid "Leave fullscreen"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:32
|
||||
msgid "Reveal OSD (fullscreen only)"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:33
|
||||
msgid "Tap"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:39
|
||||
msgid "Quit"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:47
|
||||
msgid "Media"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:50
|
||||
msgid "Open files"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:56 src/dialogs.js:137
|
||||
msgid "Open URI"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:64
|
||||
msgid "Playlist"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:67
|
||||
msgid "Next item"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:68
|
||||
msgid "Double tap (right side)"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:74
|
||||
msgid "Previous item"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:75
|
||||
msgid "Double tap (left side)"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:81
|
||||
msgid "Change repeat mode"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:87
|
||||
msgid "Export to file"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:95 ui/preferences-window.ui:119
|
||||
msgid "Playback"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:98
|
||||
msgid "Toggle play"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:99
|
||||
msgid "Long press | Right click"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:105
|
||||
msgid "Seek forward"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:106
|
||||
msgid "Swipe right | Scroll right"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:112
|
||||
msgid "Seek backward"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:113
|
||||
msgid "Swipe left | Scroll left"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:119
|
||||
msgid "Volume up"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:120
|
||||
msgid "Swipe up | Scroll up"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:126
|
||||
msgid "Volume down"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:127
|
||||
msgid "Swipe down | Scroll down"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:133
|
||||
msgid "Toggle mute"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:139
|
||||
msgid "Next chapter"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:145
|
||||
msgid "Previous chapter"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:11
|
||||
msgid "Decoders"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:18
|
||||
msgid "Return to the preferences"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:16
|
||||
msgid "Behavior"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:19
|
||||
msgid "Auto fullscreen"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:20
|
||||
msgid "Enter fullscreen when playlist is replaced except floating mode"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:26
|
||||
msgid "Ask to resume recent media"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:32
|
||||
msgid "Float on all workspaces"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:33
|
||||
msgid "This option only works on GNOME"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:39
|
||||
msgid "After playback"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:44
|
||||
msgid "Do nothing"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:45
|
||||
msgid "Freeze last frame"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:46
|
||||
msgid "Close the app"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:56
|
||||
msgid "Volume"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:59
|
||||
msgid "Custom initial value"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:60
|
||||
msgid "Set custom volume at startup instead of restoring it"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:64
|
||||
msgid "Volume percentage"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:75
|
||||
msgid "Seeking"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:78
|
||||
msgid "Mode"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:84
|
||||
msgid "Accurate"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:85
|
||||
msgid "Fast"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:93
|
||||
msgid "Unit"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:98
|
||||
msgid "Second"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:99
|
||||
msgid "Minute"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:100
|
||||
msgid "Percentage"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:108
|
||||
msgid "Value"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:123
|
||||
msgid "Audio"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:126
|
||||
msgid "Offset in milliseconds"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:133
|
||||
msgid "Only native audio formats"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:141
|
||||
msgid "Subtitles"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:144
|
||||
msgid "Default font"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:154
|
||||
msgid "Network"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:158
|
||||
msgid "Client"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:161
|
||||
msgid "Progressive download buffering"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:169
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:172
|
||||
msgid "Control player remotely"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:176
|
||||
msgid "Listening port"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:183
|
||||
msgid "Run web application in background"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:184
|
||||
msgid "Requires GTK compiled with Broadway backend"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:190
|
||||
msgid "Web application port"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:204
|
||||
msgid "Prefer adaptive streaming"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:210
|
||||
msgid "Max quality"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:228
|
||||
msgid "Tweaks"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:232
|
||||
msgid "Appearance"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:235
|
||||
msgid "Dark theme"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:241
|
||||
msgid "Render window shadows"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:242
|
||||
msgid "Disable to increase performance when windowed"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:253
|
||||
msgid "Plugin ranking"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:254
|
||||
msgid "Alter default ranks of GStreamer plugins"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:259
|
||||
msgid "Use playbin3"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:260 ui/preferences-window.ui:269
|
||||
msgid "Requires player restart"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:262 ui/preferences-window.ui:271
|
||||
msgid "Experimental"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:268
|
||||
msgid "Use PipeWire for audio output"
|
||||
msgstr ""
|
||||
|
||||
#: src/buttons.js:201
|
||||
#, javascript-format
|
||||
msgid "Decoder: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:152
|
||||
msgid "Enter or drop URI here"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:157
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:158
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
35
po/fi.po
35
po/fi.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:31\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-14 15:25\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Finnish\n"
|
||||
"Language: fi_FI\n"
|
||||
@@ -18,11 +18,11 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgid "Open Files…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgid "Open URI…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
@@ -399,56 +399,61 @@ msgstr ""
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
|
267
po/fr.po
267
po/fr.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:31\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2022-01-18 20:57\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: French\n"
|
||||
"Language: fr_FR\n"
|
||||
@@ -18,437 +18,442 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgstr ""
|
||||
msgid "Open Files…"
|
||||
msgstr "Ouvrir un fichier…"
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgstr ""
|
||||
msgid "Open URI…"
|
||||
msgstr "Ouvrir une URL…"
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
msgid "Preferences"
|
||||
msgstr ""
|
||||
msgstr "Préférences"
|
||||
|
||||
#: ui/clapper.ui:20
|
||||
msgid "Shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Raccourcis clavier"
|
||||
|
||||
#: ui/clapper.ui:26
|
||||
msgid "About Clapper"
|
||||
msgstr ""
|
||||
msgstr "Á propos de Clapper"
|
||||
|
||||
#: ui/elapsed-time-button.ui:27
|
||||
msgid "Speed"
|
||||
msgstr ""
|
||||
msgstr "Vitesse"
|
||||
|
||||
#: ui/elapsed-time-button.ui:41 ui/preferences-window.ui:83
|
||||
#: ui/preferences-window.ui:215
|
||||
msgid "Normal"
|
||||
msgstr ""
|
||||
msgstr "Normal"
|
||||
|
||||
#: ui/help-overlay.ui:10 ui/preferences-window.ui:12
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
msgstr "Général"
|
||||
|
||||
#: ui/help-overlay.ui:13
|
||||
msgid "Show shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Montrer les raccourcis"
|
||||
|
||||
#: ui/help-overlay.ui:19
|
||||
msgid "Toggle fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Basculer en plein écran"
|
||||
|
||||
#: ui/help-overlay.ui:20
|
||||
msgid "Double tap | Double click"
|
||||
msgstr ""
|
||||
msgstr "Tapoter/cliquer deux fois"
|
||||
|
||||
#: ui/help-overlay.ui:26
|
||||
msgid "Leave fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Sortir du plein écran"
|
||||
|
||||
#: ui/help-overlay.ui:32
|
||||
msgid "Reveal OSD (fullscreen only)"
|
||||
msgstr ""
|
||||
msgstr "Afficher les commandes de lecture (seulement en plein écran)"
|
||||
|
||||
#: ui/help-overlay.ui:33
|
||||
msgid "Tap"
|
||||
msgstr ""
|
||||
msgstr "Taper"
|
||||
|
||||
#: ui/help-overlay.ui:39
|
||||
msgid "Quit"
|
||||
msgstr ""
|
||||
msgstr "Quitter"
|
||||
|
||||
#: ui/help-overlay.ui:47
|
||||
msgid "Media"
|
||||
msgstr ""
|
||||
msgstr "Média"
|
||||
|
||||
#: ui/help-overlay.ui:50
|
||||
msgid "Open files"
|
||||
msgstr ""
|
||||
msgstr "Ouvrir un fichier"
|
||||
|
||||
#: ui/help-overlay.ui:56 src/dialogs.js:137
|
||||
msgid "Open URI"
|
||||
msgstr ""
|
||||
msgstr "Ouvrir une URL"
|
||||
|
||||
#: ui/help-overlay.ui:64
|
||||
msgid "Playlist"
|
||||
msgstr ""
|
||||
msgstr "Playlist"
|
||||
|
||||
#: ui/help-overlay.ui:67
|
||||
msgid "Next item"
|
||||
msgstr ""
|
||||
msgstr "Prochain média"
|
||||
|
||||
#: ui/help-overlay.ui:68
|
||||
msgid "Double tap (right side)"
|
||||
msgstr ""
|
||||
msgstr "Tapoter deux fois (côté droit)"
|
||||
|
||||
#: ui/help-overlay.ui:74
|
||||
msgid "Previous item"
|
||||
msgstr ""
|
||||
msgstr "Média précédent"
|
||||
|
||||
#: ui/help-overlay.ui:75
|
||||
msgid "Double tap (left side)"
|
||||
msgstr ""
|
||||
msgstr "Tapoter deux fois (côté gauche)"
|
||||
|
||||
#: ui/help-overlay.ui:81
|
||||
msgid "Change repeat mode"
|
||||
msgstr ""
|
||||
msgstr "Changer le mode de répétition"
|
||||
|
||||
#: ui/help-overlay.ui:87
|
||||
msgid "Export to file"
|
||||
msgstr ""
|
||||
msgstr "Exporter vers un fichier"
|
||||
|
||||
#: ui/help-overlay.ui:95 ui/preferences-window.ui:119
|
||||
msgid "Playback"
|
||||
msgstr ""
|
||||
msgstr "Lecture"
|
||||
|
||||
#: ui/help-overlay.ui:98
|
||||
msgid "Toggle play"
|
||||
msgstr ""
|
||||
msgstr "Relancer/stopper la lecture"
|
||||
|
||||
#: ui/help-overlay.ui:99
|
||||
msgid "Long press | Right click"
|
||||
msgstr ""
|
||||
msgstr "Longue pression | Clic droit"
|
||||
|
||||
#: ui/help-overlay.ui:105
|
||||
msgid "Seek forward"
|
||||
msgstr ""
|
||||
msgstr "Avancer dans la lecture"
|
||||
|
||||
#: ui/help-overlay.ui:106
|
||||
msgid "Swipe right | Scroll right"
|
||||
msgstr ""
|
||||
msgstr "Glisser/Faire défiler vers la droite"
|
||||
|
||||
#: ui/help-overlay.ui:112
|
||||
msgid "Seek backward"
|
||||
msgstr ""
|
||||
msgstr "Reculer dans la lecture"
|
||||
|
||||
#: ui/help-overlay.ui:113
|
||||
msgid "Swipe left | Scroll left"
|
||||
msgstr ""
|
||||
msgstr "Glisser/Faire défiler vers la gauche"
|
||||
|
||||
#: ui/help-overlay.ui:119
|
||||
msgid "Volume up"
|
||||
msgstr ""
|
||||
msgstr "Augmenter le volume"
|
||||
|
||||
#: ui/help-overlay.ui:120
|
||||
msgid "Swipe up | Scroll up"
|
||||
msgstr ""
|
||||
msgstr "Glisser/Défiler vers le haut"
|
||||
|
||||
#: ui/help-overlay.ui:126
|
||||
msgid "Volume down"
|
||||
msgstr ""
|
||||
msgstr "Baisser le volume"
|
||||
|
||||
#: ui/help-overlay.ui:127
|
||||
msgid "Swipe down | Scroll down"
|
||||
msgstr ""
|
||||
msgstr "Glisser/Défiler vers le bas"
|
||||
|
||||
#: ui/help-overlay.ui:133
|
||||
msgid "Toggle mute"
|
||||
msgstr ""
|
||||
msgstr "Basculer le mode silencieux"
|
||||
|
||||
#: ui/help-overlay.ui:139
|
||||
msgid "Next chapter"
|
||||
msgstr ""
|
||||
msgstr "Prochain chapitre"
|
||||
|
||||
#: ui/help-overlay.ui:145
|
||||
msgid "Previous chapter"
|
||||
msgstr ""
|
||||
msgstr "Chapitre précédent"
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:11
|
||||
msgid "Decoders"
|
||||
msgstr ""
|
||||
msgstr "Décodeurs"
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:18
|
||||
msgid "Return to the preferences"
|
||||
msgstr ""
|
||||
msgstr "Retourner aux préférences"
|
||||
|
||||
#: ui/preferences-window.ui:16
|
||||
msgid "Behavior"
|
||||
msgstr ""
|
||||
msgstr "Comportement"
|
||||
|
||||
#: ui/preferences-window.ui:19
|
||||
msgid "Auto fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Lecture automatique en plein écran"
|
||||
|
||||
#: ui/preferences-window.ui:20
|
||||
msgid "Enter fullscreen when playlist is replaced except floating mode"
|
||||
msgstr ""
|
||||
msgstr "Basculer en plein écran quand la playlisyt est remplacée sauf si le mode flottant est activé"
|
||||
|
||||
#: ui/preferences-window.ui:26
|
||||
msgid "Ask to resume recent media"
|
||||
msgstr ""
|
||||
msgstr "Demander pour reprendre à la position des médias récents"
|
||||
|
||||
#: ui/preferences-window.ui:32
|
||||
msgid "Float on all workspaces"
|
||||
msgstr ""
|
||||
msgstr "Flotter sur tous les bureaux virtuels"
|
||||
|
||||
#: ui/preferences-window.ui:33
|
||||
msgid "This option only works on GNOME"
|
||||
msgstr ""
|
||||
msgstr "Cette option ne marche qu'avec GNOME"
|
||||
|
||||
#: ui/preferences-window.ui:39
|
||||
msgid "After playback"
|
||||
msgstr ""
|
||||
msgstr "Après la lecture"
|
||||
|
||||
#: ui/preferences-window.ui:44
|
||||
msgid "Do nothing"
|
||||
msgstr ""
|
||||
msgstr "Ne rien faire"
|
||||
|
||||
#: ui/preferences-window.ui:45
|
||||
msgid "Freeze last frame"
|
||||
msgstr ""
|
||||
msgstr "Geler la dernière image"
|
||||
|
||||
#: ui/preferences-window.ui:46
|
||||
msgid "Close the app"
|
||||
msgstr ""
|
||||
msgstr "Fermer l'application"
|
||||
|
||||
#: ui/preferences-window.ui:56
|
||||
msgid "Volume"
|
||||
msgstr ""
|
||||
msgstr "Volume"
|
||||
|
||||
#: ui/preferences-window.ui:59
|
||||
msgid "Custom initial value"
|
||||
msgstr ""
|
||||
msgstr "Valeur initiale personnalisée"
|
||||
|
||||
#: ui/preferences-window.ui:60
|
||||
msgid "Set custom volume at startup instead of restoring it"
|
||||
msgstr ""
|
||||
msgstr "Régler une valeur personnalisée du volume au démarrage au lien de restorer la valeur précédente"
|
||||
|
||||
#: ui/preferences-window.ui:64
|
||||
msgid "Volume percentage"
|
||||
msgstr ""
|
||||
msgstr "Pourcentage du volume"
|
||||
|
||||
#: ui/preferences-window.ui:75
|
||||
msgid "Seeking"
|
||||
msgstr ""
|
||||
msgstr "Avancement"
|
||||
|
||||
#: ui/preferences-window.ui:78
|
||||
msgid "Mode"
|
||||
msgstr ""
|
||||
msgstr "Comportement"
|
||||
|
||||
#: ui/preferences-window.ui:84
|
||||
msgid "Accurate"
|
||||
msgstr ""
|
||||
msgstr "Précis"
|
||||
|
||||
#: ui/preferences-window.ui:85
|
||||
msgid "Fast"
|
||||
msgstr ""
|
||||
msgstr "Rapide"
|
||||
|
||||
#: ui/preferences-window.ui:93
|
||||
msgid "Unit"
|
||||
msgstr ""
|
||||
msgstr "Unité des sauts"
|
||||
|
||||
#: ui/preferences-window.ui:98
|
||||
msgid "Second"
|
||||
msgstr ""
|
||||
msgstr "Seconde"
|
||||
|
||||
#: ui/preferences-window.ui:99
|
||||
msgid "Minute"
|
||||
msgstr ""
|
||||
msgstr "Minute"
|
||||
|
||||
#: ui/preferences-window.ui:100
|
||||
msgid "Percentage"
|
||||
msgstr ""
|
||||
msgstr "Pourcentage"
|
||||
|
||||
#: ui/preferences-window.ui:108
|
||||
msgid "Value"
|
||||
msgstr ""
|
||||
msgstr "Longueur du saut"
|
||||
|
||||
#: ui/preferences-window.ui:123
|
||||
msgid "Audio"
|
||||
msgstr ""
|
||||
msgstr "Audio"
|
||||
|
||||
#: ui/preferences-window.ui:126
|
||||
msgid "Offset in milliseconds"
|
||||
msgstr ""
|
||||
msgstr "Décalage en millisecondes"
|
||||
|
||||
#: ui/preferences-window.ui:133
|
||||
msgid "Only native audio formats"
|
||||
msgstr ""
|
||||
msgstr "Seulement des formats audios natifs"
|
||||
|
||||
#: ui/preferences-window.ui:141
|
||||
msgid "Subtitles"
|
||||
msgstr ""
|
||||
msgstr "Sous-titres"
|
||||
|
||||
#: ui/preferences-window.ui:144
|
||||
msgid "Default font"
|
||||
msgstr ""
|
||||
msgstr "Police par défaut"
|
||||
|
||||
#: ui/preferences-window.ui:154
|
||||
msgid "Network"
|
||||
msgstr ""
|
||||
msgstr "Réseau"
|
||||
|
||||
#: ui/preferences-window.ui:158
|
||||
msgid "Client"
|
||||
msgstr ""
|
||||
msgstr "Client"
|
||||
|
||||
#: ui/preferences-window.ui:161
|
||||
msgid "Progressive download buffering"
|
||||
msgstr ""
|
||||
msgstr "Téléchargement progressif dans le tampon"
|
||||
|
||||
#: ui/preferences-window.ui:169
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
msgstr "Serveur"
|
||||
|
||||
#: ui/preferences-window.ui:172
|
||||
msgid "Control player remotely"
|
||||
msgstr ""
|
||||
msgstr "Controler le lecteur à distance"
|
||||
|
||||
#: ui/preferences-window.ui:176
|
||||
msgid "Listening port"
|
||||
msgstr ""
|
||||
msgstr "Écouter sur le port"
|
||||
|
||||
#: ui/preferences-window.ui:183
|
||||
msgid "Run web application in background"
|
||||
msgstr ""
|
||||
msgstr "Lancer l'application web en arrière plan"
|
||||
|
||||
#: ui/preferences-window.ui:184
|
||||
msgid "Requires GTK compiled with Broadway backend"
|
||||
msgstr ""
|
||||
msgstr "Requiert GTK compilé avec l'interface Broadway"
|
||||
|
||||
#: ui/preferences-window.ui:190
|
||||
msgid "Web application port"
|
||||
msgstr ""
|
||||
msgstr "Port de l'application web"
|
||||
|
||||
#: ui/preferences-window.ui:204
|
||||
msgid "Prefer adaptive streaming"
|
||||
msgstr ""
|
||||
msgstr "Préférer le streaming adaptatif"
|
||||
|
||||
#: ui/preferences-window.ui:210
|
||||
msgid "Max quality"
|
||||
msgstr ""
|
||||
msgstr "Qualité maximale"
|
||||
|
||||
#: ui/preferences-window.ui:228
|
||||
msgid "Tweaks"
|
||||
msgstr ""
|
||||
msgstr "Réglages"
|
||||
|
||||
#: ui/preferences-window.ui:232
|
||||
msgid "Appearance"
|
||||
msgstr ""
|
||||
msgstr "Apparence"
|
||||
|
||||
#: ui/preferences-window.ui:235
|
||||
msgid "Dark theme"
|
||||
msgstr ""
|
||||
msgstr "Thème sombre"
|
||||
|
||||
#: ui/preferences-window.ui:241
|
||||
msgid "Render window shadows"
|
||||
msgstr ""
|
||||
msgstr "Afficher les ombres de la fenêtre"
|
||||
|
||||
#: ui/preferences-window.ui:242
|
||||
msgid "Disable to increase performance when windowed"
|
||||
msgstr ""
|
||||
msgstr "Désactiver pour améliorer les performances quand fenêtré"
|
||||
|
||||
#: ui/preferences-window.ui:253
|
||||
msgid "Plugin ranking"
|
||||
msgstr ""
|
||||
msgstr "Liste des plugins"
|
||||
|
||||
#: ui/preferences-window.ui:254
|
||||
msgid "Alter default ranks of GStreamer plugins"
|
||||
msgstr ""
|
||||
msgstr "Changer les options par défaut de plugins GStreamer"
|
||||
|
||||
#: ui/preferences-window.ui:259
|
||||
msgid "Use playbin3"
|
||||
msgstr ""
|
||||
msgstr "Utiliser playbin3"
|
||||
|
||||
#: ui/preferences-window.ui:260 ui/preferences-window.ui:269
|
||||
msgid "Requires player restart"
|
||||
msgstr ""
|
||||
msgstr "Requiert le redémarrage du lecteur"
|
||||
|
||||
#: ui/preferences-window.ui:262 ui/preferences-window.ui:271
|
||||
msgid "Experimental"
|
||||
msgstr ""
|
||||
msgstr "Expérimental"
|
||||
|
||||
#: ui/preferences-window.ui:268
|
||||
msgid "Use PipeWire for audio output"
|
||||
msgstr ""
|
||||
msgstr "Utiliser PipeWire pour la sortie audio"
|
||||
|
||||
#: src/buttons.js:201
|
||||
#, javascript-format
|
||||
msgid "Decoder: %s"
|
||||
msgstr ""
|
||||
msgstr "Décodeur: %s"
|
||||
|
||||
#: src/dialogs.js:152
|
||||
msgid "Enter or drop URI here"
|
||||
msgstr ""
|
||||
msgstr "Entrer ou déposer une URL ici"
|
||||
|
||||
#: src/dialogs.js:157
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "Annuler"
|
||||
|
||||
#: src/dialogs.js:158
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
msgstr "Ouvrir"
|
||||
|
||||
#: src/dialogs.js:226
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
msgid "Title"
|
||||
msgstr "Titre"
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr "Terminé"
|
||||
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr "Reprendre la lecture?"
|
||||
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
msgstr "Version de GTK: %s"
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
msgstr "Version d'Adwaita: %s"
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr "Version de GStreamer: %s"
|
||||
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr "Version de GJS: %s"
|
||||
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
msgstr "Un lecteur multimédia pour GNOME propulsé par GStreamer"
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr "Robin Verdenal-Tallieux"
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
msgstr "Finit à: %s"
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
msgstr "Indéterminé"
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
msgstr "Chaines"
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
msgstr "Désactivé"
|
||||
|
||||
|
35
po/he.po
35
po/he.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:31\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-14 15:25\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Hebrew\n"
|
||||
"Language: he_IL\n"
|
||||
@@ -18,11 +18,11 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgid "Open Files…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgid "Open URI…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
@@ -399,56 +399,61 @@ msgstr ""
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
|
267
po/hu.po
267
po/hu.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:31\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-21 16:37\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Hungarian\n"
|
||||
"Language: hu_HU\n"
|
||||
@@ -18,437 +18,442 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgstr ""
|
||||
msgid "Open Files…"
|
||||
msgstr "Fájlok megnyitása…"
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgstr ""
|
||||
msgid "Open URI…"
|
||||
msgstr "URI megnyitása…"
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
msgid "Preferences"
|
||||
msgstr ""
|
||||
msgstr "Beállítások"
|
||||
|
||||
#: ui/clapper.ui:20
|
||||
msgid "Shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Gyorsbillentyűk"
|
||||
|
||||
#: ui/clapper.ui:26
|
||||
msgid "About Clapper"
|
||||
msgstr ""
|
||||
msgstr "A Clapper -ről"
|
||||
|
||||
#: ui/elapsed-time-button.ui:27
|
||||
msgid "Speed"
|
||||
msgstr ""
|
||||
msgstr "Sebesség"
|
||||
|
||||
#: ui/elapsed-time-button.ui:41 ui/preferences-window.ui:83
|
||||
#: ui/preferences-window.ui:215
|
||||
msgid "Normal"
|
||||
msgstr ""
|
||||
msgstr "Normál"
|
||||
|
||||
#: ui/help-overlay.ui:10 ui/preferences-window.ui:12
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
msgstr "Általános beállítások"
|
||||
|
||||
#: ui/help-overlay.ui:13
|
||||
msgid "Show shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Gyorsbillentyűk megjelenítése"
|
||||
|
||||
#: ui/help-overlay.ui:19
|
||||
msgid "Toggle fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Teljes képernyő be/ki"
|
||||
|
||||
#: ui/help-overlay.ui:20
|
||||
msgid "Double tap | Double click"
|
||||
msgstr ""
|
||||
msgstr "Dupla koppintás | Dupla kattintás"
|
||||
|
||||
#: ui/help-overlay.ui:26
|
||||
msgid "Leave fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Teljes képernyő be/ki"
|
||||
|
||||
#: ui/help-overlay.ui:32
|
||||
msgid "Reveal OSD (fullscreen only)"
|
||||
msgstr ""
|
||||
msgstr "Képernyőn megjelenő kijelző (OSD) mutatása (csak teljes képernyős módban)"
|
||||
|
||||
#: ui/help-overlay.ui:33
|
||||
msgid "Tap"
|
||||
msgstr ""
|
||||
msgstr "Koppintás"
|
||||
|
||||
#: ui/help-overlay.ui:39
|
||||
msgid "Quit"
|
||||
msgstr ""
|
||||
msgstr "Kilépés"
|
||||
|
||||
#: ui/help-overlay.ui:47
|
||||
msgid "Media"
|
||||
msgstr ""
|
||||
msgstr "Média"
|
||||
|
||||
#: ui/help-overlay.ui:50
|
||||
msgid "Open files"
|
||||
msgstr ""
|
||||
msgstr "Fájlok megnyitása"
|
||||
|
||||
#: ui/help-overlay.ui:56 src/dialogs.js:137
|
||||
msgid "Open URI"
|
||||
msgstr ""
|
||||
msgstr "URI megnyitása"
|
||||
|
||||
#: ui/help-overlay.ui:64
|
||||
msgid "Playlist"
|
||||
msgstr ""
|
||||
msgstr "Lejátszólista"
|
||||
|
||||
#: ui/help-overlay.ui:67
|
||||
msgid "Next item"
|
||||
msgstr ""
|
||||
msgstr "Következő listaelem"
|
||||
|
||||
#: ui/help-overlay.ui:68
|
||||
msgid "Double tap (right side)"
|
||||
msgstr ""
|
||||
msgstr "Dupla koppintás (jobb oldalon)"
|
||||
|
||||
#: ui/help-overlay.ui:74
|
||||
msgid "Previous item"
|
||||
msgstr ""
|
||||
msgstr "Előző listaelem"
|
||||
|
||||
#: ui/help-overlay.ui:75
|
||||
msgid "Double tap (left side)"
|
||||
msgstr ""
|
||||
msgstr "Dupla koppintás (bal oldalon)"
|
||||
|
||||
#: ui/help-overlay.ui:81
|
||||
msgid "Change repeat mode"
|
||||
msgstr ""
|
||||
msgstr "Ismétlési típus változtatása"
|
||||
|
||||
#: ui/help-overlay.ui:87
|
||||
msgid "Export to file"
|
||||
msgstr ""
|
||||
msgstr "Exportálás fájlba"
|
||||
|
||||
#: ui/help-overlay.ui:95 ui/preferences-window.ui:119
|
||||
msgid "Playback"
|
||||
msgstr ""
|
||||
msgstr "Lejátszás"
|
||||
|
||||
#: ui/help-overlay.ui:98
|
||||
msgid "Toggle play"
|
||||
msgstr ""
|
||||
msgstr "Lejátszás indítása/megállítása"
|
||||
|
||||
#: ui/help-overlay.ui:99
|
||||
msgid "Long press | Right click"
|
||||
msgstr ""
|
||||
msgstr "Hosszú nyomás | Jobb kattintás"
|
||||
|
||||
#: ui/help-overlay.ui:105
|
||||
msgid "Seek forward"
|
||||
msgstr ""
|
||||
msgstr "Előretekerés"
|
||||
|
||||
#: ui/help-overlay.ui:106
|
||||
msgid "Swipe right | Scroll right"
|
||||
msgstr ""
|
||||
msgstr "Húzás jobbra | Görgetés jobbra"
|
||||
|
||||
#: ui/help-overlay.ui:112
|
||||
msgid "Seek backward"
|
||||
msgstr ""
|
||||
msgstr "Visszatekerés"
|
||||
|
||||
#: ui/help-overlay.ui:113
|
||||
msgid "Swipe left | Scroll left"
|
||||
msgstr ""
|
||||
msgstr "Húzás balra | Görgetés balra"
|
||||
|
||||
#: ui/help-overlay.ui:119
|
||||
msgid "Volume up"
|
||||
msgstr ""
|
||||
msgstr "Hangerő növelése"
|
||||
|
||||
#: ui/help-overlay.ui:120
|
||||
msgid "Swipe up | Scroll up"
|
||||
msgstr ""
|
||||
msgstr "Húzás felfelé | Görgetés felfelé"
|
||||
|
||||
#: ui/help-overlay.ui:126
|
||||
msgid "Volume down"
|
||||
msgstr ""
|
||||
msgstr "Hangerő csökkentése"
|
||||
|
||||
#: ui/help-overlay.ui:127
|
||||
msgid "Swipe down | Scroll down"
|
||||
msgstr ""
|
||||
msgstr "Húzás lefelé | Görgetés lefelé"
|
||||
|
||||
#: ui/help-overlay.ui:133
|
||||
msgid "Toggle mute"
|
||||
msgstr ""
|
||||
msgstr "Némítás be-/kikapcsolása"
|
||||
|
||||
#: ui/help-overlay.ui:139
|
||||
msgid "Next chapter"
|
||||
msgstr ""
|
||||
msgstr "Következő jelenet"
|
||||
|
||||
#: ui/help-overlay.ui:145
|
||||
msgid "Previous chapter"
|
||||
msgstr ""
|
||||
msgstr "Előző jelenet"
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:11
|
||||
msgid "Decoders"
|
||||
msgstr ""
|
||||
msgstr "Dekóderek"
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:18
|
||||
msgid "Return to the preferences"
|
||||
msgstr ""
|
||||
msgstr "Visszatérés a beállításokhoz"
|
||||
|
||||
#: ui/preferences-window.ui:16
|
||||
msgid "Behavior"
|
||||
msgstr ""
|
||||
msgstr "Viselkedés"
|
||||
|
||||
#: ui/preferences-window.ui:19
|
||||
msgid "Auto fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Automatikus teljes képernyős mód"
|
||||
|
||||
#: ui/preferences-window.ui:20
|
||||
msgid "Enter fullscreen when playlist is replaced except floating mode"
|
||||
msgstr ""
|
||||
msgstr "Teljes képernyős módra váltás a lejátszólista megváltoztatásakor (kivétel ha lebegőablakos módban vagyunk)"
|
||||
|
||||
#: ui/preferences-window.ui:26
|
||||
msgid "Ask to resume recent media"
|
||||
msgstr ""
|
||||
msgstr "Rákérdezés a legutóbbi média folytatására"
|
||||
|
||||
#: ui/preferences-window.ui:32
|
||||
msgid "Float on all workspaces"
|
||||
msgstr ""
|
||||
msgstr "Lebegő ablak az összes munkaasztalon"
|
||||
|
||||
#: ui/preferences-window.ui:33
|
||||
msgid "This option only works on GNOME"
|
||||
msgstr ""
|
||||
msgstr "Ez az opció csak GNOME asztali környezettel működik"
|
||||
|
||||
#: ui/preferences-window.ui:39
|
||||
msgid "After playback"
|
||||
msgstr ""
|
||||
msgstr "Lejátszás után"
|
||||
|
||||
#: ui/preferences-window.ui:44
|
||||
msgid "Do nothing"
|
||||
msgstr ""
|
||||
msgstr "Ne csináljon semmit"
|
||||
|
||||
#: ui/preferences-window.ui:45
|
||||
msgid "Freeze last frame"
|
||||
msgstr ""
|
||||
msgstr "Utolsó képkocka mutatása"
|
||||
|
||||
#: ui/preferences-window.ui:46
|
||||
msgid "Close the app"
|
||||
msgstr ""
|
||||
msgstr "Alkalmazás bezárása"
|
||||
|
||||
#: ui/preferences-window.ui:56
|
||||
msgid "Volume"
|
||||
msgstr ""
|
||||
msgstr "Hangerő"
|
||||
|
||||
#: ui/preferences-window.ui:59
|
||||
msgid "Custom initial value"
|
||||
msgstr ""
|
||||
msgstr "Egyedi kezdeti érték"
|
||||
|
||||
#: ui/preferences-window.ui:60
|
||||
msgid "Set custom volume at startup instead of restoring it"
|
||||
msgstr ""
|
||||
msgstr "Induláskor egyedi hangerő az utolsó visszaállítása helyett"
|
||||
|
||||
#: ui/preferences-window.ui:64
|
||||
msgid "Volume percentage"
|
||||
msgstr ""
|
||||
msgstr "Hangerő százalék"
|
||||
|
||||
#: ui/preferences-window.ui:75
|
||||
msgid "Seeking"
|
||||
msgstr ""
|
||||
msgstr "Tekerés"
|
||||
|
||||
#: ui/preferences-window.ui:78
|
||||
msgid "Mode"
|
||||
msgstr ""
|
||||
msgstr "Mód"
|
||||
|
||||
#: ui/preferences-window.ui:84
|
||||
msgid "Accurate"
|
||||
msgstr ""
|
||||
msgstr "Precíz"
|
||||
|
||||
#: ui/preferences-window.ui:85
|
||||
msgid "Fast"
|
||||
msgstr ""
|
||||
msgstr "Gyors"
|
||||
|
||||
#: ui/preferences-window.ui:93
|
||||
msgid "Unit"
|
||||
msgstr ""
|
||||
msgstr "Mértékegység"
|
||||
|
||||
#: ui/preferences-window.ui:98
|
||||
msgid "Second"
|
||||
msgstr ""
|
||||
msgstr "Másodperc"
|
||||
|
||||
#: ui/preferences-window.ui:99
|
||||
msgid "Minute"
|
||||
msgstr ""
|
||||
msgstr "Perc"
|
||||
|
||||
#: ui/preferences-window.ui:100
|
||||
msgid "Percentage"
|
||||
msgstr ""
|
||||
msgstr "Százalék"
|
||||
|
||||
#: ui/preferences-window.ui:108
|
||||
msgid "Value"
|
||||
msgstr ""
|
||||
msgstr "Érték"
|
||||
|
||||
#: ui/preferences-window.ui:123
|
||||
msgid "Audio"
|
||||
msgstr ""
|
||||
msgstr "Hang"
|
||||
|
||||
#: ui/preferences-window.ui:126
|
||||
msgid "Offset in milliseconds"
|
||||
msgstr ""
|
||||
msgstr "Eltolás miliszekundumban"
|
||||
|
||||
#: ui/preferences-window.ui:133
|
||||
msgid "Only native audio formats"
|
||||
msgstr ""
|
||||
msgstr "Csak natív hang formátumok"
|
||||
|
||||
#: ui/preferences-window.ui:141
|
||||
msgid "Subtitles"
|
||||
msgstr ""
|
||||
msgstr "Feliratok"
|
||||
|
||||
#: ui/preferences-window.ui:144
|
||||
msgid "Default font"
|
||||
msgstr ""
|
||||
msgstr "Alapértelmezett betűtípus"
|
||||
|
||||
#: ui/preferences-window.ui:154
|
||||
msgid "Network"
|
||||
msgstr ""
|
||||
msgstr "Hálózat"
|
||||
|
||||
#: ui/preferences-window.ui:158
|
||||
msgid "Client"
|
||||
msgstr ""
|
||||
msgstr "Kliens"
|
||||
|
||||
#: ui/preferences-window.ui:161
|
||||
msgid "Progressive download buffering"
|
||||
msgstr ""
|
||||
msgstr "Progresszív letöltéspufferelés"
|
||||
|
||||
#: ui/preferences-window.ui:169
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
msgstr "Szerver"
|
||||
|
||||
#: ui/preferences-window.ui:172
|
||||
msgid "Control player remotely"
|
||||
msgstr ""
|
||||
msgstr "Lejátszó távirányítása"
|
||||
|
||||
#: ui/preferences-window.ui:176
|
||||
msgid "Listening port"
|
||||
msgstr ""
|
||||
msgstr "Port figyelése"
|
||||
|
||||
#: ui/preferences-window.ui:183
|
||||
msgid "Run web application in background"
|
||||
msgstr ""
|
||||
msgstr "Web alkalmazás háttérben való futtatása"
|
||||
|
||||
#: ui/preferences-window.ui:184
|
||||
msgid "Requires GTK compiled with Broadway backend"
|
||||
msgstr ""
|
||||
msgstr "Broadway backenddel fordított GTK -t igényel"
|
||||
|
||||
#: ui/preferences-window.ui:190
|
||||
msgid "Web application port"
|
||||
msgstr ""
|
||||
msgstr "Web alkalmazás portja"
|
||||
|
||||
#: ui/preferences-window.ui:204
|
||||
msgid "Prefer adaptive streaming"
|
||||
msgstr ""
|
||||
msgstr "Adaptív streaming előnyben részesítése"
|
||||
|
||||
#: ui/preferences-window.ui:210
|
||||
msgid "Max quality"
|
||||
msgstr ""
|
||||
msgstr "Maximális minőség"
|
||||
|
||||
#: ui/preferences-window.ui:228
|
||||
msgid "Tweaks"
|
||||
msgstr ""
|
||||
msgstr "Finomhangolások"
|
||||
|
||||
#: ui/preferences-window.ui:232
|
||||
msgid "Appearance"
|
||||
msgstr ""
|
||||
msgstr "Megjelenés"
|
||||
|
||||
#: ui/preferences-window.ui:235
|
||||
msgid "Dark theme"
|
||||
msgstr ""
|
||||
msgstr "Sötét téma"
|
||||
|
||||
#: ui/preferences-window.ui:241
|
||||
msgid "Render window shadows"
|
||||
msgstr ""
|
||||
msgstr "Ablak árnyékok renderelése"
|
||||
|
||||
#: ui/preferences-window.ui:242
|
||||
msgid "Disable to increase performance when windowed"
|
||||
msgstr ""
|
||||
msgstr "Kikapcsolása javítja a teljesítményt ablakban futtatás esetén"
|
||||
|
||||
#: ui/preferences-window.ui:253
|
||||
msgid "Plugin ranking"
|
||||
msgstr ""
|
||||
msgstr "Bővítményrangsor"
|
||||
|
||||
#: ui/preferences-window.ui:254
|
||||
msgid "Alter default ranks of GStreamer plugins"
|
||||
msgstr ""
|
||||
msgstr "Az alapértelmezett GStreamer bővítményrangsor megváltoztatása"
|
||||
|
||||
#: ui/preferences-window.ui:259
|
||||
msgid "Use playbin3"
|
||||
msgstr ""
|
||||
msgstr "A playbin3 használata"
|
||||
|
||||
#: ui/preferences-window.ui:260 ui/preferences-window.ui:269
|
||||
msgid "Requires player restart"
|
||||
msgstr ""
|
||||
msgstr "A lejátszó újraindítását igényli"
|
||||
|
||||
#: ui/preferences-window.ui:262 ui/preferences-window.ui:271
|
||||
msgid "Experimental"
|
||||
msgstr ""
|
||||
msgstr "Kísérleti funkció"
|
||||
|
||||
#: ui/preferences-window.ui:268
|
||||
msgid "Use PipeWire for audio output"
|
||||
msgstr ""
|
||||
msgstr "A PipeWire használata hang kimenetként"
|
||||
|
||||
#: src/buttons.js:201
|
||||
#, javascript-format
|
||||
msgid "Decoder: %s"
|
||||
msgstr ""
|
||||
msgstr "Dekóder: %s"
|
||||
|
||||
#: src/dialogs.js:152
|
||||
msgid "Enter or drop URI here"
|
||||
msgstr ""
|
||||
msgstr "Adjon meg egy URI -t itt, vagy húzza és ejtse ide"
|
||||
|
||||
#: src/dialogs.js:157
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "Mégsem"
|
||||
|
||||
#: src/dialogs.js:158
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
msgstr "Megnyitás"
|
||||
|
||||
#: src/dialogs.js:226
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
msgid "Title"
|
||||
msgstr "Cím"
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr "Lejátszva"
|
||||
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr "Lejátszás folytatása?"
|
||||
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
msgstr "GTK verzió: %s"
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
msgstr "Adwaita verzió: %s"
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr "GStreamer verzió: %s"
|
||||
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr "GJS verzió: %s"
|
||||
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
msgstr "GNOME médialejátszó a GStreamer képességeivel"
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr "Ferenc Géczi"
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
msgstr "%s-kor ér véget"
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
msgstr "Meghatározatlan"
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
msgstr "Csatornák"
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
msgstr "Kikapcsolva"
|
||||
|
||||
|
39
po/it.po
39
po/it.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-10 19:43\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-10-04 08:30\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Italian\n"
|
||||
"Language: it_IT\n"
|
||||
@@ -18,12 +18,12 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgstr "Apri i File..."
|
||||
msgid "Open Files…"
|
||||
msgstr "Apri i File…"
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgstr "Apri URI..."
|
||||
msgid "Open URI…"
|
||||
msgstr "Apri URI…"
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
msgid "Preferences"
|
||||
@@ -399,56 +399,61 @@ msgstr "Cancella"
|
||||
msgid "Open"
|
||||
msgstr "Apri"
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr "Titolo"
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr "Completato"
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr "Riprendere la riproduzione?"
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr "Versione GTK: %s"
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr "Versione Adwaita: %s"
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr "Versione GStreamer: %s"
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr "Versione GJS: %s"
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr "Un riproduttore multimediale per GNOME basato su GStreamer"
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr "Termina alle: %s"
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr "Indeterminato"
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr "Canali"
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr "Disabilitato"
|
||||
|
||||
|
35
po/ja.po
35
po/ja.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:31\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-14 15:25\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Japanese\n"
|
||||
"Language: ja_JP\n"
|
||||
@@ -18,11 +18,11 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgid "Open Files…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgid "Open URI…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
@@ -399,56 +399,61 @@ msgstr ""
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
|
35
po/ko.po
35
po/ko.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:30\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-14 15:24\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Korean\n"
|
||||
"Language: ko_KR\n"
|
||||
@@ -18,11 +18,11 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgid "Open Files…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgid "Open URI…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
@@ -399,56 +399,61 @@ msgstr ""
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
|
35
po/nl.po
35
po/nl.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 19:35\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-14 16:21\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Dutch\n"
|
||||
"Language: nl_NL\n"
|
||||
@@ -18,11 +18,11 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgid "Open Files…"
|
||||
msgstr "Bestanden openen…"
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgid "Open URI…"
|
||||
msgstr "URI openen…"
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
@@ -399,56 +399,61 @@ msgstr ""
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr "Heimen Stoffels <vistausss@fastmail.com>"
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr "Eindigt op: %s"
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
|
35
po/no.po
35
po/no.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:31\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-14 15:25\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Norwegian\n"
|
||||
"Language: no_NO\n"
|
||||
@@ -18,11 +18,11 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgid "Open Files…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgid "Open URI…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
@@ -399,56 +399,61 @@ msgstr ""
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
|
39
po/pl.po
39
po/pl.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-08 09:12\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-15 08:41\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Polish\n"
|
||||
"Language: pl_PL\n"
|
||||
@@ -18,12 +18,12 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgstr "Otwórz pliki..."
|
||||
msgid "Open Files…"
|
||||
msgstr "Otwórz pliki…"
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgstr "Otwórz URI..."
|
||||
msgid "Open URI…"
|
||||
msgstr "Otwórz URI…"
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
msgid "Preferences"
|
||||
@@ -399,56 +399,61 @@ msgstr "Anuluj"
|
||||
msgid "Open"
|
||||
msgstr "Otwórz"
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr "Tytuł"
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr "Ukończono"
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr "Wznowić odtwarzanie?"
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr "Wersja GTK: %s"
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr "Wersja Adwaity: %s"
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr "Wersja GStreamera: %s"
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr "Wersja GJS: %s"
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr "Odtwarzacz multimedialny dla GNOME zasilany przez GStreamer"
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr "Rafał Dzięgiel <rafostar.github@gmail.com>"
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr "Koniec o: %s"
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr "Nieokreślony"
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr "Kanały"
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr "Wyłączony"
|
||||
|
||||
|
77
po/pt.po
77
po/pt.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:31\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-10-21 00:29\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Portuguese\n"
|
||||
"Language: pt_PT\n"
|
||||
@@ -18,89 +18,89 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgstr ""
|
||||
msgid "Open Files…"
|
||||
msgstr "Abrir Arquivos…"
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgstr ""
|
||||
msgid "Open URI…"
|
||||
msgstr "Abrir URI…"
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
msgid "Preferences"
|
||||
msgstr ""
|
||||
msgstr "Preferências"
|
||||
|
||||
#: ui/clapper.ui:20
|
||||
msgid "Shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Atalhos"
|
||||
|
||||
#: ui/clapper.ui:26
|
||||
msgid "About Clapper"
|
||||
msgstr ""
|
||||
msgstr "Sobre o Clapper"
|
||||
|
||||
#: ui/elapsed-time-button.ui:27
|
||||
msgid "Speed"
|
||||
msgstr ""
|
||||
msgstr "Velocidade"
|
||||
|
||||
#: ui/elapsed-time-button.ui:41 ui/preferences-window.ui:83
|
||||
#: ui/preferences-window.ui:215
|
||||
msgid "Normal"
|
||||
msgstr ""
|
||||
msgstr "Predefinido"
|
||||
|
||||
#: ui/help-overlay.ui:10 ui/preferences-window.ui:12
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
msgstr "Geral"
|
||||
|
||||
#: ui/help-overlay.ui:13
|
||||
msgid "Show shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Mostrar atalhos"
|
||||
|
||||
#: ui/help-overlay.ui:19
|
||||
msgid "Toggle fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Mudar modo de ecrã"
|
||||
|
||||
#: ui/help-overlay.ui:20
|
||||
msgid "Double tap | Double click"
|
||||
msgstr ""
|
||||
msgstr "Toque duplo duplo Clique duplo"
|
||||
|
||||
#: ui/help-overlay.ui:26
|
||||
msgid "Leave fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Sair do modo de ecrã completo"
|
||||
|
||||
#: ui/help-overlay.ui:32
|
||||
msgid "Reveal OSD (fullscreen only)"
|
||||
msgstr ""
|
||||
msgstr "Revelar OSD (apenas em tela cheia)"
|
||||
|
||||
#: ui/help-overlay.ui:33
|
||||
msgid "Tap"
|
||||
msgstr ""
|
||||
msgstr "Tocar"
|
||||
|
||||
#: ui/help-overlay.ui:39
|
||||
msgid "Quit"
|
||||
msgstr ""
|
||||
msgstr "Sair"
|
||||
|
||||
#: ui/help-overlay.ui:47
|
||||
msgid "Media"
|
||||
msgstr ""
|
||||
msgstr "Multimédia"
|
||||
|
||||
#: ui/help-overlay.ui:50
|
||||
msgid "Open files"
|
||||
msgstr ""
|
||||
msgstr "Abrir ficheiro"
|
||||
|
||||
#: ui/help-overlay.ui:56 src/dialogs.js:137
|
||||
msgid "Open URI"
|
||||
msgstr ""
|
||||
msgstr "Abrir URI"
|
||||
|
||||
#: ui/help-overlay.ui:64
|
||||
msgid "Playlist"
|
||||
msgstr ""
|
||||
msgstr "Lista de reprodução"
|
||||
|
||||
#: ui/help-overlay.ui:67
|
||||
msgid "Next item"
|
||||
msgstr ""
|
||||
msgstr "Próximo item"
|
||||
|
||||
#: ui/help-overlay.ui:68
|
||||
msgid "Double tap (right side)"
|
||||
msgstr ""
|
||||
msgstr "Toque duplo (lado direito)"
|
||||
|
||||
#: ui/help-overlay.ui:74
|
||||
msgid "Previous item"
|
||||
@@ -399,56 +399,61 @@ msgstr ""
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
|
267
po/pt_BR.po
267
po/pt_BR.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:31\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-10-11 10:33\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Portuguese, Brazilian\n"
|
||||
"Language: pt_BR\n"
|
||||
@@ -18,437 +18,442 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgstr ""
|
||||
msgid "Open Files…"
|
||||
msgstr "Abrir Arquivos"
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgstr ""
|
||||
msgid "Open URI…"
|
||||
msgstr "Abrir URI"
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
msgid "Preferences"
|
||||
msgstr ""
|
||||
msgstr "Preferências"
|
||||
|
||||
#: ui/clapper.ui:20
|
||||
msgid "Shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Atalhos"
|
||||
|
||||
#: ui/clapper.ui:26
|
||||
msgid "About Clapper"
|
||||
msgstr ""
|
||||
msgstr "Sobre o Clapper"
|
||||
|
||||
#: ui/elapsed-time-button.ui:27
|
||||
msgid "Speed"
|
||||
msgstr ""
|
||||
msgstr "Velocidade"
|
||||
|
||||
#: ui/elapsed-time-button.ui:41 ui/preferences-window.ui:83
|
||||
#: ui/preferences-window.ui:215
|
||||
msgid "Normal"
|
||||
msgstr ""
|
||||
msgstr "Normal"
|
||||
|
||||
#: ui/help-overlay.ui:10 ui/preferences-window.ui:12
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
msgstr "Geral"
|
||||
|
||||
#: ui/help-overlay.ui:13
|
||||
msgid "Show shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Mostrar atalhos"
|
||||
|
||||
#: ui/help-overlay.ui:19
|
||||
msgid "Toggle fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Tela Cheia"
|
||||
|
||||
#: ui/help-overlay.ui:20
|
||||
msgid "Double tap | Double click"
|
||||
msgstr ""
|
||||
msgstr "Toque duplo duplo Clique duplo"
|
||||
|
||||
#: ui/help-overlay.ui:26
|
||||
msgid "Leave fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Sair de tela cheia"
|
||||
|
||||
#: ui/help-overlay.ui:32
|
||||
msgid "Reveal OSD (fullscreen only)"
|
||||
msgstr ""
|
||||
msgstr "Revelar OSD (apenas em tela cheia)"
|
||||
|
||||
#: ui/help-overlay.ui:33
|
||||
msgid "Tap"
|
||||
msgstr ""
|
||||
msgstr "Tocar"
|
||||
|
||||
#: ui/help-overlay.ui:39
|
||||
msgid "Quit"
|
||||
msgstr ""
|
||||
msgstr "Sair"
|
||||
|
||||
#: ui/help-overlay.ui:47
|
||||
msgid "Media"
|
||||
msgstr ""
|
||||
msgstr "Mídia"
|
||||
|
||||
#: ui/help-overlay.ui:50
|
||||
msgid "Open files"
|
||||
msgstr ""
|
||||
msgstr "Abrir Arquivos"
|
||||
|
||||
#: ui/help-overlay.ui:56 src/dialogs.js:137
|
||||
msgid "Open URI"
|
||||
msgstr ""
|
||||
msgstr "Abrir o URL"
|
||||
|
||||
#: ui/help-overlay.ui:64
|
||||
msgid "Playlist"
|
||||
msgstr ""
|
||||
msgstr "Lista de reprodução"
|
||||
|
||||
#: ui/help-overlay.ui:67
|
||||
msgid "Next item"
|
||||
msgstr ""
|
||||
msgstr "Próximo"
|
||||
|
||||
#: ui/help-overlay.ui:68
|
||||
msgid "Double tap (right side)"
|
||||
msgstr ""
|
||||
msgstr "Toque duplo (lado direito)"
|
||||
|
||||
#: ui/help-overlay.ui:74
|
||||
msgid "Previous item"
|
||||
msgstr ""
|
||||
msgstr "Anterior"
|
||||
|
||||
#: ui/help-overlay.ui:75
|
||||
msgid "Double tap (left side)"
|
||||
msgstr ""
|
||||
msgstr "Toque duplo (lado esquerdo)"
|
||||
|
||||
#: ui/help-overlay.ui:81
|
||||
msgid "Change repeat mode"
|
||||
msgstr ""
|
||||
msgstr "Alternar modo de repetição"
|
||||
|
||||
#: ui/help-overlay.ui:87
|
||||
msgid "Export to file"
|
||||
msgstr ""
|
||||
msgstr "Exportar arquivo"
|
||||
|
||||
#: ui/help-overlay.ui:95 ui/preferences-window.ui:119
|
||||
msgid "Playback"
|
||||
msgstr ""
|
||||
msgstr "Reprodução"
|
||||
|
||||
#: ui/help-overlay.ui:98
|
||||
msgid "Toggle play"
|
||||
msgstr ""
|
||||
msgstr "Alternar video"
|
||||
|
||||
#: ui/help-overlay.ui:99
|
||||
msgid "Long press | Right click"
|
||||
msgstr ""
|
||||
msgstr "Toque longo (Clique com o botão direito)"
|
||||
|
||||
#: ui/help-overlay.ui:105
|
||||
msgid "Seek forward"
|
||||
msgstr ""
|
||||
msgstr "Avançar para frente"
|
||||
|
||||
#: ui/help-overlay.ui:106
|
||||
msgid "Swipe right | Scroll right"
|
||||
msgstr ""
|
||||
msgstr "Deslizar para a Direita Scroll para Direita"
|
||||
|
||||
#: ui/help-overlay.ui:112
|
||||
msgid "Seek backward"
|
||||
msgstr ""
|
||||
msgstr "Volta video"
|
||||
|
||||
#: ui/help-overlay.ui:113
|
||||
msgid "Swipe left | Scroll left"
|
||||
msgstr ""
|
||||
msgstr "Deslizar para a esquerda Scroll para a Esquerda"
|
||||
|
||||
#: ui/help-overlay.ui:119
|
||||
msgid "Volume up"
|
||||
msgstr ""
|
||||
msgstr "Aumentar o volume"
|
||||
|
||||
#: ui/help-overlay.ui:120
|
||||
msgid "Swipe up | Scroll up"
|
||||
msgstr ""
|
||||
msgstr "Deslizar para cima Scroll para cima"
|
||||
|
||||
#: ui/help-overlay.ui:126
|
||||
msgid "Volume down"
|
||||
msgstr ""
|
||||
msgstr "Diminuir o volume"
|
||||
|
||||
#: ui/help-overlay.ui:127
|
||||
msgid "Swipe down | Scroll down"
|
||||
msgstr ""
|
||||
msgstr "Deslizar para baixo ► Rolar para baixo"
|
||||
|
||||
#: ui/help-overlay.ui:133
|
||||
msgid "Toggle mute"
|
||||
msgstr ""
|
||||
msgstr "Ativar/Desativar Som"
|
||||
|
||||
#: ui/help-overlay.ui:139
|
||||
msgid "Next chapter"
|
||||
msgstr ""
|
||||
msgstr "Próximo Capítulo"
|
||||
|
||||
#: ui/help-overlay.ui:145
|
||||
msgid "Previous chapter"
|
||||
msgstr ""
|
||||
msgstr "Capítulo Anterior"
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:11
|
||||
msgid "Decoders"
|
||||
msgstr ""
|
||||
msgstr "Decodificadores"
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:18
|
||||
msgid "Return to the preferences"
|
||||
msgstr ""
|
||||
msgstr "Voltar para as preferências"
|
||||
|
||||
#: ui/preferences-window.ui:16
|
||||
msgid "Behavior"
|
||||
msgstr ""
|
||||
msgstr "Comportamento"
|
||||
|
||||
#: ui/preferences-window.ui:19
|
||||
msgid "Auto fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Tela cheia automaticamente"
|
||||
|
||||
#: ui/preferences-window.ui:20
|
||||
msgid "Enter fullscreen when playlist is replaced except floating mode"
|
||||
msgstr ""
|
||||
msgstr "Insira em tela cheia quando a lista de reprodução for substituída, exceto o modo flutuante"
|
||||
|
||||
#: ui/preferences-window.ui:26
|
||||
msgid "Ask to resume recent media"
|
||||
msgstr ""
|
||||
msgstr "Pedir para retomar o video recente"
|
||||
|
||||
#: ui/preferences-window.ui:32
|
||||
msgid "Float on all workspaces"
|
||||
msgstr ""
|
||||
msgstr "Flutuar em todas as áreas de trabalho"
|
||||
|
||||
#: ui/preferences-window.ui:33
|
||||
msgid "This option only works on GNOME"
|
||||
msgstr ""
|
||||
msgstr "Esta opção só funciona no GNOME"
|
||||
|
||||
#: ui/preferences-window.ui:39
|
||||
msgid "After playback"
|
||||
msgstr ""
|
||||
msgstr "Pós reprodução"
|
||||
|
||||
#: ui/preferences-window.ui:44
|
||||
msgid "Do nothing"
|
||||
msgstr ""
|
||||
msgstr "Não fazer nada"
|
||||
|
||||
#: ui/preferences-window.ui:45
|
||||
msgid "Freeze last frame"
|
||||
msgstr ""
|
||||
msgstr "Congelar o último quadro"
|
||||
|
||||
#: ui/preferences-window.ui:46
|
||||
msgid "Close the app"
|
||||
msgstr ""
|
||||
msgstr "Fechar aplicativo"
|
||||
|
||||
#: ui/preferences-window.ui:56
|
||||
msgid "Volume"
|
||||
msgstr ""
|
||||
msgstr "Volume"
|
||||
|
||||
#: ui/preferences-window.ui:59
|
||||
msgid "Custom initial value"
|
||||
msgstr ""
|
||||
msgstr "Valor inicial personalizado"
|
||||
|
||||
#: ui/preferences-window.ui:60
|
||||
msgid "Set custom volume at startup instead of restoring it"
|
||||
msgstr ""
|
||||
msgstr "Definir volume personalizado na inicialização ao invés de restaurá-lo"
|
||||
|
||||
#: ui/preferences-window.ui:64
|
||||
msgid "Volume percentage"
|
||||
msgstr ""
|
||||
msgstr "Percentual do volume"
|
||||
|
||||
#: ui/preferences-window.ui:75
|
||||
msgid "Seeking"
|
||||
msgstr ""
|
||||
msgstr "Buscando"
|
||||
|
||||
#: ui/preferences-window.ui:78
|
||||
msgid "Mode"
|
||||
msgstr ""
|
||||
msgstr "Modo"
|
||||
|
||||
#: ui/preferences-window.ui:84
|
||||
msgid "Accurate"
|
||||
msgstr ""
|
||||
msgstr "Preciso"
|
||||
|
||||
#: ui/preferences-window.ui:85
|
||||
msgid "Fast"
|
||||
msgstr ""
|
||||
msgstr "Rápido"
|
||||
|
||||
#: ui/preferences-window.ui:93
|
||||
msgid "Unit"
|
||||
msgstr ""
|
||||
msgstr "Unidade"
|
||||
|
||||
#: ui/preferences-window.ui:98
|
||||
msgid "Second"
|
||||
msgstr ""
|
||||
msgstr "Segundo"
|
||||
|
||||
#: ui/preferences-window.ui:99
|
||||
msgid "Minute"
|
||||
msgstr ""
|
||||
msgstr "Minuto"
|
||||
|
||||
#: ui/preferences-window.ui:100
|
||||
msgid "Percentage"
|
||||
msgstr ""
|
||||
msgstr "Porcentagem"
|
||||
|
||||
#: ui/preferences-window.ui:108
|
||||
msgid "Value"
|
||||
msgstr ""
|
||||
msgstr "Valor"
|
||||
|
||||
#: ui/preferences-window.ui:123
|
||||
msgid "Audio"
|
||||
msgstr ""
|
||||
msgstr "Audio"
|
||||
|
||||
#: ui/preferences-window.ui:126
|
||||
msgid "Offset in milliseconds"
|
||||
msgstr ""
|
||||
msgstr "tempo de desvanecimento em milissegundos"
|
||||
|
||||
#: ui/preferences-window.ui:133
|
||||
msgid "Only native audio formats"
|
||||
msgstr ""
|
||||
msgstr "Apenas formatos de áudio nativos"
|
||||
|
||||
#: ui/preferences-window.ui:141
|
||||
msgid "Subtitles"
|
||||
msgstr ""
|
||||
msgstr "Legendas"
|
||||
|
||||
#: ui/preferences-window.ui:144
|
||||
msgid "Default font"
|
||||
msgstr ""
|
||||
msgstr "Fonte padrão"
|
||||
|
||||
#: ui/preferences-window.ui:154
|
||||
msgid "Network"
|
||||
msgstr ""
|
||||
msgstr "Rede"
|
||||
|
||||
#: ui/preferences-window.ui:158
|
||||
msgid "Client"
|
||||
msgstr ""
|
||||
msgstr "Cliente"
|
||||
|
||||
#: ui/preferences-window.ui:161
|
||||
msgid "Progressive download buffering"
|
||||
msgstr ""
|
||||
msgstr "buffering progressivo de download"
|
||||
|
||||
#: ui/preferences-window.ui:169
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
msgstr "Servidor"
|
||||
|
||||
#: ui/preferences-window.ui:172
|
||||
msgid "Control player remotely"
|
||||
msgstr ""
|
||||
msgstr "Controle o video remotamente "
|
||||
|
||||
#: ui/preferences-window.ui:176
|
||||
msgid "Listening port"
|
||||
msgstr ""
|
||||
msgstr "Porta de escuta"
|
||||
|
||||
#: ui/preferences-window.ui:183
|
||||
msgid "Run web application in background"
|
||||
msgstr ""
|
||||
msgstr "Executar web app em segundo plano"
|
||||
|
||||
#: ui/preferences-window.ui:184
|
||||
msgid "Requires GTK compiled with Broadway backend"
|
||||
msgstr ""
|
||||
msgstr "Requer GTK compilado com backend de Broadway"
|
||||
|
||||
#: ui/preferences-window.ui:190
|
||||
msgid "Web application port"
|
||||
msgstr ""
|
||||
msgstr "Porta do aplicativo Web"
|
||||
|
||||
#: ui/preferences-window.ui:204
|
||||
msgid "Prefer adaptive streaming"
|
||||
msgstr ""
|
||||
msgstr "Preferir streaming adaptável"
|
||||
|
||||
#: ui/preferences-window.ui:210
|
||||
msgid "Max quality"
|
||||
msgstr ""
|
||||
msgstr "Qualidade Máxima"
|
||||
|
||||
#: ui/preferences-window.ui:228
|
||||
msgid "Tweaks"
|
||||
msgstr ""
|
||||
msgstr "Ajustes"
|
||||
|
||||
#: ui/preferences-window.ui:232
|
||||
msgid "Appearance"
|
||||
msgstr ""
|
||||
msgstr "Aparência"
|
||||
|
||||
#: ui/preferences-window.ui:235
|
||||
msgid "Dark theme"
|
||||
msgstr ""
|
||||
msgstr "Tema Escuro"
|
||||
|
||||
#: ui/preferences-window.ui:241
|
||||
msgid "Render window shadows"
|
||||
msgstr ""
|
||||
msgstr "Renderizar sombras das janelas"
|
||||
|
||||
#: ui/preferences-window.ui:242
|
||||
msgid "Disable to increase performance when windowed"
|
||||
msgstr ""
|
||||
msgstr "Desabilite para aumentar o desempenho em placas gráficas mais fracas."
|
||||
|
||||
#: ui/preferences-window.ui:253
|
||||
msgid "Plugin ranking"
|
||||
msgstr ""
|
||||
msgstr "Classificação do plugin"
|
||||
|
||||
#: ui/preferences-window.ui:254
|
||||
msgid "Alter default ranks of GStreamer plugins"
|
||||
msgstr ""
|
||||
msgstr "Altera os ranks padrão dos plugins do GStreamer"
|
||||
|
||||
#: ui/preferences-window.ui:259
|
||||
msgid "Use playbin3"
|
||||
msgstr ""
|
||||
msgstr "Usar playbin3"
|
||||
|
||||
#: ui/preferences-window.ui:260 ui/preferences-window.ui:269
|
||||
msgid "Requires player restart"
|
||||
msgstr ""
|
||||
msgstr "Requer reinicialização do Clapper"
|
||||
|
||||
#: ui/preferences-window.ui:262 ui/preferences-window.ui:271
|
||||
msgid "Experimental"
|
||||
msgstr ""
|
||||
msgstr "Experimental"
|
||||
|
||||
#: ui/preferences-window.ui:268
|
||||
msgid "Use PipeWire for audio output"
|
||||
msgstr ""
|
||||
msgstr "Usar PipeWire para saída de áudio"
|
||||
|
||||
#: src/buttons.js:201
|
||||
#, javascript-format
|
||||
msgid "Decoder: %s"
|
||||
msgstr ""
|
||||
msgstr "Decodificador: %s"
|
||||
|
||||
#: src/dialogs.js:152
|
||||
msgid "Enter or drop URI here"
|
||||
msgstr ""
|
||||
msgstr "Digite ou solte o URI aqui"
|
||||
|
||||
#: src/dialogs.js:157
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "Cancelar"
|
||||
|
||||
#: src/dialogs.js:158
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
msgstr "Abrir"
|
||||
|
||||
#: src/dialogs.js:226
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
msgid "Title"
|
||||
msgstr "Título"
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr "Completado"
|
||||
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr "Retomar a reprodução?"
|
||||
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
msgstr "Versão do GTK: %s"
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
msgstr "Adwaita versão:"
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr "Versão do GStreamer: %s"
|
||||
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr "Versão do GJS: %s"
|
||||
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
msgstr "Um player de mídia GNOME desenvolvido por GStreamer"
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr "KevenDoriaLinuxBR"
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
msgstr "termina em %s"
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
msgstr "Indeterminado"
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
msgstr "Canais"
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
msgstr "Desabilitado"
|
||||
|
||||
|
35
po/ro.po
35
po/ro.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:30\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-14 15:24\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Romanian\n"
|
||||
"Language: ro_RO\n"
|
||||
@@ -18,11 +18,11 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgid "Open Files…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgid "Open URI…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
@@ -399,56 +399,61 @@ msgstr ""
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
|
267
po/ru.po
267
po/ru.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:31\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2022-01-16 14:15\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Russian\n"
|
||||
"Language: ru_RU\n"
|
||||
@@ -18,437 +18,442 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgstr ""
|
||||
msgid "Open Files…"
|
||||
msgstr "Открыть файлы…"
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgstr ""
|
||||
msgid "Open URI…"
|
||||
msgstr "Открыть URI…"
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
msgid "Preferences"
|
||||
msgstr ""
|
||||
msgstr "Параметры"
|
||||
|
||||
#: ui/clapper.ui:20
|
||||
msgid "Shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Комбинации клавиш"
|
||||
|
||||
#: ui/clapper.ui:26
|
||||
msgid "About Clapper"
|
||||
msgstr ""
|
||||
msgstr "О приложении"
|
||||
|
||||
#: ui/elapsed-time-button.ui:27
|
||||
msgid "Speed"
|
||||
msgstr ""
|
||||
msgstr "Скорость"
|
||||
|
||||
#: ui/elapsed-time-button.ui:41 ui/preferences-window.ui:83
|
||||
#: ui/preferences-window.ui:215
|
||||
msgid "Normal"
|
||||
msgstr ""
|
||||
msgstr "Обычная"
|
||||
|
||||
#: ui/help-overlay.ui:10 ui/preferences-window.ui:12
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
msgstr "Общие"
|
||||
|
||||
#: ui/help-overlay.ui:13
|
||||
msgid "Show shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Комбинации клавиш"
|
||||
|
||||
#: ui/help-overlay.ui:19
|
||||
msgid "Toggle fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Включить полноэкранный режим"
|
||||
|
||||
#: ui/help-overlay.ui:20
|
||||
msgid "Double tap | Double click"
|
||||
msgstr ""
|
||||
msgstr "Двойное нажатие | Двойной клик"
|
||||
|
||||
#: ui/help-overlay.ui:26
|
||||
msgid "Leave fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Выйти из полноэкранного режима"
|
||||
|
||||
#: ui/help-overlay.ui:32
|
||||
msgid "Reveal OSD (fullscreen only)"
|
||||
msgstr ""
|
||||
msgstr "Показывать OSD (только в полноэкранном режиме)"
|
||||
|
||||
#: ui/help-overlay.ui:33
|
||||
msgid "Tap"
|
||||
msgstr ""
|
||||
msgstr "Нажатие"
|
||||
|
||||
#: ui/help-overlay.ui:39
|
||||
msgid "Quit"
|
||||
msgstr ""
|
||||
msgstr "Выйти из приложения"
|
||||
|
||||
#: ui/help-overlay.ui:47
|
||||
msgid "Media"
|
||||
msgstr ""
|
||||
msgstr "Медиа"
|
||||
|
||||
#: ui/help-overlay.ui:50
|
||||
msgid "Open files"
|
||||
msgstr ""
|
||||
msgstr "Открыть файлы"
|
||||
|
||||
#: ui/help-overlay.ui:56 src/dialogs.js:137
|
||||
msgid "Open URI"
|
||||
msgstr ""
|
||||
msgstr "Открыть URI"
|
||||
|
||||
#: ui/help-overlay.ui:64
|
||||
msgid "Playlist"
|
||||
msgstr ""
|
||||
msgstr "Плейлист"
|
||||
|
||||
#: ui/help-overlay.ui:67
|
||||
msgid "Next item"
|
||||
msgstr ""
|
||||
msgstr "Следующий элемент"
|
||||
|
||||
#: ui/help-overlay.ui:68
|
||||
msgid "Double tap (right side)"
|
||||
msgstr ""
|
||||
msgstr "Двойное нажатие (правая сторона)"
|
||||
|
||||
#: ui/help-overlay.ui:74
|
||||
msgid "Previous item"
|
||||
msgstr ""
|
||||
msgstr "Предыдущий элемент"
|
||||
|
||||
#: ui/help-overlay.ui:75
|
||||
msgid "Double tap (left side)"
|
||||
msgstr ""
|
||||
msgstr "Двойное нажатие (левая сторона)"
|
||||
|
||||
#: ui/help-overlay.ui:81
|
||||
msgid "Change repeat mode"
|
||||
msgstr ""
|
||||
msgstr "Изменить режим повторения"
|
||||
|
||||
#: ui/help-overlay.ui:87
|
||||
msgid "Export to file"
|
||||
msgstr ""
|
||||
msgstr "Экспорт в файл"
|
||||
|
||||
#: ui/help-overlay.ui:95 ui/preferences-window.ui:119
|
||||
msgid "Playback"
|
||||
msgstr ""
|
||||
msgstr "Воспроизведение"
|
||||
|
||||
#: ui/help-overlay.ui:98
|
||||
msgid "Toggle play"
|
||||
msgstr ""
|
||||
msgstr "Управление воспроизведением"
|
||||
|
||||
#: ui/help-overlay.ui:99
|
||||
msgid "Long press | Right click"
|
||||
msgstr ""
|
||||
msgstr "Длительное нажатие | Щелкните правой кнопкой мыши"
|
||||
|
||||
#: ui/help-overlay.ui:105
|
||||
msgid "Seek forward"
|
||||
msgstr ""
|
||||
msgstr "Перемотка вперед"
|
||||
|
||||
#: ui/help-overlay.ui:106
|
||||
msgid "Swipe right | Scroll right"
|
||||
msgstr ""
|
||||
msgstr "Проведите вправо | Прокрутите вправо"
|
||||
|
||||
#: ui/help-overlay.ui:112
|
||||
msgid "Seek backward"
|
||||
msgstr ""
|
||||
msgstr "Перемотка назад"
|
||||
|
||||
#: ui/help-overlay.ui:113
|
||||
msgid "Swipe left | Scroll left"
|
||||
msgstr ""
|
||||
msgstr "Проведите влево | Прокрутите влево"
|
||||
|
||||
#: ui/help-overlay.ui:119
|
||||
msgid "Volume up"
|
||||
msgstr ""
|
||||
msgstr "Увеличить громкость"
|
||||
|
||||
#: ui/help-overlay.ui:120
|
||||
msgid "Swipe up | Scroll up"
|
||||
msgstr ""
|
||||
msgstr "Проведите вверх | Прокрутите вверх"
|
||||
|
||||
#: ui/help-overlay.ui:126
|
||||
msgid "Volume down"
|
||||
msgstr ""
|
||||
msgstr "Уменьшить громкость"
|
||||
|
||||
#: ui/help-overlay.ui:127
|
||||
msgid "Swipe down | Scroll down"
|
||||
msgstr ""
|
||||
msgstr "Проведите вниз | Прокрутить вниз"
|
||||
|
||||
#: ui/help-overlay.ui:133
|
||||
msgid "Toggle mute"
|
||||
msgstr ""
|
||||
msgstr "Отключить звук"
|
||||
|
||||
#: ui/help-overlay.ui:139
|
||||
msgid "Next chapter"
|
||||
msgstr ""
|
||||
msgstr "Следующая глава"
|
||||
|
||||
#: ui/help-overlay.ui:145
|
||||
msgid "Previous chapter"
|
||||
msgstr ""
|
||||
msgstr "Предыдущая глава"
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:11
|
||||
msgid "Decoders"
|
||||
msgstr ""
|
||||
msgstr "Декодеры"
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:18
|
||||
msgid "Return to the preferences"
|
||||
msgstr ""
|
||||
msgstr "Вернуться к настройкам"
|
||||
|
||||
#: ui/preferences-window.ui:16
|
||||
msgid "Behavior"
|
||||
msgstr ""
|
||||
msgstr "Поведение"
|
||||
|
||||
#: ui/preferences-window.ui:19
|
||||
msgid "Auto fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Автоматический полноэкранный режим"
|
||||
|
||||
#: ui/preferences-window.ui:20
|
||||
msgid "Enter fullscreen when playlist is replaced except floating mode"
|
||||
msgstr ""
|
||||
msgstr "Переход в полноэкранный режим при замене списка воспроизведения, кроме плавающего режима"
|
||||
|
||||
#: ui/preferences-window.ui:26
|
||||
msgid "Ask to resume recent media"
|
||||
msgstr ""
|
||||
msgstr "Спрашивать о возобновление недавние медиа"
|
||||
|
||||
#: ui/preferences-window.ui:32
|
||||
msgid "Float on all workspaces"
|
||||
msgstr ""
|
||||
msgstr "Показывать «плавающий режим» на всех рабочих столах"
|
||||
|
||||
#: ui/preferences-window.ui:33
|
||||
msgid "This option only works on GNOME"
|
||||
msgstr ""
|
||||
msgstr "Эта опция работает только в GNOME"
|
||||
|
||||
#: ui/preferences-window.ui:39
|
||||
msgid "After playback"
|
||||
msgstr ""
|
||||
msgstr "После воспроизведения"
|
||||
|
||||
#: ui/preferences-window.ui:44
|
||||
msgid "Do nothing"
|
||||
msgstr ""
|
||||
msgstr "Ничего не делать"
|
||||
|
||||
#: ui/preferences-window.ui:45
|
||||
msgid "Freeze last frame"
|
||||
msgstr ""
|
||||
msgstr "Заморозить последний кадр"
|
||||
|
||||
#: ui/preferences-window.ui:46
|
||||
msgid "Close the app"
|
||||
msgstr ""
|
||||
msgstr "Закрыть приложение"
|
||||
|
||||
#: ui/preferences-window.ui:56
|
||||
msgid "Volume"
|
||||
msgstr ""
|
||||
msgstr "Громкость"
|
||||
|
||||
#: ui/preferences-window.ui:59
|
||||
msgid "Custom initial value"
|
||||
msgstr ""
|
||||
msgstr "Пользовательское начальное значение"
|
||||
|
||||
#: ui/preferences-window.ui:60
|
||||
msgid "Set custom volume at startup instead of restoring it"
|
||||
msgstr ""
|
||||
msgstr "Установите настраиваемую громкость при запуске вместо ее восстановления"
|
||||
|
||||
#: ui/preferences-window.ui:64
|
||||
msgid "Volume percentage"
|
||||
msgstr ""
|
||||
msgstr "Процент громкости"
|
||||
|
||||
#: ui/preferences-window.ui:75
|
||||
msgid "Seeking"
|
||||
msgstr ""
|
||||
msgstr "Перемотка"
|
||||
|
||||
#: ui/preferences-window.ui:78
|
||||
msgid "Mode"
|
||||
msgstr ""
|
||||
msgstr "Режим"
|
||||
|
||||
#: ui/preferences-window.ui:84
|
||||
msgid "Accurate"
|
||||
msgstr ""
|
||||
msgstr "Точный"
|
||||
|
||||
#: ui/preferences-window.ui:85
|
||||
msgid "Fast"
|
||||
msgstr ""
|
||||
msgstr "Быстрый"
|
||||
|
||||
#: ui/preferences-window.ui:93
|
||||
msgid "Unit"
|
||||
msgstr ""
|
||||
msgstr "Ед. изм"
|
||||
|
||||
#: ui/preferences-window.ui:98
|
||||
msgid "Second"
|
||||
msgstr ""
|
||||
msgstr "Секунды"
|
||||
|
||||
#: ui/preferences-window.ui:99
|
||||
msgid "Minute"
|
||||
msgstr ""
|
||||
msgstr "Минуты"
|
||||
|
||||
#: ui/preferences-window.ui:100
|
||||
msgid "Percentage"
|
||||
msgstr ""
|
||||
msgstr "Проценты"
|
||||
|
||||
#: ui/preferences-window.ui:108
|
||||
msgid "Value"
|
||||
msgstr ""
|
||||
msgstr "Значение"
|
||||
|
||||
#: ui/preferences-window.ui:123
|
||||
msgid "Audio"
|
||||
msgstr ""
|
||||
msgstr "Аудио"
|
||||
|
||||
#: ui/preferences-window.ui:126
|
||||
msgid "Offset in milliseconds"
|
||||
msgstr ""
|
||||
msgstr "Смещение в миллисекундах"
|
||||
|
||||
#: ui/preferences-window.ui:133
|
||||
msgid "Only native audio formats"
|
||||
msgstr ""
|
||||
msgstr "Только нативные аудиоформаты"
|
||||
|
||||
#: ui/preferences-window.ui:141
|
||||
msgid "Subtitles"
|
||||
msgstr ""
|
||||
msgstr "Субтитры"
|
||||
|
||||
#: ui/preferences-window.ui:144
|
||||
msgid "Default font"
|
||||
msgstr ""
|
||||
msgstr "Шрифт по умолчанию"
|
||||
|
||||
#: ui/preferences-window.ui:154
|
||||
msgid "Network"
|
||||
msgstr ""
|
||||
msgstr "Сеть"
|
||||
|
||||
#: ui/preferences-window.ui:158
|
||||
msgid "Client"
|
||||
msgstr ""
|
||||
msgstr "Клиент"
|
||||
|
||||
#: ui/preferences-window.ui:161
|
||||
msgid "Progressive download buffering"
|
||||
msgstr ""
|
||||
msgstr "Прогрессивная буферизация загрузки"
|
||||
|
||||
#: ui/preferences-window.ui:169
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
msgstr "Сервер"
|
||||
|
||||
#: ui/preferences-window.ui:172
|
||||
msgid "Control player remotely"
|
||||
msgstr ""
|
||||
msgstr "Удаленное управление плеером"
|
||||
|
||||
#: ui/preferences-window.ui:176
|
||||
msgid "Listening port"
|
||||
msgstr ""
|
||||
msgstr "Порт прослушивания"
|
||||
|
||||
#: ui/preferences-window.ui:183
|
||||
msgid "Run web application in background"
|
||||
msgstr ""
|
||||
msgstr "Запустить веб-приложение в фоновом режиме"
|
||||
|
||||
#: ui/preferences-window.ui:184
|
||||
msgid "Requires GTK compiled with Broadway backend"
|
||||
msgstr ""
|
||||
msgstr "Требуется GTK, скомпилированный с бэкэндом Broadway"
|
||||
|
||||
#: ui/preferences-window.ui:190
|
||||
msgid "Web application port"
|
||||
msgstr ""
|
||||
msgstr "Порт веб-приложения"
|
||||
|
||||
#: ui/preferences-window.ui:204
|
||||
msgid "Prefer adaptive streaming"
|
||||
msgstr ""
|
||||
msgstr "Предпочитайте адаптивную потоковую передачу"
|
||||
|
||||
#: ui/preferences-window.ui:210
|
||||
msgid "Max quality"
|
||||
msgstr ""
|
||||
msgstr "Максимальное качество"
|
||||
|
||||
#: ui/preferences-window.ui:228
|
||||
msgid "Tweaks"
|
||||
msgstr ""
|
||||
msgstr "Твики"
|
||||
|
||||
#: ui/preferences-window.ui:232
|
||||
msgid "Appearance"
|
||||
msgstr ""
|
||||
msgstr "Внешний вид"
|
||||
|
||||
#: ui/preferences-window.ui:235
|
||||
msgid "Dark theme"
|
||||
msgstr ""
|
||||
msgstr "Тёмная тема"
|
||||
|
||||
#: ui/preferences-window.ui:241
|
||||
msgid "Render window shadows"
|
||||
msgstr ""
|
||||
msgstr "Рендеринг оконных теней"
|
||||
|
||||
#: ui/preferences-window.ui:242
|
||||
msgid "Disable to increase performance when windowed"
|
||||
msgstr ""
|
||||
msgstr "Отключить, чтобы повысить производительность в оконном режиме"
|
||||
|
||||
#: ui/preferences-window.ui:253
|
||||
msgid "Plugin ranking"
|
||||
msgstr ""
|
||||
msgstr "Рейтинг плагинов"
|
||||
|
||||
#: ui/preferences-window.ui:254
|
||||
msgid "Alter default ranks of GStreamer plugins"
|
||||
msgstr ""
|
||||
msgstr "Изменить ранги плагинов GStreamer по умолчанию"
|
||||
|
||||
#: ui/preferences-window.ui:259
|
||||
msgid "Use playbin3"
|
||||
msgstr ""
|
||||
msgstr "Использовать playbin3"
|
||||
|
||||
#: ui/preferences-window.ui:260 ui/preferences-window.ui:269
|
||||
msgid "Requires player restart"
|
||||
msgstr ""
|
||||
msgstr "Требуется перезапуск плеера"
|
||||
|
||||
#: ui/preferences-window.ui:262 ui/preferences-window.ui:271
|
||||
msgid "Experimental"
|
||||
msgstr ""
|
||||
msgstr "Экспериментально"
|
||||
|
||||
#: ui/preferences-window.ui:268
|
||||
msgid "Use PipeWire for audio output"
|
||||
msgstr ""
|
||||
msgstr "Использовать PipeWire для вывода звука"
|
||||
|
||||
#: src/buttons.js:201
|
||||
#, javascript-format
|
||||
msgid "Decoder: %s"
|
||||
msgstr ""
|
||||
msgstr "Декодер: %s"
|
||||
|
||||
#: src/dialogs.js:152
|
||||
msgid "Enter or drop URI here"
|
||||
msgstr ""
|
||||
msgstr "Введите URI"
|
||||
|
||||
#: src/dialogs.js:157
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "Отмена"
|
||||
|
||||
#: src/dialogs.js:158
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
msgstr "Открыть"
|
||||
|
||||
#: src/dialogs.js:226
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
msgid "Title"
|
||||
msgstr "Заголовок"
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr "Завершенный"
|
||||
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr "Возобновить воспроизведение?"
|
||||
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
msgstr "Версия GTK: %s"
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
msgstr "Версия Adwaita: %s"
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr "Версия GStreamer: %s"
|
||||
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr "Версия GJS: %s"
|
||||
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
msgstr "Медиаплеер для GNOME на базе GStreamer"
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr "Игорь Дятлов"
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
msgstr "Окончание: %s"
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
msgstr "Неопределенный"
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
msgstr "Каналы"
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
msgstr "Отключено"
|
||||
|
||||
|
35
po/sr.po
35
po/sr.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:31\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-14 15:25\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Serbian (Cyrillic)\n"
|
||||
"Language: sr_SP\n"
|
||||
@@ -18,11 +18,11 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgid "Open Files…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgid "Open URI…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
@@ -399,56 +399,61 @@ msgstr ""
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
|
267
po/sv.po
267
po/sv.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:31\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2022-01-16 14:15\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Swedish\n"
|
||||
"Language: sv_SE\n"
|
||||
@@ -18,437 +18,442 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgstr ""
|
||||
msgid "Open Files…"
|
||||
msgstr "Öppna filer…"
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgstr ""
|
||||
msgid "Open URI…"
|
||||
msgstr "Öppna URL…"
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
msgid "Preferences"
|
||||
msgstr ""
|
||||
msgstr "Inställningar"
|
||||
|
||||
#: ui/clapper.ui:20
|
||||
msgid "Shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Tangentbordsgenvägar"
|
||||
|
||||
#: ui/clapper.ui:26
|
||||
msgid "About Clapper"
|
||||
msgstr ""
|
||||
msgstr "Om Clapper"
|
||||
|
||||
#: ui/elapsed-time-button.ui:27
|
||||
msgid "Speed"
|
||||
msgstr ""
|
||||
msgstr "Hastighet"
|
||||
|
||||
#: ui/elapsed-time-button.ui:41 ui/preferences-window.ui:83
|
||||
#: ui/preferences-window.ui:215
|
||||
msgid "Normal"
|
||||
msgstr ""
|
||||
msgstr "Normal"
|
||||
|
||||
#: ui/help-overlay.ui:10 ui/preferences-window.ui:12
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
msgstr "Allmänt"
|
||||
|
||||
#: ui/help-overlay.ui:13
|
||||
msgid "Show shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Visa tangentbordsgenvägar"
|
||||
|
||||
#: ui/help-overlay.ui:19
|
||||
msgid "Toggle fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Växla helskärmsläge"
|
||||
|
||||
#: ui/help-overlay.ui:20
|
||||
msgid "Double tap | Double click"
|
||||
msgstr ""
|
||||
msgstr "Dubbeltryck | Dubbelklicka"
|
||||
|
||||
#: ui/help-overlay.ui:26
|
||||
msgid "Leave fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Lämna helskärmsläge"
|
||||
|
||||
#: ui/help-overlay.ui:32
|
||||
msgid "Reveal OSD (fullscreen only)"
|
||||
msgstr ""
|
||||
msgstr "Visa OSD (endast helskärmsläge)"
|
||||
|
||||
#: ui/help-overlay.ui:33
|
||||
msgid "Tap"
|
||||
msgstr ""
|
||||
msgstr "Tryck"
|
||||
|
||||
#: ui/help-overlay.ui:39
|
||||
msgid "Quit"
|
||||
msgstr ""
|
||||
msgstr "Avsluta"
|
||||
|
||||
#: ui/help-overlay.ui:47
|
||||
msgid "Media"
|
||||
msgstr ""
|
||||
msgstr "Media"
|
||||
|
||||
#: ui/help-overlay.ui:50
|
||||
msgid "Open files"
|
||||
msgstr ""
|
||||
msgstr "Öppna filer"
|
||||
|
||||
#: ui/help-overlay.ui:56 src/dialogs.js:137
|
||||
msgid "Open URI"
|
||||
msgstr ""
|
||||
msgstr "Öppna URI"
|
||||
|
||||
#: ui/help-overlay.ui:64
|
||||
msgid "Playlist"
|
||||
msgstr ""
|
||||
msgstr "Spellista"
|
||||
|
||||
#: ui/help-overlay.ui:67
|
||||
msgid "Next item"
|
||||
msgstr ""
|
||||
msgstr "Nästa föremål"
|
||||
|
||||
#: ui/help-overlay.ui:68
|
||||
msgid "Double tap (right side)"
|
||||
msgstr ""
|
||||
msgstr "Dubbeltryck (höger sida)"
|
||||
|
||||
#: ui/help-overlay.ui:74
|
||||
msgid "Previous item"
|
||||
msgstr ""
|
||||
msgstr "Föregående föremål"
|
||||
|
||||
#: ui/help-overlay.ui:75
|
||||
msgid "Double tap (left side)"
|
||||
msgstr ""
|
||||
msgstr "Dubbeltryck (vänster sida)"
|
||||
|
||||
#: ui/help-overlay.ui:81
|
||||
msgid "Change repeat mode"
|
||||
msgstr ""
|
||||
msgstr "Ändra upprepningsläge"
|
||||
|
||||
#: ui/help-overlay.ui:87
|
||||
msgid "Export to file"
|
||||
msgstr ""
|
||||
msgstr "Exportera till fil"
|
||||
|
||||
#: ui/help-overlay.ui:95 ui/preferences-window.ui:119
|
||||
msgid "Playback"
|
||||
msgstr ""
|
||||
msgstr "Uppspelning"
|
||||
|
||||
#: ui/help-overlay.ui:98
|
||||
msgid "Toggle play"
|
||||
msgstr ""
|
||||
msgstr "Spela/pausa"
|
||||
|
||||
#: ui/help-overlay.ui:99
|
||||
msgid "Long press | Right click"
|
||||
msgstr ""
|
||||
msgstr "Långtryck | Högerklicka"
|
||||
|
||||
#: ui/help-overlay.ui:105
|
||||
msgid "Seek forward"
|
||||
msgstr ""
|
||||
msgstr "Spola framåt"
|
||||
|
||||
#: ui/help-overlay.ui:106
|
||||
msgid "Swipe right | Scroll right"
|
||||
msgstr ""
|
||||
msgstr "Svep höger | Skrolla höger"
|
||||
|
||||
#: ui/help-overlay.ui:112
|
||||
msgid "Seek backward"
|
||||
msgstr ""
|
||||
msgstr "Spola bakåt"
|
||||
|
||||
#: ui/help-overlay.ui:113
|
||||
msgid "Swipe left | Scroll left"
|
||||
msgstr ""
|
||||
msgstr "Svep vänster | Skrolla vänster"
|
||||
|
||||
#: ui/help-overlay.ui:119
|
||||
msgid "Volume up"
|
||||
msgstr ""
|
||||
msgstr "Höj volymen"
|
||||
|
||||
#: ui/help-overlay.ui:120
|
||||
msgid "Swipe up | Scroll up"
|
||||
msgstr ""
|
||||
msgstr "Svep uppåt | Skrolla uppåt"
|
||||
|
||||
#: ui/help-overlay.ui:126
|
||||
msgid "Volume down"
|
||||
msgstr ""
|
||||
msgstr "Sänk volymen"
|
||||
|
||||
#: ui/help-overlay.ui:127
|
||||
msgid "Swipe down | Scroll down"
|
||||
msgstr ""
|
||||
msgstr "Svep nedåt | Skrolla nedåt"
|
||||
|
||||
#: ui/help-overlay.ui:133
|
||||
msgid "Toggle mute"
|
||||
msgstr ""
|
||||
msgstr "Växla ljudet på/av"
|
||||
|
||||
#: ui/help-overlay.ui:139
|
||||
msgid "Next chapter"
|
||||
msgstr ""
|
||||
msgstr "Nästa kapitel"
|
||||
|
||||
#: ui/help-overlay.ui:145
|
||||
msgid "Previous chapter"
|
||||
msgstr ""
|
||||
msgstr "Föregående kapitel"
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:11
|
||||
msgid "Decoders"
|
||||
msgstr ""
|
||||
msgstr "Avkodare"
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:18
|
||||
msgid "Return to the preferences"
|
||||
msgstr ""
|
||||
msgstr "Återgå till inställningarna"
|
||||
|
||||
#: ui/preferences-window.ui:16
|
||||
msgid "Behavior"
|
||||
msgstr ""
|
||||
msgstr "Beteende"
|
||||
|
||||
#: ui/preferences-window.ui:19
|
||||
msgid "Auto fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Automatiskt helskärmsläge"
|
||||
|
||||
#: ui/preferences-window.ui:20
|
||||
msgid "Enter fullscreen when playlist is replaced except floating mode"
|
||||
msgstr ""
|
||||
msgstr "Växla till fullskärmsläge när en spellista ersätts, förutom i flytande läge"
|
||||
|
||||
#: ui/preferences-window.ui:26
|
||||
msgid "Ask to resume recent media"
|
||||
msgstr ""
|
||||
msgstr "Be att återuppta senaste media"
|
||||
|
||||
#: ui/preferences-window.ui:32
|
||||
msgid "Float on all workspaces"
|
||||
msgstr ""
|
||||
msgstr "Flyt på alla arbetsytor"
|
||||
|
||||
#: ui/preferences-window.ui:33
|
||||
msgid "This option only works on GNOME"
|
||||
msgstr ""
|
||||
msgstr "Det här alternativet fungerar endast i GNOME"
|
||||
|
||||
#: ui/preferences-window.ui:39
|
||||
msgid "After playback"
|
||||
msgstr ""
|
||||
msgstr "Efter uppspelning"
|
||||
|
||||
#: ui/preferences-window.ui:44
|
||||
msgid "Do nothing"
|
||||
msgstr ""
|
||||
msgstr "Gör ingenting"
|
||||
|
||||
#: ui/preferences-window.ui:45
|
||||
msgid "Freeze last frame"
|
||||
msgstr ""
|
||||
msgstr "Frys sista bildruta"
|
||||
|
||||
#: ui/preferences-window.ui:46
|
||||
msgid "Close the app"
|
||||
msgstr ""
|
||||
msgstr "Stäng appen"
|
||||
|
||||
#: ui/preferences-window.ui:56
|
||||
msgid "Volume"
|
||||
msgstr ""
|
||||
msgstr "Volym"
|
||||
|
||||
#: ui/preferences-window.ui:59
|
||||
msgid "Custom initial value"
|
||||
msgstr ""
|
||||
msgstr "Anpassat startvärde"
|
||||
|
||||
#: ui/preferences-window.ui:60
|
||||
msgid "Set custom volume at startup instead of restoring it"
|
||||
msgstr ""
|
||||
msgstr "Ställ in anpassad volym vid start istället för att återställa den"
|
||||
|
||||
#: ui/preferences-window.ui:64
|
||||
msgid "Volume percentage"
|
||||
msgstr ""
|
||||
msgstr "Volymprocent"
|
||||
|
||||
#: ui/preferences-window.ui:75
|
||||
msgid "Seeking"
|
||||
msgstr ""
|
||||
msgstr "Spolning"
|
||||
|
||||
#: ui/preferences-window.ui:78
|
||||
msgid "Mode"
|
||||
msgstr ""
|
||||
msgstr "Läge"
|
||||
|
||||
#: ui/preferences-window.ui:84
|
||||
msgid "Accurate"
|
||||
msgstr ""
|
||||
msgstr "Riktig"
|
||||
|
||||
#: ui/preferences-window.ui:85
|
||||
msgid "Fast"
|
||||
msgstr ""
|
||||
msgstr "Snabbt"
|
||||
|
||||
#: ui/preferences-window.ui:93
|
||||
msgid "Unit"
|
||||
msgstr ""
|
||||
msgstr "Enhet"
|
||||
|
||||
#: ui/preferences-window.ui:98
|
||||
msgid "Second"
|
||||
msgstr ""
|
||||
msgstr "Sekund"
|
||||
|
||||
#: ui/preferences-window.ui:99
|
||||
msgid "Minute"
|
||||
msgstr ""
|
||||
msgstr "Minut"
|
||||
|
||||
#: ui/preferences-window.ui:100
|
||||
msgid "Percentage"
|
||||
msgstr ""
|
||||
msgstr "Procent"
|
||||
|
||||
#: ui/preferences-window.ui:108
|
||||
msgid "Value"
|
||||
msgstr ""
|
||||
msgstr "Värde"
|
||||
|
||||
#: ui/preferences-window.ui:123
|
||||
msgid "Audio"
|
||||
msgstr ""
|
||||
msgstr "Ljud"
|
||||
|
||||
#: ui/preferences-window.ui:126
|
||||
msgid "Offset in milliseconds"
|
||||
msgstr ""
|
||||
msgstr "Förskjutning i millisekunder"
|
||||
|
||||
#: ui/preferences-window.ui:133
|
||||
msgid "Only native audio formats"
|
||||
msgstr ""
|
||||
msgstr "Endast inbyggda ljudformat"
|
||||
|
||||
#: ui/preferences-window.ui:141
|
||||
msgid "Subtitles"
|
||||
msgstr ""
|
||||
msgstr "Undertexter"
|
||||
|
||||
#: ui/preferences-window.ui:144
|
||||
msgid "Default font"
|
||||
msgstr ""
|
||||
msgstr "Standardteckensnitt"
|
||||
|
||||
#: ui/preferences-window.ui:154
|
||||
msgid "Network"
|
||||
msgstr ""
|
||||
msgstr "Nätverk"
|
||||
|
||||
#: ui/preferences-window.ui:158
|
||||
msgid "Client"
|
||||
msgstr ""
|
||||
msgstr "Klient"
|
||||
|
||||
#: ui/preferences-window.ui:161
|
||||
msgid "Progressive download buffering"
|
||||
msgstr ""
|
||||
msgstr "Progressiv nedladdningsbuffert"
|
||||
|
||||
#: ui/preferences-window.ui:169
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
msgstr "Server"
|
||||
|
||||
#: ui/preferences-window.ui:172
|
||||
msgid "Control player remotely"
|
||||
msgstr ""
|
||||
msgstr "Fjärrstyra spelaren"
|
||||
|
||||
#: ui/preferences-window.ui:176
|
||||
msgid "Listening port"
|
||||
msgstr ""
|
||||
msgstr "Lyssningsport"
|
||||
|
||||
#: ui/preferences-window.ui:183
|
||||
msgid "Run web application in background"
|
||||
msgstr ""
|
||||
msgstr "Kör webbprogram i bakgrunden"
|
||||
|
||||
#: ui/preferences-window.ui:184
|
||||
msgid "Requires GTK compiled with Broadway backend"
|
||||
msgstr ""
|
||||
msgstr "Kräver GTK kompilerad med Broadway backend"
|
||||
|
||||
#: ui/preferences-window.ui:190
|
||||
msgid "Web application port"
|
||||
msgstr ""
|
||||
msgstr "Port för webbprogram"
|
||||
|
||||
#: ui/preferences-window.ui:204
|
||||
msgid "Prefer adaptive streaming"
|
||||
msgstr ""
|
||||
msgstr "Föredra adaptiv streaming"
|
||||
|
||||
#: ui/preferences-window.ui:210
|
||||
msgid "Max quality"
|
||||
msgstr ""
|
||||
msgstr "Max kvalitet"
|
||||
|
||||
#: ui/preferences-window.ui:228
|
||||
msgid "Tweaks"
|
||||
msgstr ""
|
||||
msgstr "Tweaks"
|
||||
|
||||
#: ui/preferences-window.ui:232
|
||||
msgid "Appearance"
|
||||
msgstr ""
|
||||
msgstr "Utseende"
|
||||
|
||||
#: ui/preferences-window.ui:235
|
||||
msgid "Dark theme"
|
||||
msgstr ""
|
||||
msgstr "Mörkt Tema"
|
||||
|
||||
#: ui/preferences-window.ui:241
|
||||
msgid "Render window shadows"
|
||||
msgstr ""
|
||||
msgstr "Rendera fönsterskuggor"
|
||||
|
||||
#: ui/preferences-window.ui:242
|
||||
msgid "Disable to increase performance when windowed"
|
||||
msgstr ""
|
||||
msgstr "Inaktivera för att öka prestanda när fönsterläge är på"
|
||||
|
||||
#: ui/preferences-window.ui:253
|
||||
msgid "Plugin ranking"
|
||||
msgstr ""
|
||||
msgstr "Rangordning av plugin"
|
||||
|
||||
#: ui/preferences-window.ui:254
|
||||
msgid "Alter default ranks of GStreamer plugins"
|
||||
msgstr ""
|
||||
msgstr "Ändra standardrankningar för GStreamer-plugins"
|
||||
|
||||
#: ui/preferences-window.ui:259
|
||||
msgid "Use playbin3"
|
||||
msgstr ""
|
||||
msgstr "Använd playbin3"
|
||||
|
||||
#: ui/preferences-window.ui:260 ui/preferences-window.ui:269
|
||||
msgid "Requires player restart"
|
||||
msgstr ""
|
||||
msgstr "Kräver omstart av spelaren"
|
||||
|
||||
#: ui/preferences-window.ui:262 ui/preferences-window.ui:271
|
||||
msgid "Experimental"
|
||||
msgstr ""
|
||||
msgstr "Exprimentalt"
|
||||
|
||||
#: ui/preferences-window.ui:268
|
||||
msgid "Use PipeWire for audio output"
|
||||
msgstr ""
|
||||
msgstr "Använd PipeWire för Ljudutgång"
|
||||
|
||||
#: src/buttons.js:201
|
||||
#, javascript-format
|
||||
msgid "Decoder: %s"
|
||||
msgstr ""
|
||||
msgstr "Avkodare: %s"
|
||||
|
||||
#: src/dialogs.js:152
|
||||
msgid "Enter or drop URI here"
|
||||
msgstr ""
|
||||
msgstr "Ange eller släpp URI här"
|
||||
|
||||
#: src/dialogs.js:157
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "Avbryt"
|
||||
|
||||
#: src/dialogs.js:158
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
msgstr "Öppna"
|
||||
|
||||
#: src/dialogs.js:226
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
msgid "Title"
|
||||
msgstr "Titel"
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr "Klar"
|
||||
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr "Återuppta uppspelningen?"
|
||||
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
msgstr "GTK version: %s"
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
msgstr "Adwaita version: %s"
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr "GStreamer version: %s"
|
||||
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr "GJS version: %s"
|
||||
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
msgstr "En media spelare för GNOME som drivs av GStreamer"
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr "SA ST (sastofficial)"
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
msgstr "Slutar vid: %s"
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
msgstr "Obestämd"
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
msgstr "Kanaler"
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
msgstr "Avstängd"
|
||||
|
||||
|
35
po/tr.po
35
po/tr.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:31\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-14 15:24\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Turkish\n"
|
||||
"Language: tr_TR\n"
|
||||
@@ -18,11 +18,11 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgid "Open Files…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgid "Open URI…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
@@ -399,56 +399,61 @@ msgstr ""
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
|
35
po/uk.po
35
po/uk.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:30\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-14 15:24\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Ukrainian\n"
|
||||
"Language: uk_UA\n"
|
||||
@@ -18,11 +18,11 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgid "Open Files…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgid "Open URI…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
@@ -399,56 +399,61 @@ msgstr ""
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
|
35
po/vi.po
35
po/vi.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:30\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-14 15:24\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Vietnamese\n"
|
||||
"Language: vi_VN\n"
|
||||
@@ -18,11 +18,11 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgid "Open Files…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgid "Open URI…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
@@ -399,56 +399,61 @@ msgstr ""
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
|
203
po/zh_CN.po
203
po/zh_CN.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:30\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2022-01-16 14:15\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Chinese Simplified\n"
|
||||
"Language: zh_CN\n"
|
||||
@@ -18,37 +18,37 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgstr ""
|
||||
msgid "Open Files…"
|
||||
msgstr "打开文件…"
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgstr ""
|
||||
msgid "Open URI…"
|
||||
msgstr "打开 URI…"
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
msgid "Preferences"
|
||||
msgstr ""
|
||||
msgstr "选项"
|
||||
|
||||
#: ui/clapper.ui:20
|
||||
msgid "Shortcuts"
|
||||
msgstr ""
|
||||
msgstr "快捷键"
|
||||
|
||||
#: ui/clapper.ui:26
|
||||
msgid "About Clapper"
|
||||
msgstr ""
|
||||
msgstr "关于 Claper"
|
||||
|
||||
#: ui/elapsed-time-button.ui:27
|
||||
msgid "Speed"
|
||||
msgstr ""
|
||||
msgstr "速度"
|
||||
|
||||
#: ui/elapsed-time-button.ui:41 ui/preferences-window.ui:83
|
||||
#: ui/preferences-window.ui:215
|
||||
msgid "Normal"
|
||||
msgstr ""
|
||||
msgstr "一般"
|
||||
|
||||
#: ui/help-overlay.ui:10 ui/preferences-window.ui:12
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
msgstr "常规"
|
||||
|
||||
#: ui/help-overlay.ui:13
|
||||
msgid "Show shortcuts"
|
||||
@@ -64,11 +64,11 @@ msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:26
|
||||
msgid "Leave fullscreen"
|
||||
msgstr ""
|
||||
msgstr "离开全屏"
|
||||
|
||||
#: ui/help-overlay.ui:32
|
||||
msgid "Reveal OSD (fullscreen only)"
|
||||
msgstr ""
|
||||
msgstr "显示 OSD(仅全屏)"
|
||||
|
||||
#: ui/help-overlay.ui:33
|
||||
msgid "Tap"
|
||||
@@ -76,27 +76,27 @@ msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:39
|
||||
msgid "Quit"
|
||||
msgstr ""
|
||||
msgstr "退出"
|
||||
|
||||
#: ui/help-overlay.ui:47
|
||||
msgid "Media"
|
||||
msgstr ""
|
||||
msgstr "媒体"
|
||||
|
||||
#: ui/help-overlay.ui:50
|
||||
msgid "Open files"
|
||||
msgstr ""
|
||||
msgstr "打开文件"
|
||||
|
||||
#: ui/help-overlay.ui:56 src/dialogs.js:137
|
||||
msgid "Open URI"
|
||||
msgstr ""
|
||||
msgstr "打开 URI"
|
||||
|
||||
#: ui/help-overlay.ui:64
|
||||
msgid "Playlist"
|
||||
msgstr ""
|
||||
msgstr "播放列表"
|
||||
|
||||
#: ui/help-overlay.ui:67
|
||||
msgid "Next item"
|
||||
msgstr ""
|
||||
msgstr "下一项"
|
||||
|
||||
#: ui/help-overlay.ui:68
|
||||
msgid "Double tap (right side)"
|
||||
@@ -104,7 +104,7 @@ msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:74
|
||||
msgid "Previous item"
|
||||
msgstr ""
|
||||
msgstr "上一项"
|
||||
|
||||
#: ui/help-overlay.ui:75
|
||||
msgid "Double tap (left side)"
|
||||
@@ -112,7 +112,7 @@ msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:81
|
||||
msgid "Change repeat mode"
|
||||
msgstr ""
|
||||
msgstr "更改循环模式"
|
||||
|
||||
#: ui/help-overlay.ui:87
|
||||
msgid "Export to file"
|
||||
@@ -128,11 +128,11 @@ msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:99
|
||||
msgid "Long press | Right click"
|
||||
msgstr ""
|
||||
msgstr "长按 | 右键点击"
|
||||
|
||||
#: ui/help-overlay.ui:105
|
||||
msgid "Seek forward"
|
||||
msgstr ""
|
||||
msgstr "快进"
|
||||
|
||||
#: ui/help-overlay.ui:106
|
||||
msgid "Swipe right | Scroll right"
|
||||
@@ -140,7 +140,7 @@ msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:112
|
||||
msgid "Seek backward"
|
||||
msgstr ""
|
||||
msgstr "快退"
|
||||
|
||||
#: ui/help-overlay.ui:113
|
||||
msgid "Swipe left | Scroll left"
|
||||
@@ -148,19 +148,19 @@ msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:119
|
||||
msgid "Volume up"
|
||||
msgstr ""
|
||||
msgstr "提高音量"
|
||||
|
||||
#: ui/help-overlay.ui:120
|
||||
msgid "Swipe up | Scroll up"
|
||||
msgstr ""
|
||||
msgstr "向上滑动 | 向上滚动"
|
||||
|
||||
#: ui/help-overlay.ui:126
|
||||
msgid "Volume down"
|
||||
msgstr ""
|
||||
msgstr "降低音量"
|
||||
|
||||
#: ui/help-overlay.ui:127
|
||||
msgid "Swipe down | Scroll down"
|
||||
msgstr ""
|
||||
msgstr "向下滑动 | 向下滚动"
|
||||
|
||||
#: ui/help-overlay.ui:133
|
||||
msgid "Toggle mute"
|
||||
@@ -176,7 +176,7 @@ msgstr ""
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:11
|
||||
msgid "Decoders"
|
||||
msgstr ""
|
||||
msgstr "解码器"
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:18
|
||||
msgid "Return to the preferences"
|
||||
@@ -184,11 +184,11 @@ msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:16
|
||||
msgid "Behavior"
|
||||
msgstr ""
|
||||
msgstr "行为"
|
||||
|
||||
#: ui/preferences-window.ui:19
|
||||
msgid "Auto fullscreen"
|
||||
msgstr ""
|
||||
msgstr "自动全屏"
|
||||
|
||||
#: ui/preferences-window.ui:20
|
||||
msgid "Enter fullscreen when playlist is replaced except floating mode"
|
||||
@@ -204,31 +204,31 @@ msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:33
|
||||
msgid "This option only works on GNOME"
|
||||
msgstr ""
|
||||
msgstr "此选项仅适用于 GNOME"
|
||||
|
||||
#: ui/preferences-window.ui:39
|
||||
msgid "After playback"
|
||||
msgstr ""
|
||||
msgstr "播放结束后"
|
||||
|
||||
#: ui/preferences-window.ui:44
|
||||
msgid "Do nothing"
|
||||
msgstr ""
|
||||
msgstr "不执行任何操作"
|
||||
|
||||
#: ui/preferences-window.ui:45
|
||||
msgid "Freeze last frame"
|
||||
msgstr ""
|
||||
msgstr "停留在最后一帧"
|
||||
|
||||
#: ui/preferences-window.ui:46
|
||||
msgid "Close the app"
|
||||
msgstr ""
|
||||
msgstr "关闭应用程序"
|
||||
|
||||
#: ui/preferences-window.ui:56
|
||||
msgid "Volume"
|
||||
msgstr ""
|
||||
msgstr "音量"
|
||||
|
||||
#: ui/preferences-window.ui:59
|
||||
msgid "Custom initial value"
|
||||
msgstr ""
|
||||
msgstr "自定义初始值"
|
||||
|
||||
#: ui/preferences-window.ui:60
|
||||
msgid "Set custom volume at startup instead of restoring it"
|
||||
@@ -236,47 +236,47 @@ msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:64
|
||||
msgid "Volume percentage"
|
||||
msgstr ""
|
||||
msgstr "音量百分比"
|
||||
|
||||
#: ui/preferences-window.ui:75
|
||||
msgid "Seeking"
|
||||
msgstr ""
|
||||
msgstr "定位播放"
|
||||
|
||||
#: ui/preferences-window.ui:78
|
||||
msgid "Mode"
|
||||
msgstr ""
|
||||
msgstr "模式"
|
||||
|
||||
#: ui/preferences-window.ui:84
|
||||
msgid "Accurate"
|
||||
msgstr ""
|
||||
msgstr "精确"
|
||||
|
||||
#: ui/preferences-window.ui:85
|
||||
msgid "Fast"
|
||||
msgstr ""
|
||||
msgstr "快速"
|
||||
|
||||
#: ui/preferences-window.ui:93
|
||||
msgid "Unit"
|
||||
msgstr ""
|
||||
msgstr "单位"
|
||||
|
||||
#: ui/preferences-window.ui:98
|
||||
msgid "Second"
|
||||
msgstr ""
|
||||
msgstr "秒钟"
|
||||
|
||||
#: ui/preferences-window.ui:99
|
||||
msgid "Minute"
|
||||
msgstr ""
|
||||
msgstr "分钟"
|
||||
|
||||
#: ui/preferences-window.ui:100
|
||||
msgid "Percentage"
|
||||
msgstr ""
|
||||
msgstr "百分比"
|
||||
|
||||
#: ui/preferences-window.ui:108
|
||||
msgid "Value"
|
||||
msgstr ""
|
||||
msgstr "值"
|
||||
|
||||
#: ui/preferences-window.ui:123
|
||||
msgid "Audio"
|
||||
msgstr ""
|
||||
msgstr "音频"
|
||||
|
||||
#: ui/preferences-window.ui:126
|
||||
msgid "Offset in milliseconds"
|
||||
@@ -288,19 +288,19 @@ msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:141
|
||||
msgid "Subtitles"
|
||||
msgstr ""
|
||||
msgstr "字幕"
|
||||
|
||||
#: ui/preferences-window.ui:144
|
||||
msgid "Default font"
|
||||
msgstr ""
|
||||
msgstr "默认字体"
|
||||
|
||||
#: ui/preferences-window.ui:154
|
||||
msgid "Network"
|
||||
msgstr ""
|
||||
msgstr "网络"
|
||||
|
||||
#: ui/preferences-window.ui:158
|
||||
msgid "Client"
|
||||
msgstr ""
|
||||
msgstr "客户端"
|
||||
|
||||
#: ui/preferences-window.ui:161
|
||||
msgid "Progressive download buffering"
|
||||
@@ -308,15 +308,15 @@ msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:169
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
msgstr "服务器"
|
||||
|
||||
#: ui/preferences-window.ui:172
|
||||
msgid "Control player remotely"
|
||||
msgstr ""
|
||||
msgstr "远程控制播放器"
|
||||
|
||||
#: ui/preferences-window.ui:176
|
||||
msgid "Listening port"
|
||||
msgstr ""
|
||||
msgstr "监听端口"
|
||||
|
||||
#: ui/preferences-window.ui:183
|
||||
msgid "Run web application in background"
|
||||
@@ -328,7 +328,7 @@ msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:190
|
||||
msgid "Web application port"
|
||||
msgstr ""
|
||||
msgstr "Web 应用程序端口"
|
||||
|
||||
#: ui/preferences-window.ui:204
|
||||
msgid "Prefer adaptive streaming"
|
||||
@@ -340,19 +340,19 @@ msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:228
|
||||
msgid "Tweaks"
|
||||
msgstr ""
|
||||
msgstr "微调"
|
||||
|
||||
#: ui/preferences-window.ui:232
|
||||
msgid "Appearance"
|
||||
msgstr ""
|
||||
msgstr "界面"
|
||||
|
||||
#: ui/preferences-window.ui:235
|
||||
msgid "Dark theme"
|
||||
msgstr ""
|
||||
msgstr "暗色主题"
|
||||
|
||||
#: ui/preferences-window.ui:241
|
||||
msgid "Render window shadows"
|
||||
msgstr ""
|
||||
msgstr "渲染窗口阴影"
|
||||
|
||||
#: ui/preferences-window.ui:242
|
||||
msgid "Disable to increase performance when windowed"
|
||||
@@ -368,24 +368,24 @@ msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:259
|
||||
msgid "Use playbin3"
|
||||
msgstr ""
|
||||
msgstr "使用 playbin3"
|
||||
|
||||
#: ui/preferences-window.ui:260 ui/preferences-window.ui:269
|
||||
msgid "Requires player restart"
|
||||
msgstr ""
|
||||
msgstr "需要重启播放器"
|
||||
|
||||
#: ui/preferences-window.ui:262 ui/preferences-window.ui:271
|
||||
msgid "Experimental"
|
||||
msgstr ""
|
||||
msgstr "实验性功能"
|
||||
|
||||
#: ui/preferences-window.ui:268
|
||||
msgid "Use PipeWire for audio output"
|
||||
msgstr ""
|
||||
msgstr "使用 PipeWire 输出音频"
|
||||
|
||||
#: src/buttons.js:201
|
||||
#, javascript-format
|
||||
msgid "Decoder: %s"
|
||||
msgstr ""
|
||||
msgstr "解码器:%s"
|
||||
|
||||
#: src/dialogs.js:152
|
||||
msgid "Enter or drop URI here"
|
||||
@@ -393,62 +393,67 @@ msgstr ""
|
||||
|
||||
#: src/dialogs.js:157
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "取消"
|
||||
|
||||
#: src/dialogs.js:158
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
msgstr "打开"
|
||||
|
||||
#: src/dialogs.js:226
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
msgid "Title"
|
||||
msgstr "标题"
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr "已播放"
|
||||
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr "继续播放?"
|
||||
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
msgstr "GTK 版本:%s"
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
msgstr "Adwaita 版本:%s"
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr "GStreamer 版本:%s"
|
||||
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr "GJS 版本:%s"
|
||||
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
msgstr "结束于:%s"
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
msgstr "声道"
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
msgstr "禁用"
|
||||
|
||||
|
35
po/zh_TW.po
35
po/zh_TW.po
@@ -2,8 +2,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-06 20:22+0200\n"
|
||||
"PO-Revision-Date: 2021-09-06 18:30\n"
|
||||
"POT-Creation-Date: 2021-09-14 16:35+0200\n"
|
||||
"PO-Revision-Date: 2021-09-14 15:24\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Chinese Traditional\n"
|
||||
"Language: zh_TW\n"
|
||||
@@ -18,11 +18,11 @@ msgstr ""
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files..."
|
||||
msgid "Open Files…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI..."
|
||||
msgid "Open URI…"
|
||||
msgstr ""
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
@@ -399,56 +399,61 @@ msgstr ""
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:217
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:218
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:226
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:280
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:281
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:282
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:283
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:225 src/widget.js:234 src/widget.js:240 src/widget.js:246
|
||||
#: src/widget.js:227 src/widget.js:236 src/widget.js:242 src/widget.js:248
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:241
|
||||
#: src/widget.js:243
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:259
|
||||
#: src/widget.js:261
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
|
@@ -18,13 +18,13 @@ var actions = {
|
||||
prev_track: ['<Ctrl>Left'],
|
||||
volume_up: ['Up'],
|
||||
volume_down: ['Down'],
|
||||
mute: ['<Ctrl>m'],
|
||||
mute: ['<Ctrl>M', 'M'],
|
||||
toggle_play: ['space'],
|
||||
change_repeat: ['<Ctrl>r'],
|
||||
change_repeat: ['<Ctrl>R'],
|
||||
reveal_controls: ['Return'],
|
||||
toggle_fullscreen: ['F11', 'f'],
|
||||
toggle_fullscreen: ['F11', 'F'],
|
||||
leave_fullscreen: ['Escape'],
|
||||
quit: ['<Ctrl>q', 'q'],
|
||||
quit: ['<Ctrl>Q', 'Q'],
|
||||
};
|
||||
|
||||
function handleAction(action, window)
|
||||
|
@@ -96,13 +96,6 @@ class ClapperAppBase extends Gtk.Application
|
||||
if(accels)
|
||||
this.set_accels_for_action(`app.${name}`, accels);
|
||||
}
|
||||
|
||||
const gtkSettings = Gtk.Settings.get_default();
|
||||
settings.bind(
|
||||
'dark-theme', gtkSettings,
|
||||
'gtk-application-prefer-dark-theme',
|
||||
Gio.SettingsBindFlags.GET
|
||||
);
|
||||
this.doneFirstActivate = true;
|
||||
}
|
||||
});
|
||||
|
@@ -1,25 +0,0 @@
|
||||
const { GObject } = imports.gi;
|
||||
const { AppBase } = imports.src.appBase;
|
||||
const { HeaderBarRemote } = imports.src.headerbarRemote;
|
||||
const { WidgetRemote } = imports.src.widgetRemote;
|
||||
|
||||
var AppRemote = GObject.registerClass({
|
||||
GTypeName: 'ClapperAppRemote',
|
||||
},
|
||||
class ClapperAppRemote extends AppBase
|
||||
{
|
||||
vfunc_startup()
|
||||
{
|
||||
super.vfunc_startup();
|
||||
|
||||
const window = this.active_window;
|
||||
|
||||
const clapperWidget = new WidgetRemote();
|
||||
window.set_child(clapperWidget);
|
||||
|
||||
const headerBar = new HeaderBarRemote();
|
||||
window.set_titlebar(headerBar);
|
||||
|
||||
window.maximize();
|
||||
}
|
||||
});
|
@@ -1,151 +0,0 @@
|
||||
/* Copyright (C) 2012-present by fent
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
const jsVarStr = '[a-zA-Z_\\$][a-zA-Z_0-9]*';
|
||||
const jsSingleQuoteStr = `'[^'\\\\]*(:?\\\\[\\s\\S][^'\\\\]*)*'`;
|
||||
const jsDoubleQuoteStr = `"[^"\\\\]*(:?\\\\[\\s\\S][^"\\\\]*)*"`;
|
||||
const jsQuoteStr = `(?:${jsSingleQuoteStr}|${jsDoubleQuoteStr})`;
|
||||
const jsKeyStr = `(?:${jsVarStr}|${jsQuoteStr})`;
|
||||
const jsPropStr = `(?:\\.${jsVarStr}|\\[${jsQuoteStr}\\])`;
|
||||
const jsEmptyStr = `(?:''|"")`;
|
||||
const reverseStr = ':function\\(a\\)\\{' +
|
||||
'(?:return )?a\\.reverse\\(\\)' +
|
||||
'\\}';
|
||||
const sliceStr = ':function\\(a,b\\)\\{' +
|
||||
'return a\\.slice\\(b\\)' +
|
||||
'\\}';
|
||||
const spliceStr = ':function\\(a,b\\)\\{' +
|
||||
'a\\.splice\\(0,b\\)' +
|
||||
'\\}';
|
||||
const swapStr = ':function\\(a,b\\)\\{' +
|
||||
'var c=a\\[0\\];a\\[0\\]=a\\[b(?:%a\\.length)?\\];a\\[b(?:%a\\.length)?\\]=c(?:;return a)?' +
|
||||
'\\}';
|
||||
const actionsObjRegexp = new RegExp(
|
||||
`var (${jsVarStr})=\\{((?:(?:${
|
||||
jsKeyStr}${reverseStr}|${
|
||||
jsKeyStr}${sliceStr}|${
|
||||
jsKeyStr}${spliceStr}|${
|
||||
jsKeyStr}${swapStr
|
||||
}),?\\r?\\n?)+)\\};`);
|
||||
const actionsFuncRegexp = new RegExp(`${`function(?: ${jsVarStr})?\\(a\\)\\{` +
|
||||
`a=a\\.split\\(${jsEmptyStr}\\);\\s*` +
|
||||
`((?:(?:a=)?${jsVarStr}`}${
|
||||
jsPropStr
|
||||
}\\(a,\\d+\\);)+)` +
|
||||
`return a\\.join\\(${jsEmptyStr}\\)` +
|
||||
`\\}`);
|
||||
const reverseRegexp = new RegExp(`(?:^|,)(${jsKeyStr})${reverseStr}`, 'm');
|
||||
const sliceRegexp = new RegExp(`(?:^|,)(${jsKeyStr})${sliceStr}`, 'm');
|
||||
const spliceRegexp = new RegExp(`(?:^|,)(${jsKeyStr})${spliceStr}`, 'm');
|
||||
const swapRegexp = new RegExp(`(?:^|,)(${jsKeyStr})${swapStr}`, 'm');
|
||||
|
||||
const swapHeadAndPosition = (arr, position) => {
|
||||
const first = arr[0];
|
||||
arr[0] = arr[position % arr.length];
|
||||
arr[position] = first;
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
function decipher(sig, tokens) {
|
||||
sig = sig.split('');
|
||||
tokens = tokens.split(',');
|
||||
|
||||
for(let i = 0, len = tokens.length; i < len; i++) {
|
||||
let token = tokens[i], pos;
|
||||
switch (token[0]) {
|
||||
case 'r':
|
||||
sig = sig.reverse();
|
||||
break;
|
||||
case 'w':
|
||||
pos = ~~token.slice(1);
|
||||
sig = swapHeadAndPosition(sig, pos);
|
||||
break;
|
||||
case 's':
|
||||
pos = ~~token.slice(1);
|
||||
sig = sig.slice(pos);
|
||||
break;
|
||||
case 'p':
|
||||
pos = ~~token.slice(1);
|
||||
sig.splice(0, pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return sig.join('');
|
||||
};
|
||||
|
||||
function extractActions(body) {
|
||||
const objResult = actionsObjRegexp.exec(body);
|
||||
const funcResult = actionsFuncRegexp.exec(body);
|
||||
|
||||
if(!objResult || !funcResult)
|
||||
return null;
|
||||
|
||||
const obj = objResult[1].replace(/\$/g, '\\$');
|
||||
const objBody = objResult[2].replace(/\$/g, '\\$');
|
||||
const funcBody = funcResult[1].replace(/\$/g, '\\$');
|
||||
|
||||
let result = reverseRegexp.exec(objBody);
|
||||
const reverseKey = result && result[1]
|
||||
.replace(/\$/g, '\\$')
|
||||
.replace(/\$|^'|^"|'$|"$/g, '');
|
||||
result = sliceRegexp.exec(objBody);
|
||||
const sliceKey = result && result[1]
|
||||
.replace(/\$/g, '\\$')
|
||||
.replace(/\$|^'|^"|'$|"$/g, '');
|
||||
result = spliceRegexp.exec(objBody);
|
||||
const spliceKey = result && result[1]
|
||||
.replace(/\$/g, '\\$')
|
||||
.replace(/\$|^'|^"|'$|"$/g, '');
|
||||
result = swapRegexp.exec(objBody);
|
||||
const swapKey = result && result[1]
|
||||
.replace(/\$/g, '\\$')
|
||||
.replace(/\$|^'|^"|'$|"$/g, '');
|
||||
|
||||
const keys = `(${[reverseKey, sliceKey, spliceKey, swapKey].join('|')})`;
|
||||
const myreg = `(?:a=)?${obj
|
||||
}(?:\\.${keys}|\\['${keys}'\\]|\\["${keys}"\\])` +
|
||||
`\\(a,(\\d+)\\)`;
|
||||
const tokenizeRegexp = new RegExp(myreg, 'g');
|
||||
const tokens = [];
|
||||
|
||||
while((result = tokenizeRegexp.exec(funcBody)) !== null) {
|
||||
const key = result[1] || result[2] || result[3];
|
||||
const pos = result[4];
|
||||
switch (key) {
|
||||
case swapKey:
|
||||
tokens.push(`w${result[4]}`);
|
||||
break;
|
||||
case reverseKey:
|
||||
tokens.push('r');
|
||||
break;
|
||||
case sliceKey:
|
||||
tokens.push(`s${result[4]}`);
|
||||
break;
|
||||
case spliceKey:
|
||||
tokens.push(`p${result[4]}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return tokens.join(',');
|
||||
}
|
@@ -165,7 +165,7 @@ class ClapperElapsedTimeButton extends PopoverButtonBase
|
||||
|
||||
setInitialState()
|
||||
{
|
||||
this.label = '00:00/00:00';
|
||||
this.label = '00∶00∕00∶00';
|
||||
}
|
||||
|
||||
setFullscreenMode(isFullscreen, isMobileMonitor)
|
||||
|
6
src/controls.js
vendored
6
src/controls.js
vendored
@@ -7,8 +7,6 @@ const Revealers = imports.src.revealers;
|
||||
const { debug } = Debug;
|
||||
const { settings } = Misc;
|
||||
|
||||
const INITIAL_ELAPSED = '00:00/00:00';
|
||||
|
||||
var Controls = GObject.registerClass({
|
||||
GTypeName: 'ClapperControls',
|
||||
},
|
||||
@@ -29,7 +27,7 @@ class ClapperControls extends Gtk.Box
|
||||
this.isMobile = false;
|
||||
|
||||
this.showHours = false;
|
||||
this.durationFormatted = '00:00';
|
||||
this.durationFormatted = '00∶00';
|
||||
this.revealersArr = [];
|
||||
this.chapters = null;
|
||||
|
||||
@@ -148,7 +146,7 @@ class ClapperControls extends Gtk.Box
|
||||
value = value || 0;
|
||||
|
||||
const elapsed = Misc.getFormattedTime(value, this.showHours)
|
||||
+ '/' + this.durationFormatted;
|
||||
+ '∕' + this.durationFormatted;
|
||||
|
||||
this.elapsedButton.label = elapsed;
|
||||
}
|
||||
|
@@ -1,70 +0,0 @@
|
||||
const { Gio, GLib, GObject } = imports.gi;
|
||||
const Debug = imports.src.debug;
|
||||
|
||||
const { debug } = Debug;
|
||||
|
||||
var Daemon = GObject.registerClass({
|
||||
GTypeName: 'ClapperDaemon',
|
||||
},
|
||||
class ClapperDaemon extends Gio.SubprocessLauncher
|
||||
{
|
||||
_init()
|
||||
{
|
||||
const port = ARGV[0] || 8080;
|
||||
|
||||
/* FIXME: show output when debugging is on */
|
||||
const flags = Gio.SubprocessFlags.STDOUT_SILENCE
|
||||
| Gio.SubprocessFlags.STDERR_SILENCE;
|
||||
|
||||
super._init({ flags });
|
||||
|
||||
this.errMsg = 'exited with error or was forced to close';
|
||||
this.loop = GLib.MainLoop.new(null, false);
|
||||
|
||||
this.broadwayd = this.spawnv(['gtk4-broadwayd', '--port=' + port]);
|
||||
this.broadwayd.wait_async(null, this._onBroadwaydClosed.bind(this));
|
||||
|
||||
this.setenv('GDK_BACKEND', 'broadway', true);
|
||||
|
||||
const remoteApp = this.spawnv(['com.github.rafostar.Clapper.Remote']);
|
||||
remoteApp.wait_async(null, this._onRemoteClosed.bind(this));
|
||||
|
||||
this.loop.run();
|
||||
}
|
||||
|
||||
_checkProcResult(proc, result)
|
||||
{
|
||||
let hadError = false;
|
||||
|
||||
try {
|
||||
hadError = proc.wait_finish(result);
|
||||
}
|
||||
catch(err) {
|
||||
debug(err);
|
||||
}
|
||||
|
||||
return hadError;
|
||||
}
|
||||
|
||||
_onBroadwaydClosed(proc, result)
|
||||
{
|
||||
const hadError = this._checkProcResult(proc, result);
|
||||
|
||||
if(hadError)
|
||||
debug(`broadwayd ${this.errMsg}`);
|
||||
|
||||
this.broadwayd = null;
|
||||
this.loop.quit();
|
||||
}
|
||||
|
||||
_onRemoteClosed(proc, result)
|
||||
{
|
||||
const hadError = this._checkProcResult(proc, result);
|
||||
|
||||
if(hadError)
|
||||
debug(`remote app ${this.errMsg}`);
|
||||
|
||||
if(this.broadwayd)
|
||||
this.broadwayd.force_exit();
|
||||
}
|
||||
});
|
165
src/dash.js
165
src/dash.js
@@ -1,165 +0,0 @@
|
||||
const Debug = imports.src.debug;
|
||||
const FileOps = imports.src.fileOps;
|
||||
const Misc = imports.src.misc;
|
||||
|
||||
const { debug } = Debug;
|
||||
|
||||
function generateDash(dashInfo)
|
||||
{
|
||||
debug('generating dash');
|
||||
|
||||
const bufferSec = Math.min(4, dashInfo.duration);
|
||||
|
||||
const dash = [
|
||||
`<?xml version="1.0" encoding="UTF-8"?>`,
|
||||
`<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"`,
|
||||
` xmlns="urn:mpeg:dash:schema:mpd:2011"`,
|
||||
` xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd"`,
|
||||
` type="static"`,
|
||||
` mediaPresentationDuration="PT${dashInfo.duration}S"`,
|
||||
` minBufferTime="PT${bufferSec}S"`,
|
||||
` profiles="urn:mpeg:dash:profile:isoff-on-demand:2011">`,
|
||||
` <Period>`
|
||||
];
|
||||
|
||||
for(let adaptation of dashInfo.adaptations)
|
||||
dash.push(_addAdaptationSet(adaptation));
|
||||
|
||||
dash.push(
|
||||
` </Period>`,
|
||||
`</MPD>`
|
||||
);
|
||||
|
||||
debug('dash generated');
|
||||
|
||||
return dash.join('\n');
|
||||
}
|
||||
|
||||
function _addAdaptationSet(streamsArr)
|
||||
{
|
||||
/* We just need it for adaptation type,
|
||||
* so any stream will do */
|
||||
const { mimeInfo } = streamsArr[0];
|
||||
|
||||
const adaptArr = [
|
||||
`contentType="${mimeInfo.content}"`,
|
||||
`mimeType="${mimeInfo.type}"`,
|
||||
`subsegmentAlignment="true"`,
|
||||
`subsegmentStartsWithSAP="1"`,
|
||||
];
|
||||
|
||||
const widthArr = [];
|
||||
const heightArr = [];
|
||||
const fpsArr = [];
|
||||
|
||||
const representations = [];
|
||||
|
||||
for(let stream of streamsArr) {
|
||||
/* No point parsing if no URL */
|
||||
if(!stream.url)
|
||||
continue;
|
||||
|
||||
if(stream.width && stream.height) {
|
||||
widthArr.push(stream.width);
|
||||
heightArr.push(stream.height);
|
||||
}
|
||||
if(stream.fps)
|
||||
fpsArr.push(stream.fps);
|
||||
|
||||
representations.push(_getStreamRepresentation(stream));
|
||||
}
|
||||
|
||||
if(widthArr.length && heightArr.length) {
|
||||
const maxWidth = Math.max.apply(null, widthArr);
|
||||
const maxHeight = Math.max.apply(null, heightArr);
|
||||
const par = _getPar(maxWidth, maxHeight);
|
||||
|
||||
adaptArr.push(`maxWidth="${maxWidth}"`);
|
||||
adaptArr.push(`maxHeight="${maxHeight}"`);
|
||||
adaptArr.push(`par="${par}"`);
|
||||
}
|
||||
if(fpsArr.length) {
|
||||
const maxFps = Math.max.apply(null, fpsArr);
|
||||
|
||||
adaptArr.push(`maxFrameRate="${maxFps}"`);
|
||||
}
|
||||
|
||||
const adaptationSet = [
|
||||
` <AdaptationSet ${adaptArr.join(' ')}>`,
|
||||
representations.join('\n'),
|
||||
` </AdaptationSet>`
|
||||
];
|
||||
|
||||
return adaptationSet.join('\n');
|
||||
}
|
||||
|
||||
function _getStreamRepresentation(stream)
|
||||
{
|
||||
const repOptsArr = [
|
||||
`id="${stream.itag}"`,
|
||||
`codecs="${stream.mimeInfo.codecs}"`,
|
||||
`bandwidth="${stream.bitrate}"`,
|
||||
];
|
||||
|
||||
if(stream.width && stream.height) {
|
||||
repOptsArr.push(`width="${stream.width}"`);
|
||||
repOptsArr.push(`height="${stream.height}"`);
|
||||
repOptsArr.push(`sar="1:1"`);
|
||||
}
|
||||
if(stream.fps)
|
||||
repOptsArr.push(`frameRate="${stream.fps}"`);
|
||||
|
||||
const repArr = [
|
||||
` <Representation ${repOptsArr.join(' ')}>`,
|
||||
];
|
||||
if(stream.audioChannels) {
|
||||
const audioConfArr = [
|
||||
`schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011"`,
|
||||
`value="${stream.audioChannels}"`,
|
||||
];
|
||||
repArr.push(` <AudioChannelConfiguration ${audioConfArr.join(' ')}/>`);
|
||||
}
|
||||
|
||||
repArr.push(
|
||||
` <BaseURL>${stream.url}</BaseURL>`
|
||||
);
|
||||
|
||||
if(stream.indexRange) {
|
||||
const segRange = `${stream.indexRange.start}-${stream.indexRange.end}`;
|
||||
repArr.push(
|
||||
` <SegmentBase indexRange="${segRange}">`
|
||||
);
|
||||
if(stream.initRange) {
|
||||
const initRange = `${stream.initRange.start}-${stream.initRange.end}`;
|
||||
repArr.push(
|
||||
` <Initialization range="${initRange}"/>`
|
||||
);
|
||||
}
|
||||
repArr.push(
|
||||
` </SegmentBase>`
|
||||
);
|
||||
}
|
||||
|
||||
repArr.push(
|
||||
` </Representation>`
|
||||
);
|
||||
|
||||
return repArr.join('\n');
|
||||
}
|
||||
|
||||
function _getPar(width, height)
|
||||
{
|
||||
const gcd = _getGCD(width, height);
|
||||
|
||||
width /= gcd;
|
||||
height /= gcd;
|
||||
|
||||
return `${width}:${height}`;
|
||||
}
|
||||
|
||||
function _getGCD(width, height)
|
||||
{
|
||||
return (height)
|
||||
? _getGCD(height, width % height)
|
||||
: width;
|
||||
}
|
25
src/debug.js
25
src/debug.js
@@ -20,17 +20,6 @@ clapperDebugger.enabled = (
|
||||
&& G_DEBUG_ENV.includes('Clapper')
|
||||
);
|
||||
|
||||
const ytDebugger = new Debug.Debugger('YouTube', {
|
||||
name_printer: new Ink.Printer({
|
||||
font: Ink.Font.BOLD,
|
||||
color: Ink.Color.RED
|
||||
}),
|
||||
time_printer: new Ink.Printer({
|
||||
color: Ink.Color.LIGHT_BLUE
|
||||
}),
|
||||
high_precision: true,
|
||||
});
|
||||
|
||||
function _logStructured(debuggerName, msg, level)
|
||||
{
|
||||
GLib.log_structured(
|
||||
@@ -52,14 +41,7 @@ function _debug(debuggerName, msg)
|
||||
return;
|
||||
}
|
||||
|
||||
switch(debuggerName) {
|
||||
case 'Clapper':
|
||||
clapperDebugger.debug(msg);
|
||||
break;
|
||||
case 'YouTube':
|
||||
ytDebugger.debug(msg);
|
||||
break;
|
||||
}
|
||||
clapperDebugger.debug(msg);
|
||||
}
|
||||
|
||||
function debug(msg)
|
||||
@@ -67,11 +49,6 @@ function debug(msg)
|
||||
_debug('Clapper', msg);
|
||||
}
|
||||
|
||||
function ytDebug(msg)
|
||||
{
|
||||
_debug('YouTube', msg);
|
||||
}
|
||||
|
||||
function warn(msg)
|
||||
{
|
||||
_logStructured('Clapper', msg, GLib.LogLevelFlags.LEVEL_WARNING);
|
||||
|
@@ -193,8 +193,17 @@ class ClapperUriDialog extends Gtk.Dialog
|
||||
|
||||
_readTextAsyncCb(clipboard, result)
|
||||
{
|
||||
const uri = clipboard.read_text_finish(result);
|
||||
if(!uri || !Gst.uri_is_valid(uri)) return;
|
||||
let uri = null;
|
||||
|
||||
try {
|
||||
uri = clipboard.read_text_finish(result);
|
||||
}
|
||||
catch(err) {
|
||||
debug(`could not read clipboard: ${err.message}`);
|
||||
}
|
||||
|
||||
if(!uri || !Gst.uri_is_valid(uri))
|
||||
return;
|
||||
|
||||
const contentBox = this.get_content_area();
|
||||
const linkEntry = contentBox.get_last_child();
|
||||
@@ -292,6 +301,8 @@ class ClapperAboutDialog extends Gtk.AboutDialog
|
||||
version: pkg.version,
|
||||
authors: ['Rafał Dzięgiel'],
|
||||
artists: ['Rafał Dzięgiel'],
|
||||
/* TRANSLATORS: Put your name(s) here for credits or leave untranslated */
|
||||
translator_credits: _('translator-credits'),
|
||||
license_type: Gtk.License.GPL_3_0,
|
||||
logo_icon_name: 'com.github.rafostar.Clapper',
|
||||
website: 'https://rafostar.github.io/clapper',
|
||||
|
@@ -1,22 +0,0 @@
|
||||
const { GObject } = imports.gi;
|
||||
const { HeaderBarBase } = imports.src.headerbarBase;
|
||||
|
||||
var HeaderBarRemote = GObject.registerClass({
|
||||
GTypeName: 'ClapperHeaderBarRemote',
|
||||
},
|
||||
class ClapperHeaderBarRemote extends HeaderBarBase
|
||||
{
|
||||
_init()
|
||||
{
|
||||
super._init();
|
||||
this.extraButtonsBox.visible = false;
|
||||
}
|
||||
|
||||
_onWindowButtonActivate(action)
|
||||
{
|
||||
if(action === 'toggle-maximized')
|
||||
action = 'toggle_maximized';
|
||||
|
||||
this.root.child.sendWs(action);
|
||||
}
|
||||
});
|
@@ -1,6 +1,6 @@
|
||||
imports.gi.versions.Gdk = '4.0';
|
||||
imports.gi.versions.Gtk = '4.0';
|
||||
imports.gi.versions.Soup = '2.4';
|
||||
imports.gi.versions.Soup = '3.0';
|
||||
|
||||
pkg.initGettext();
|
||||
pkg.initFormat();
|
||||
|
@@ -1,6 +0,0 @@
|
||||
const { Daemon } = imports.src.daemon;
|
||||
|
||||
function main()
|
||||
{
|
||||
new Daemon();
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
imports.gi.versions.Gdk = '4.0';
|
||||
imports.gi.versions.Gtk = '4.0';
|
||||
imports.gi.versions.Soup = '2.4';
|
||||
|
||||
pkg.initGettext();
|
||||
|
||||
const Misc = imports.src.misc;
|
||||
Misc.appId += '.Remote';
|
||||
|
||||
const { Gtk, Adw } = imports.gi;
|
||||
const { AppRemote } = imports.src.appRemote;
|
||||
|
||||
function main(argv)
|
||||
{
|
||||
Gtk.init();
|
||||
Adw.init();
|
||||
|
||||
new AppRemote().run(argv);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user