mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-29 23:32:04 +02:00
Compare commits
104 Commits
0.6
...
pipeline-p
Author | SHA1 | Date | |
---|---|---|---|
|
a6d6020c35 | ||
|
1eea63076c | ||
|
8e6599ae81 | ||
|
77ee519f8c | ||
|
c42e12d2be | ||
|
2b916ef856 | ||
|
303bda4d65 | ||
|
22430620a8 | ||
|
e4045b98b3 | ||
|
aa819cf2d3 | ||
|
a065b81846 | ||
|
9fbba4d66a | ||
|
ab659d0951 | ||
|
bd3ce28716 | ||
|
0a15e70d02 | ||
|
d42b17a749 | ||
|
719a4043b5 | ||
|
ee3d07b158 | ||
|
c8ef0f891d | ||
|
220913de14 | ||
|
2d1f6f471b | ||
|
af4a876edc | ||
|
14cdbef81c | ||
|
931dc255c1 | ||
|
2f39fef47b | ||
|
c05a6361b7 | ||
|
c152f3d791 | ||
|
f967e169b5 | ||
|
04a5bc8523 | ||
|
135be60497 | ||
|
736fddbe46 | ||
|
63f2fa1946 | ||
|
99708e1267 | ||
|
636e61ead1 | ||
|
147399afd8 | ||
|
2843a17879 | ||
|
bf0a8b68db | ||
|
af4ae2c942 | ||
|
c0221dedc8 | ||
|
9f54c1058c | ||
|
07f850d58a | ||
|
650b568319 | ||
|
abff579b70 | ||
|
0b253b41f6 | ||
|
d5832bd2db | ||
|
98371e822e | ||
|
3f2e5d569d | ||
|
f58e722002 | ||
|
262983e857 | ||
|
6ca1bccd1a | ||
|
c25cfd9598 | ||
|
3ce937c2b9 | ||
|
521a83bad0 | ||
|
d4598846d3 | ||
|
50d4fbe43b | ||
|
df371c698a | ||
|
2eaf5032cd | ||
|
28de283a98 | ||
|
ae6512b233 | ||
|
5049f620eb | ||
|
439e5831e2 | ||
|
6484599e46 | ||
|
333f8b4692 | ||
|
9b7c12c3d0 | ||
|
6fb25dd22b | ||
|
cc5c2b2403 | ||
|
71142ab0c6 | ||
|
cc8ed7b488 | ||
|
6f0ed93b08 | ||
|
10e0421342 | ||
|
bcd1d48922 | ||
|
aac050e252 | ||
|
1330e49ed8 | ||
|
22fb88d0f2 | ||
|
42b5acd967 | ||
|
8e14ec1697 | ||
|
a257d3f003 | ||
|
eb0baa6fe6 | ||
|
1001fda256 | ||
|
6edffb9a4b | ||
|
b013cb7405 | ||
|
07ca728b5b | ||
|
938cd44d7e | ||
|
8f4723906f | ||
|
419354fe8f | ||
|
4ec7349a04 | ||
|
03b2cb099f | ||
|
f67d5bef2e | ||
|
8f4107aab6 | ||
|
6941f1b042 | ||
|
df50802871 | ||
|
b1613273d0 | ||
|
35527e5c14 | ||
|
e060048969 | ||
|
09648bbc43 | ||
|
9e5f9e3d07 | ||
|
23c5e7ca65 | ||
|
6d47aa3c6d | ||
|
ae3d75a8b5 | ||
|
3561bc8c6f | ||
|
368a484741 | ||
|
b3ac64e5b1 | ||
|
c873c35fa7 | ||
|
af47dcb5e5 |
58
.github/workflows/documentation.yml
vendored
Normal file
58
.github/workflows/documentation.yml
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
name: "Documentation"
|
||||
jobs:
|
||||
documentation:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: registry.fedoraproject.org/fedora
|
||||
options: --privileged
|
||||
steps:
|
||||
- name: Prepare
|
||||
run: |
|
||||
dnf -y install git gcc meson glib2-devel \
|
||||
gstreamer1-devel gstreamer1-plugins-base-devel \
|
||||
gtk4-devel libsoup3-devel libmicrodns-devel \
|
||||
gobject-introspection-devel graphviz gi-docgen
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 0
|
||||
- name: Build
|
||||
run: |
|
||||
meson setup builddir -Dauto_features=enabled \
|
||||
-Denhancers-loader=disabled \
|
||||
-Dclapper-app=disabled -Dvapi=disabled -Ddoc=true \
|
||||
-Dglimporter=auto -Dgluploader=auto -Drawimporter=auto
|
||||
cd builddir
|
||||
meson compile
|
||||
- name: Commit files
|
||||
if: ${{ success() && github.ref == 'refs/heads/master' }}
|
||||
continue-on-error: true
|
||||
run: |
|
||||
git config --global --add safe.directory $GITHUB_WORKSPACE
|
||||
git checkout gh-pages
|
||||
rm -rf doc/clapper/*
|
||||
rm -rf doc/clapper-gtk/*
|
||||
mv builddir/doc/reference/clapper/clapper.toml doc/clapper/
|
||||
mv builddir/doc/reference/clapper/clapper/* doc/clapper/
|
||||
mv builddir/doc/reference/clapper-gtk/clapper-gtk.toml doc/clapper-gtk/
|
||||
mv builddir/doc/reference/clapper-gtk/clapper-gtk/* doc/clapper-gtk/
|
||||
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git config --local user.name "github-actions[bot]"
|
||||
git add doc/clapper/* doc/clapper-gtk/*
|
||||
git commit -m "doc: Update" || true
|
||||
- name: Push changes
|
||||
uses: ad-m/github-push-action@master
|
||||
if: ${{ success() && github.ref == 'refs/heads/master' }}
|
||||
continue-on-error: true
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
branch: gh-pages
|
4
.github/workflows/flatpak-nightly.yml
vendored
4
.github/workflows/flatpak-nightly.yml
vendored
@@ -30,8 +30,8 @@ jobs:
|
||||
platforms: arm64
|
||||
- name: Prepare Runtime
|
||||
run: |
|
||||
flatpak --system install -y --noninteractive flathub org.freedesktop.Sdk.Extension.rust-nightly/${{ matrix.arch }}/23.08
|
||||
flatpak --system install -y --noninteractive flathub org.freedesktop.Sdk.Extension.llvm16/${{ matrix.arch }}/23.08
|
||||
flatpak --system install -y --noninteractive flathub org.freedesktop.Sdk.Extension.rust-stable/${{ matrix.arch }}/24.08
|
||||
flatpak --system install -y --noninteractive flathub org.freedesktop.Sdk.Extension.llvm18/${{ matrix.arch }}/24.08
|
||||
- name: Build
|
||||
uses: bilelmoussaoui/flatpak-github-actions/flatpak-builder@v6
|
||||
with:
|
||||
|
90
.github/workflows/windows.yml
vendored
Normal file
90
.github/workflows/windows.yml
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
name: "Windows"
|
||||
jobs:
|
||||
windows:
|
||||
name: "Windows"
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [x86_64]
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup MSYS2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: MINGW64
|
||||
update: true
|
||||
install: |-
|
||||
mingw-w64-${{ matrix.arch }}-meson
|
||||
mingw-w64-${{ matrix.arch }}-gcc
|
||||
mingw-w64-${{ matrix.arch }}-glib2
|
||||
mingw-w64-${{ matrix.arch }}-gstreamer
|
||||
mingw-w64-${{ matrix.arch }}-gst-plugins-base
|
||||
mingw-w64-${{ matrix.arch }}-gst-plugins-good
|
||||
mingw-w64-${{ matrix.arch }}-gst-plugins-bad
|
||||
mingw-w64-${{ matrix.arch }}-gst-plugins-ugly
|
||||
mingw-w64-${{ matrix.arch }}-gst-libav
|
||||
mingw-w64-${{ matrix.arch }}-libpeas2
|
||||
mingw-w64-${{ matrix.arch }}-libsoup3
|
||||
mingw-w64-${{ matrix.arch }}-libmicrodns
|
||||
mingw-w64-${{ matrix.arch }}-gtk4
|
||||
mingw-w64-${{ matrix.arch }}-libadwaita
|
||||
- name: Prepare
|
||||
run: |
|
||||
BUILD_PREFIX="$GITHUB_WORKSPACE/clapper-win-${{ matrix.arch }}"
|
||||
|
||||
mkdir -p $BUILD_PREFIX/bin
|
||||
cp /mingw64/bin/gdbus.exe $BUILD_PREFIX/bin/
|
||||
cp /mingw64/bin/gst-inspect-1.0.exe $BUILD_PREFIX/bin/
|
||||
|
||||
mkdir -p $BUILD_PREFIX/lib
|
||||
cp -r /mingw64/lib/gio $BUILD_PREFIX/lib/
|
||||
cp -r /mingw64/lib/gstreamer-1.0 $BUILD_PREFIX/lib/
|
||||
cp -r /mingw64/lib/gdk-pixbuf-2.0 $BUILD_PREFIX/lib/
|
||||
|
||||
mkdir -p $BUILD_PREFIX/share/glib-2.0/schemas
|
||||
cp -r /mingw64/share/glib-2.0/schemas/*.xml $BUILD_PREFIX/share/glib-2.0/schemas/
|
||||
cp -r /mingw64/share/icons $BUILD_PREFIX/share/
|
||||
|
||||
mkdir -p $BUILD_PREFIX/share/xml/iso-codes
|
||||
cp /mingw64/share/xml/iso-codes/iso_639.xml $BUILD_PREFIX/share/xml/iso-codes/
|
||||
|
||||
cd "$BUILD_PREFIX/lib/gstreamer-1.0"
|
||||
rm -f \
|
||||
libgstadpcmenc.dll libgstamfcodec.dll libgstdvbsubenc.dll libgstencoding.dll \
|
||||
libgstfrei0r.dll libgstinter.dll libgstlame.dll libgstldac.dll libgstmpeg2enc.dll \
|
||||
libgstmpegpsmux.dll libgstmpegtsmux.dll libgstmplex.dll libgstrealmedia.dll \
|
||||
libgstsubenc.dll libgstsvtav1.dll libgstsvthevcenc.dll libgsttwolame.dll \
|
||||
libgstvoamrwbenc.dll libgstwavenc.dll libgstx264.dll libgstx265.dll \
|
||||
libgstxingmux.dll libgsty4menc.dll libgstzbar.dll
|
||||
- name: Build
|
||||
run: |
|
||||
meson setup builddir --prefix=$GITHUB_WORKSPACE/clapper-win-${{ matrix.arch }}
|
||||
cd builddir
|
||||
meson compile
|
||||
meson install
|
||||
- name: Package
|
||||
run: |
|
||||
BUILD_PREFIX="$GITHUB_WORKSPACE/clapper-win-${{ matrix.arch }}"
|
||||
|
||||
ldd $BUILD_PREFIX/bin/clapper.exe | grep '\/mingw.*\.dll' -o | xargs -I{} cp -n "{}" $BUILD_PREFIX/bin
|
||||
find $BUILD_PREFIX/lib/clapper-0.0/ -name '*\.dll' -type f -exec ldd "{}" \; | grep '\/mingw.*\.dll' -o | xargs -I{} cp -n "{}" $BUILD_PREFIX/bin
|
||||
find $BUILD_PREFIX/lib/gstreamer-1.0/ -name '*\.dll' -type f -exec ldd "{}" \; | grep '\/mingw.*\.dll' -o | xargs -I{} cp -n "{}" $BUILD_PREFIX/bin
|
||||
find $BUILD_PREFIX/lib/gio/ -name '*\.dll' -type f -exec ldd "{}" \; | grep '\/mingw.*\.dll' -o | xargs -I{} cp -n "{}" $BUILD_PREFIX/bin
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: clapper-win-${{ matrix.arch }}
|
||||
path: clapper-win-${{ matrix.arch }}
|
||||
if-no-files-found: error
|
@@ -31,6 +31,8 @@ Both libraries support *GObject Introspection* bindings. A simple application ex
|
||||
Above libraries are licensed under `LGPL-2.1-or-later`. You are free to use them in your own projects as long as you comply with license terms.
|
||||
Please note that until version 1.0 they should be considered as an unstable API (some things may change without prior notice).
|
||||
|
||||
Clapper `Vala` bindings are part of this repo, while `Rust` bindings can be found [here](https://gitlab.gnome.org/JanGernert/clapper-rs).
|
||||
|
||||
## Installation from Flatpak
|
||||
The `Flatpak` package includes all required dependencies and codecs.
|
||||
Additionally it also has a few patches, thus some functionalities work better in `Flatpak` version (until my changes are accepted upstream).
|
||||
@@ -54,6 +56,8 @@ meson compile
|
||||
sudo meson install
|
||||
```
|
||||
|
||||
If you want to compile app as `Flatpak`, remember to clone this repo with `--recurse-submodules` option.
|
||||
|
||||
## Questions?
|
||||
Feel free to ask me any questions. Come and talk on Matrix: [#clapper-player:matrix.org](https://matrix.to/#/#clapper-player:matrix.org)
|
||||
|
||||
@@ -68,5 +72,6 @@ so if your language is not available, please contact me first.
|
||||
Many thanks to [sp1ritCS](https://github.com/sp1ritCS) for creating and maintaining package build files.
|
||||
Big thanks to [bridadan](https://github.com/bridadan) and [Uniformbuffer3](https://github.com/Uniformbuffer3) for helping
|
||||
with testing V4L2 and NVDEC hardware acceleration methods.
|
||||
Also words of appreciation for [JanGernert](https://gitlab.gnome.org/JanGernert) who made and is sharing Clapper Rust bindings.
|
||||
|
||||
Thanks a lot to all the people who are supporting the development with their anonymous donations through [Liberapay](https://liberapay.com/Clapper/). I :heart: U.
|
||||
|
57
examples/clapper-gtk/download_cache/python/example.py
Executable file
57
examples/clapper-gtk/download_cache/python/example.py
Executable file
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import gi
|
||||
gi.require_version('Adw', '1')
|
||||
gi.require_version('Clapper', '0.0')
|
||||
gi.require_version('ClapperGtk', '0.0')
|
||||
gi.require_version('GLib', '2.0')
|
||||
gi.require_version('Gtk', '4.0')
|
||||
from gi.repository import Adw, Clapper, ClapperGtk, GLib, Gtk
|
||||
import shutil
|
||||
|
||||
Clapper.init(None)
|
||||
|
||||
download_dir = GLib.build_filenamev([GLib.get_user_cache_dir(), "example_download_dir", None])
|
||||
print('Using cache directory: {0}'.format(download_dir))
|
||||
|
||||
def on_download_complete(player, item, location):
|
||||
# Media downloaded. Data from this file is still used for current playback (including seeking).
|
||||
print('Download complete: {0} => {1}'.format(item.props.uri, location))
|
||||
|
||||
def on_activate(app):
|
||||
win = Gtk.ApplicationWindow(application=app, default_width=640, default_height=396)
|
||||
video = ClapperGtk.Video()
|
||||
controls = ClapperGtk.SimpleControls(fullscreenable=False)
|
||||
|
||||
# Enable local storage caching and monitor it
|
||||
video.props.player.set_download_dir(download_dir)
|
||||
video.props.player.set_download_enabled(True)
|
||||
video.props.player.connect('download-complete', on_download_complete)
|
||||
|
||||
# Configure playback
|
||||
video.props.player.props.queue.set_progression_mode(Clapper.QueueProgressionMode.CAROUSEL)
|
||||
video.props.player.set_autoplay(True)
|
||||
|
||||
# Assemble window
|
||||
video.add_fading_overlay(controls)
|
||||
win.set_child(video)
|
||||
win.present()
|
||||
|
||||
# Create and add media for playback
|
||||
item_1 = Clapper.MediaItem(uri='http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4')
|
||||
item_2 = Clapper.MediaItem(uri='http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4')
|
||||
video.props.player.props.queue.add_item(item_1)
|
||||
video.props.player.props.queue.add_item(item_2)
|
||||
|
||||
# Create a new application
|
||||
app = Adw.Application(application_id='com.example.ClapperDownloadCache')
|
||||
app.connect('activate', on_activate)
|
||||
|
||||
# Run the application
|
||||
app.run(None)
|
||||
|
||||
# Finally app should cleanup before exit. Possibly moving data to
|
||||
# another dir if it wants to use it on next run and deleting what's
|
||||
# left (so any unfinished downloads will also be removed).
|
||||
print('Cleanup')
|
||||
shutil.rmtree(download_dir)
|
45
examples/clapper-gtk/simple/python/example.py
Executable file
45
examples/clapper-gtk/simple/python/example.py
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import gi
|
||||
gi.require_version('Adw', '1')
|
||||
gi.require_version('Clapper', '0.0')
|
||||
gi.require_version('ClapperGtk', '0.0')
|
||||
gi.require_version('Gtk', '4.0')
|
||||
from gi.repository import Adw, Clapper, ClapperGtk, Gtk
|
||||
|
||||
Clapper.init(None)
|
||||
|
||||
def on_toggle_fullscreen(video, win):
|
||||
# Since this example uses only video inside normal window, all we
|
||||
# need to toggle fullscreen is to invert its fullscreened property
|
||||
win.props.fullscreened ^= True
|
||||
|
||||
def on_activate(app):
|
||||
win = Gtk.ApplicationWindow(application=app, default_width=640, default_height=396)
|
||||
video = ClapperGtk.Video()
|
||||
controls = ClapperGtk.SimpleControls()
|
||||
|
||||
# This signal will be emitted when user requests fullscreen state change.
|
||||
# It is app job to fullscreen video only (which might require something
|
||||
# more than simply inverting fullscreen on the whole window).
|
||||
video.connect('toggle-fullscreen', on_toggle_fullscreen, win)
|
||||
|
||||
# Create and add media for playback. First added media item to empty
|
||||
# playback queue will be automatically selected.
|
||||
item = Clapper.MediaItem(uri='http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4')
|
||||
video.props.player.props.queue.add_item(item)
|
||||
|
||||
# Assemble window
|
||||
video.add_fading_overlay(controls)
|
||||
win.set_child(video)
|
||||
win.present()
|
||||
|
||||
# Start playback
|
||||
video.props.player.play()
|
||||
|
||||
# Create a new application
|
||||
app = Adw.Application(application_id='com.example.ClapperSimple')
|
||||
app.connect('activate', on_activate)
|
||||
|
||||
# Run the application
|
||||
app.run(None)
|
12
meson.build
12
meson.build
@@ -1,5 +1,5 @@
|
||||
project('clapper', 'c',
|
||||
version: '0.6.1',
|
||||
version: '0.7.0',
|
||||
meson_version: '>= 0.64.0',
|
||||
license: 'LGPL-2.1-or-later AND GPL-3.0-or-later', # LGPL-2.1+ for libs and gst-plugin, GPL-3.0+ for app
|
||||
default_options: [
|
||||
@@ -9,7 +9,7 @@ project('clapper', 'c',
|
||||
)
|
||||
|
||||
glib_req = '>= 2.76.0'
|
||||
gst_req = '>= 1.20.0'
|
||||
gst_req = '>= 1.24.0'
|
||||
gtk4_req = '>= 4.10.0'
|
||||
adw_req = '>= 1.4.0'
|
||||
|
||||
@@ -85,6 +85,11 @@ libadwaita_dep = dependency('libadwaita-1',
|
||||
required: false,
|
||||
)
|
||||
|
||||
# Optional
|
||||
peas_dep = dependency('libpeas-2',
|
||||
required: false,
|
||||
)
|
||||
|
||||
cc = meson.get_compiler('c')
|
||||
libm = cc.find_library('m', required: false)
|
||||
|
||||
@@ -147,6 +152,9 @@ summary('vapi', build_vapi ? 'Yes' : 'No', section: 'Build')
|
||||
summary('doc', build_doc ? 'Yes' : 'No', section: 'Build')
|
||||
|
||||
if build_clapper
|
||||
foreach name : clapper_possible_functionalities
|
||||
summary(name, clapper_available_functionalities.contains(name) ? 'Yes' : 'No', section: 'Functionalities')
|
||||
endforeach
|
||||
foreach name : clapper_possible_features
|
||||
summary(name, clapper_available_features.contains(name) ? 'Yes' : 'No', section: 'Features')
|
||||
endforeach
|
||||
|
@@ -35,6 +35,13 @@ option('doc',
|
||||
description: 'Build documentation'
|
||||
)
|
||||
|
||||
# Functionalities
|
||||
option('enhancers-loader',
|
||||
type: 'feature',
|
||||
value: 'enabled',
|
||||
description: 'Ability to load libpeas based plugins that enhance capabilities'
|
||||
)
|
||||
|
||||
# Features
|
||||
option('discoverer',
|
||||
type: 'feature',
|
||||
|
@@ -4,12 +4,12 @@
|
||||
"runtime-version": "master",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"sdk-extensions": [
|
||||
"org.freedesktop.Sdk.Extension.rust-nightly",
|
||||
"org.freedesktop.Sdk.Extension.llvm16"
|
||||
"org.freedesktop.Sdk.Extension.rust-stable",
|
||||
"org.freedesktop.Sdk.Extension.llvm18"
|
||||
],
|
||||
"add-extensions": {
|
||||
"org.freedesktop.Platform.ffmpeg-full": {
|
||||
"version": "23.08",
|
||||
"version": "24.08",
|
||||
"directory": "lib/ffmpeg",
|
||||
"add-ld-path": ".",
|
||||
"no-autodownload": false,
|
||||
@@ -29,13 +29,19 @@
|
||||
"--filesystem=xdg-run/pipewire-0:ro",
|
||||
"--filesystem=xdg-videos",
|
||||
"--filesystem=xdg-run/gvfsd",
|
||||
"--own-name=org.mpris.MediaPlayer2.Clapper",
|
||||
"--own-name=org.mpris.MediaPlayer2.Clapper.*",
|
||||
"--talk-name=org.gtk.vfs.*",
|
||||
"--env=GST_PLUGIN_SYSTEM_PATH=/app/lib/gstreamer-1.0"
|
||||
],
|
||||
"build-options": {
|
||||
"append-path": "/usr/lib/sdk/rust-nightly/bin:/usr/lib/sdk/llvm16/bin",
|
||||
"prepend-ld-library-path": "/usr/lib/sdk/llvm16/lib"
|
||||
"append-path": "/usr/lib/sdk/rust-stable/bin:/usr/lib/sdk/llvm18/bin",
|
||||
"prepend-ld-library-path": "/usr/lib/sdk/llvm18/lib",
|
||||
"env": {
|
||||
"CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER": "clang",
|
||||
"CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS": "-C link-arg=-fuse-ld=/usr/lib/sdk/rust-stable/bin/mold",
|
||||
"CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER": "clang",
|
||||
"CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS": "-C link-arg=-fuse-ld=/usr/lib/sdk/rust-stable/bin/mold"
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
"flathub/shared-modules/gudev/gudev.json",
|
||||
@@ -50,7 +56,8 @@
|
||||
"testing/dav1d.json",
|
||||
"testing/gstreamer.json",
|
||||
"testing/gst-plugins-rs.json",
|
||||
"testing/gtuber.json",
|
||||
"testing/yt-dlp.json",
|
||||
"testing/libpeas.json",
|
||||
{
|
||||
"name": "clapper",
|
||||
"buildsystem": "meson",
|
||||
@@ -60,7 +67,8 @@
|
||||
"path": "../../."
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"testing/clapper-enhancers.json"
|
||||
],
|
||||
"cleanup-commands": [
|
||||
"mkdir -p /app/lib/ffmpeg",
|
||||
|
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"app-id": "com.github.rafostar.Clapper",
|
||||
"runtime": "org.gnome.Platform",
|
||||
"runtime-version": "45",
|
||||
"runtime-version": "47",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"add-extensions": {
|
||||
"org.freedesktop.Platform.ffmpeg-full": {
|
||||
"version": "23.08",
|
||||
"version": "24.08",
|
||||
"directory": "lib/ffmpeg",
|
||||
"add-ld-path": ".",
|
||||
"no-autodownload": false,
|
||||
@@ -25,7 +25,7 @@
|
||||
"--filesystem=xdg-run/pipewire-0:ro",
|
||||
"--filesystem=xdg-videos",
|
||||
"--filesystem=xdg-run/gvfsd",
|
||||
"--own-name=org.mpris.MediaPlayer2.Clapper",
|
||||
"--own-name=org.mpris.MediaPlayer2.Clapper.*",
|
||||
"--talk-name=org.gtk.vfs.*",
|
||||
"--env=GST_PLUGIN_SYSTEM_PATH=/app/lib/gstreamer-1.0"
|
||||
],
|
||||
@@ -40,21 +40,20 @@
|
||||
"flathub/lib/libass.json",
|
||||
"flathub/lib/uchardet.json",
|
||||
"flathub/lib/libmicrodns.json",
|
||||
"flathub/gstreamer-1.0/gstreamer.json",
|
||||
"testing/gtuber.json",
|
||||
"testing/gstreamer_stable.json",
|
||||
"testing/yt-dlp.json",
|
||||
"testing/libpeas.json",
|
||||
{
|
||||
"name": "clapper",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"-Dc_args=\"-DHAVE_GST_PATCHES=1\""
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "dir",
|
||||
"path": "../../."
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"testing/clapper-enhancers.json"
|
||||
],
|
||||
"cleanup-commands": [
|
||||
"mkdir -p /app/lib/ffmpeg",
|
||||
|
14
pkgs/flatpak/testing/clapper-enhancers.json
Normal file
14
pkgs/flatpak/testing/clapper-enhancers.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "clapper-enhancers",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"-Dauto_features=enabled"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/Rafostar/clapper-enhancers.git",
|
||||
"branch": "main"
|
||||
}
|
||||
]
|
||||
}
|
99
pkgs/flatpak/testing/gstreamer_stable.json
Normal file
99
pkgs/flatpak/testing/gstreamer_stable.json
Normal file
@@ -0,0 +1,99 @@
|
||||
{
|
||||
"name": "gstreamer",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"--buildtype=release",
|
||||
"--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",
|
||||
"-Dgstreamer:gobject-cast-checks=disabled",
|
||||
"-Dgstreamer:glib-asserts=disabled",
|
||||
"-Dgstreamer:glib-checks=disabled",
|
||||
"-Dgstreamer:extra-checks=disabled",
|
||||
|
||||
"-Dgst-plugins-base:gobject-cast-checks=disabled",
|
||||
"-Dgst-plugins-base:glib-asserts=disabled",
|
||||
"-Dgst-plugins-base:glib-checks=disabled",
|
||||
"-Dgst-plugins-base:gl_api=opengl,gles2",
|
||||
"-Dgst-plugins-base:gl_platform=egl,glx",
|
||||
|
||||
"-Dgst-plugins-good:gobject-cast-checks=disabled",
|
||||
"-Dgst-plugins-good:glib-asserts=disabled",
|
||||
"-Dgst-plugins-good:glib-checks=disabled",
|
||||
"-Dgst-plugins-good:gtk3=disabled",
|
||||
|
||||
"-Dgst-plugins-bad:gobject-cast-checks=disabled",
|
||||
"-Dgst-plugins-bad:glib-asserts=disabled",
|
||||
"-Dgst-plugins-bad:glib-checks=disabled",
|
||||
"-Dgst-plugins-bad:extra-checks=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:gobject-cast-checks=disabled",
|
||||
"-Dgst-plugins-ugly:glib-asserts=disabled",
|
||||
"-Dgst-plugins-ugly:glib-checks=disabled",
|
||||
"-Dgst-plugins-ugly:mpeg2dec=enabled"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.freedesktop.org/gstreamer/gstreamer.git",
|
||||
"tag": "1.24.9",
|
||||
"commit": "b309f90bfde36e6d175b70bfa0c941f2829dd6a5",
|
||||
"disable-submodules": true
|
||||
},
|
||||
{
|
||||
"type": "patch",
|
||||
"path": "../flathub/gstreamer-1.0/gst-libav-stop-caching-codecs.patch"
|
||||
},
|
||||
{
|
||||
"type": "patch",
|
||||
"path": "../flathub/gstreamer-1.0/gst-plugins-base-autodetect-subtitle-text-encoding.patch"
|
||||
},
|
||||
{
|
||||
"type": "patch",
|
||||
"path": "../flathub/gstreamer-1.0/gst-plugins-good-matroska-fix-attachments-detection.patch"
|
||||
},
|
||||
{
|
||||
"type": "patch",
|
||||
"path": "../flathub/gstreamer-1.0/gst-plugins-good-dashdemux2-play-last-subfragment.patch"
|
||||
},
|
||||
{
|
||||
"type": "patch",
|
||||
"path": "../flathub/gstreamer-1.0/gst-plugins-bad-dashdemux-sidx-range-download.patch"
|
||||
},
|
||||
{
|
||||
"type": "patch",
|
||||
"path": "../flathub/gstreamer-1.0/gst-plugins-bad-dashdemux-improve-initial-representation-selection.patch"
|
||||
}
|
||||
]
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
21
pkgs/flatpak/testing/libpeas.json
Normal file
21
pkgs/flatpak/testing/libpeas.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "libpeas",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"--wrap-mode=nodownload",
|
||||
"-Dgjs=false",
|
||||
"-Dlua51=false",
|
||||
"-Dintrospection=false"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://download.gnome.org/sources/libpeas/2.0/libpeas-2.0.5.tar.xz",
|
||||
"sha256": "376f2f73d731b54e13ddbab1d91b6382cf6a980524def44df62add15489de6dd",
|
||||
"x-checker-data": {
|
||||
"type": "gnome",
|
||||
"name": "libpeas"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
19
pkgs/flatpak/testing/yt-dlp.json
Normal file
19
pkgs/flatpak/testing/yt-dlp.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "yt-dlp",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": [
|
||||
"pip3 install -v --root-user-action=ignore --no-deps --prefix=/app *.whl"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/bb/68/548f9819b41d53561d4f3d39588111cf39993c066b6e5300b4ae118eb2e6/yt_dlp-2024.10.22-py3-none-any.whl",
|
||||
"sha256": "ba166602ebe22a220e4dc1ead45bf00eb469ed812b22f4fb8bb54734f9b02084",
|
||||
"x-checker-data": {
|
||||
"type": "pypi",
|
||||
"name": "yt-dlp",
|
||||
"packagetype": "bdist_wheel"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gst/gst.h>
|
||||
#include <clapper/clapper.h>
|
||||
#include <adwaita.h>
|
||||
|
||||
#include "clapper-app-about-window.h"
|
||||
@@ -39,6 +40,9 @@ clapper_app_about_window_new (GtkApplication *gtk_app)
|
||||
gtk_window_set_modal (GTK_WINDOW (about), TRUE);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (about), window);
|
||||
|
||||
/* Also show development versions */
|
||||
adw_about_window_set_version (about, CLAPPER_VERSION_S);
|
||||
|
||||
/* TRANSLATORS: Put your name(s) here for credits or leave untranslated */
|
||||
adw_about_window_set_translator_credits (about, _("translator-credits"));
|
||||
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gst/gst.h>
|
||||
#include <clapper-gtk/clapper-gtk.h>
|
||||
|
||||
@@ -26,6 +27,7 @@
|
||||
#include "clapper-app-file-dialog.h"
|
||||
#include "clapper-app-uri-dialog.h"
|
||||
#include "clapper-app-info-window.h"
|
||||
#include "clapper-app-pipeline-window.h"
|
||||
#include "clapper-app-preferences-window.h"
|
||||
#include "clapper-app-about-window.h"
|
||||
#include "clapper-app-utils.h"
|
||||
@@ -44,6 +46,9 @@ struct _ClapperAppApplication
|
||||
gboolean need_init_state;
|
||||
};
|
||||
|
||||
#define parent_class clapper_app_application_parent_class
|
||||
G_DEFINE_TYPE (ClapperAppApplication, clapper_app_application, GTK_TYPE_APPLICATION);
|
||||
|
||||
struct ClapperPluginFeatureData
|
||||
{
|
||||
const gchar *name;
|
||||
@@ -63,8 +68,147 @@ typedef struct
|
||||
const gchar *accels[3];
|
||||
} ClapperAppShortcut;
|
||||
|
||||
#define parent_class clapper_app_application_parent_class
|
||||
G_DEFINE_TYPE (ClapperAppApplication, clapper_app_application, GTK_TYPE_APPLICATION);
|
||||
static gboolean
|
||||
clapper_app_options_get (const gchar *key, const gchar *format, GVariantDict *options,
|
||||
GObject *src_object, GSettings *settings, gpointer output)
|
||||
{
|
||||
if (options && g_variant_dict_lookup (options, key, format, output)) {
|
||||
return TRUE;
|
||||
} else if (src_object) {
|
||||
g_object_get (src_object, key, output, NULL);
|
||||
return TRUE;
|
||||
} else if (settings) {
|
||||
g_settings_get (settings, key, format, output);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clapper_app_options_get_extra (const gchar *key, GVariantDict *options,
|
||||
const gchar *extra_value, GSettings *settings, gchar **output)
|
||||
{
|
||||
if (options && g_variant_dict_lookup (options, key, "s", output)) {
|
||||
return TRUE;
|
||||
} else if (extra_value) {
|
||||
*output = g_strdup (extra_value);
|
||||
return TRUE;
|
||||
} else if (settings) {
|
||||
*output = g_settings_get_string (settings, key);
|
||||
|
||||
/* Ensure non-empty string */
|
||||
if (*output) {
|
||||
if (strlen (*output) > 0)
|
||||
return TRUE;
|
||||
else
|
||||
g_clear_pointer (output, g_free);
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply options to @dest_window. Option providers will be used in args order.
|
||||
* If any arg is %NULL it will not be used. For example, passing %NULL as
|
||||
* @settings will avoid restoring values to @dest_window from GSettings.
|
||||
*/
|
||||
static void
|
||||
clapper_app_apply_options_to_window (ClapperAppWindow *dest_window, GVariantDict *options,
|
||||
ClapperAppWindow *src_window, GSettings *settings)
|
||||
{
|
||||
ClapperPlayer *dest_player;
|
||||
ClapperAppWindowExtraOptions *src_extra_opts = NULL, *dest_extra_opts = NULL;
|
||||
GObject *src_player_obj = NULL;
|
||||
GObject *src_queue_obj = NULL;
|
||||
gchar *option_str;
|
||||
gdouble option_dbl;
|
||||
gint option_int;
|
||||
gboolean option_bool;
|
||||
|
||||
GST_DEBUG ("Applying options to window: %p", dest_window);
|
||||
|
||||
dest_player = clapper_app_window_get_player (dest_window);
|
||||
dest_extra_opts = clapper_app_window_get_extra_options (dest_window);
|
||||
|
||||
if (src_window) {
|
||||
src_player_obj = (GObject *) clapper_app_window_get_player (src_window);
|
||||
src_queue_obj = (GObject *) clapper_player_get_queue (CLAPPER_PLAYER_CAST (src_player_obj));
|
||||
src_extra_opts = clapper_app_window_get_extra_options (src_window);
|
||||
}
|
||||
|
||||
/* Apply player values, clamp them to be within allowed range */
|
||||
if (clapper_app_options_get ("volume", "d", options, src_player_obj, settings, &option_dbl))
|
||||
clapper_player_set_volume (dest_player, PERCENTAGE_ROUND (CLAMP (option_dbl, 0, 2.0)));
|
||||
if (clapper_app_options_get ("mute", "b", NULL, src_player_obj, settings, &option_bool))
|
||||
clapper_player_set_mute (dest_player, option_bool);
|
||||
if (clapper_app_options_get ("speed", "d", options, src_player_obj, settings, &option_dbl))
|
||||
clapper_player_set_speed (dest_player, PERCENTAGE_ROUND (CLAMP (option_dbl, 0.05, 2.0)));
|
||||
if (clapper_app_options_get ("adaptive-start-bitrate", "i", options, src_player_obj, settings, &option_int))
|
||||
clapper_player_set_adaptive_start_bitrate (dest_player, option_int);
|
||||
if (clapper_app_options_get ("progression-mode", "i", options, src_queue_obj, settings, &option_int))
|
||||
clapper_queue_set_progression_mode (clapper_player_get_queue (dest_player), CLAMP (option_int, 0, 4));
|
||||
if (clapper_app_options_get ("subtitles-enabled", "b", NULL, src_player_obj, settings, &option_bool))
|
||||
clapper_player_set_subtitles_enabled (dest_player, option_bool);
|
||||
|
||||
if (clapper_app_options_get_extra ("video-filter", options,
|
||||
(src_extra_opts) ? src_extra_opts->video_filter : NULL, NULL, &option_str)) {
|
||||
clapper_player_set_video_filter (dest_player, clapper_app_utils_make_element (option_str));
|
||||
g_free (dest_extra_opts->video_filter);
|
||||
dest_extra_opts->video_filter = option_str;
|
||||
}
|
||||
if (clapper_app_options_get_extra ("audio-filter", options,
|
||||
(src_extra_opts) ? src_extra_opts->audio_filter : NULL, NULL, &option_str)) {
|
||||
clapper_player_set_audio_filter (dest_player, clapper_app_utils_make_element (option_str));
|
||||
g_free (dest_extra_opts->audio_filter);
|
||||
dest_extra_opts->audio_filter = option_str;
|
||||
}
|
||||
if (clapper_app_options_get_extra ("video-sink", options,
|
||||
(src_extra_opts) ? src_extra_opts->video_sink : NULL, NULL, &option_str)) {
|
||||
clapper_player_set_video_sink (dest_player, clapper_app_utils_make_element (option_str));
|
||||
g_free (dest_extra_opts->video_sink);
|
||||
dest_extra_opts->video_sink = option_str;
|
||||
}
|
||||
if (clapper_app_options_get_extra ("audio-sink", options,
|
||||
(src_extra_opts) ? src_extra_opts->audio_sink : NULL, NULL, &option_str)) {
|
||||
clapper_player_set_audio_sink (dest_player, clapper_app_utils_make_element (option_str));
|
||||
g_free (dest_extra_opts->audio_sink);
|
||||
dest_extra_opts->audio_sink = option_str;
|
||||
}
|
||||
|
||||
/* Apply window options */
|
||||
if ((options && g_variant_dict_contains (options, "fullscreen"))
|
||||
|| (settings && g_settings_get_boolean (settings, "fullscreened")))
|
||||
gtk_window_fullscreen (GTK_WINDOW (dest_window));
|
||||
else if (settings && g_settings_get_boolean (settings, "maximized"))
|
||||
gtk_window_maximize (GTK_WINDOW (dest_window));
|
||||
|
||||
GST_DEBUG ("Options applied");
|
||||
}
|
||||
|
||||
static inline void
|
||||
_store_settings_from_window (ClapperAppApplication *self, ClapperAppWindow *app_window)
|
||||
{
|
||||
ClapperPlayer *player = clapper_app_window_get_player (app_window);
|
||||
ClapperQueue *queue = clapper_player_get_queue (player);
|
||||
GtkWindow *window = GTK_WINDOW (app_window);
|
||||
|
||||
GST_DEBUG ("Storing current configuration to GSettings");
|
||||
|
||||
g_settings_set_double (self->settings, "volume", clapper_player_get_volume (player));
|
||||
g_settings_set_boolean (self->settings, "mute", clapper_player_get_mute (player));
|
||||
g_settings_set_double (self->settings, "speed", clapper_player_get_speed (player));
|
||||
g_settings_set_int (self->settings, "adaptive-start-bitrate",
|
||||
CLAMP (clapper_player_get_adaptive_bandwidth (player) * 0.8, 0, G_MAXINT));
|
||||
g_settings_set_boolean (self->settings, "subtitles-enabled", clapper_player_get_subtitles_enabled (player));
|
||||
g_settings_set_int (self->settings, "progression-mode", clapper_queue_get_progression_mode (queue));
|
||||
|
||||
g_settings_set_boolean (self->settings, "maximized", gtk_window_is_maximized (window));
|
||||
g_settings_set_boolean (self->settings, "fullscreened", gtk_window_is_fullscreen (window));
|
||||
|
||||
GST_DEBUG ("Configuration stored");
|
||||
}
|
||||
|
||||
static inline void
|
||||
_set_initial_plugin_feature_ranks (void)
|
||||
@@ -190,6 +334,26 @@ add_uri (GSimpleAction *action, GVariant *param, gpointer user_data)
|
||||
clapper_app_uri_dialog_open_uri (gtk_app);
|
||||
}
|
||||
|
||||
static void
|
||||
new_window (GSimpleAction *action, GVariant *param, gpointer user_data)
|
||||
{
|
||||
GtkApplication *gtk_app = GTK_APPLICATION (user_data);
|
||||
GtkWidget *stack = gtk_window_get_child (gtk_application_get_active_window (gtk_app));
|
||||
const gchar *child_name = gtk_stack_get_visible_child_name (GTK_STACK (stack));
|
||||
|
||||
/* Do not allow to open new windows during initial state,
|
||||
* there already is a free one to use */
|
||||
if (g_strcmp0 (child_name, "initial_state") != 0) {
|
||||
ClapperAppWindow *src_window, *dest_window;
|
||||
|
||||
src_window = CLAPPER_APP_WINDOW_CAST (gtk_application_get_active_window (gtk_app));
|
||||
dest_window = CLAPPER_APP_WINDOW_CAST (clapper_app_window_new (gtk_app));
|
||||
|
||||
clapper_app_apply_options_to_window (dest_window, NULL, src_window, NULL);
|
||||
gtk_window_present (GTK_WINDOW (dest_window));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
show_preferences (GSimpleAction *action, GVariant *param, gpointer user_data)
|
||||
{
|
||||
@@ -215,6 +379,32 @@ show_info (GSimpleAction *action, GVariant *param, gpointer user_data)
|
||||
gtk_window_present (GTK_WINDOW (info_window));
|
||||
}
|
||||
|
||||
static void
|
||||
show_pipeline (GSimpleAction *action, GVariant *param, gpointer user_data)
|
||||
{
|
||||
GtkApplication *gtk_app = GTK_APPLICATION (user_data);
|
||||
GtkWidget *pipeline_window;
|
||||
GtkWindow *window;
|
||||
ClapperPlayer *player;
|
||||
|
||||
window = gtk_application_get_active_window (gtk_app);
|
||||
|
||||
/* Already open */
|
||||
if (CLAPPER_APP_IS_PIPELINE_WINDOW (window))
|
||||
return;
|
||||
|
||||
while (window && !CLAPPER_APP_IS_WINDOW (window))
|
||||
window = gtk_window_get_transient_for (window);
|
||||
|
||||
if (G_UNLIKELY (window == NULL))
|
||||
return;
|
||||
|
||||
player = clapper_app_window_get_player (CLAPPER_APP_WINDOW (window));
|
||||
|
||||
pipeline_window = clapper_app_pipeline_window_new (gtk_app, player);
|
||||
gtk_window_present (GTK_WINDOW (pipeline_window));
|
||||
}
|
||||
|
||||
static void
|
||||
show_about (GSimpleAction *action, GVariant *param, gpointer user_data)
|
||||
{
|
||||
@@ -225,55 +415,12 @@ show_about (GSimpleAction *action, GVariant *param, gpointer user_data)
|
||||
gtk_window_present (GTK_WINDOW (about_window));
|
||||
}
|
||||
|
||||
static inline void
|
||||
_restore_settings_to_window (ClapperAppApplication *self, ClapperAppWindow *app_window)
|
||||
{
|
||||
ClapperPlayer *player = clapper_app_window_get_player (app_window);
|
||||
ClapperQueue *queue = clapper_player_get_queue (player);
|
||||
|
||||
GST_DEBUG ("Restoring saved GSettings values to: %" GST_PTR_FORMAT, app_window);
|
||||
|
||||
clapper_player_set_volume (player, PERCENTAGE_ROUND (g_settings_get_double (self->settings, "volume")));
|
||||
clapper_player_set_mute (player, g_settings_get_boolean (self->settings, "mute"));
|
||||
clapper_player_set_speed (player, PERCENTAGE_ROUND (g_settings_get_double (self->settings, "speed")));
|
||||
clapper_player_set_subtitles_enabled (player, g_settings_get_boolean (self->settings, "subtitles-enabled"));
|
||||
clapper_queue_set_progression_mode (queue, g_settings_get_int (self->settings, "progression-mode"));
|
||||
|
||||
if (g_settings_get_boolean (self->settings, "fullscreened"))
|
||||
gtk_window_fullscreen (GTK_WINDOW (app_window));
|
||||
else if (g_settings_get_boolean (self->settings, "maximized"))
|
||||
gtk_window_maximize (GTK_WINDOW (app_window));
|
||||
|
||||
GST_DEBUG ("Configuration restored");
|
||||
}
|
||||
|
||||
static inline void
|
||||
_store_settings_from_window (ClapperAppApplication *self, ClapperAppWindow *app_window)
|
||||
{
|
||||
ClapperPlayer *player = clapper_app_window_get_player (app_window);
|
||||
ClapperQueue *queue = clapper_player_get_queue (player);
|
||||
GtkWindow *window = GTK_WINDOW (app_window);
|
||||
|
||||
GST_DEBUG ("Storing current configuration to GSettings");
|
||||
|
||||
g_settings_set_double (self->settings, "volume", clapper_player_get_volume (player));
|
||||
g_settings_set_boolean (self->settings, "mute", clapper_player_get_mute (player));
|
||||
g_settings_set_double (self->settings, "speed", clapper_player_get_speed (player));
|
||||
g_settings_set_boolean (self->settings, "subtitles-enabled", clapper_player_get_subtitles_enabled (player));
|
||||
g_settings_set_int (self->settings, "progression-mode", clapper_queue_get_progression_mode (queue));
|
||||
|
||||
g_settings_set_boolean (self->settings, "maximized", gtk_window_is_maximized (window));
|
||||
g_settings_set_boolean (self->settings, "fullscreened", gtk_window_is_fullscreen (window));
|
||||
|
||||
GST_DEBUG ("Configuration stored");
|
||||
}
|
||||
|
||||
GApplication *
|
||||
clapper_app_application_new (void)
|
||||
{
|
||||
return g_object_new (CLAPPER_APP_TYPE_APPLICATION,
|
||||
"application-id", CLAPPER_APP_ID,
|
||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||
"flags", G_APPLICATION_HANDLES_OPEN | G_APPLICATION_HANDLES_COMMAND_LINE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
@@ -306,14 +453,18 @@ static void
|
||||
clapper_app_application_activate (GApplication *app)
|
||||
{
|
||||
ClapperAppApplication *self = CLAPPER_APP_APPLICATION_CAST (app);
|
||||
GtkApplication *gtk_app = GTK_APPLICATION (app);
|
||||
GtkWindow *window;
|
||||
|
||||
GST_INFO ("Activate");
|
||||
G_APPLICATION_CLASS (parent_class)->activate (app);
|
||||
|
||||
if (!(window = gtk_application_get_active_window (GTK_APPLICATION (app)))) {
|
||||
window = GTK_WINDOW (clapper_app_window_new (GTK_APPLICATION (app)));
|
||||
_restore_settings_to_window (self, CLAPPER_APP_WINDOW_CAST (window));
|
||||
/* When activated through DBus command line does not run,
|
||||
* so create our first window here instead */
|
||||
if (!(window = gtk_application_get_active_window (gtk_app))) {
|
||||
window = GTK_WINDOW (clapper_app_window_new (gtk_app));
|
||||
clapper_app_apply_options_to_window (CLAPPER_APP_WINDOW_CAST (window),
|
||||
NULL, NULL, self->settings);
|
||||
}
|
||||
|
||||
if (self->need_init_state) {
|
||||
@@ -331,6 +482,8 @@ clapper_app_application_local_command_line (GApplication *app,
|
||||
gchar **argv = *arguments;
|
||||
guint i;
|
||||
|
||||
GST_INFO ("Handling local command line");
|
||||
|
||||
/* NOTE: argv is never NULL, so no need to check */
|
||||
|
||||
for (i = 0; argv[i]; ++i) {
|
||||
@@ -344,6 +497,43 @@ clapper_app_application_local_command_line (GApplication *app,
|
||||
return G_APPLICATION_CLASS (parent_class)->local_command_line (app, arguments, exit_status);
|
||||
}
|
||||
|
||||
static gint
|
||||
clapper_app_application_command_line (GApplication *app, GApplicationCommandLine *cmd_line)
|
||||
{
|
||||
ClapperAppApplication *self = CLAPPER_APP_APPLICATION_CAST (app);
|
||||
ClapperAppWindow *src_window = NULL, *dest_window = NULL;
|
||||
GtkApplication *gtk_app = GTK_APPLICATION (app);
|
||||
GVariantDict *options;
|
||||
GFile **files = NULL;
|
||||
GSettings *settings;
|
||||
gint n_files = 0;
|
||||
|
||||
GST_INFO ("Handling command line");
|
||||
|
||||
options = g_application_command_line_get_options_dict (cmd_line);
|
||||
dest_window = CLAPPER_APP_WINDOW_CAST (gtk_application_get_active_window (gtk_app));
|
||||
|
||||
/* Restore settings only once by making them %NULL when run again */
|
||||
settings = (!dest_window) ? self->settings : NULL;
|
||||
|
||||
if (!dest_window || g_variant_dict_contains (options, "new-window")) {
|
||||
src_window = dest_window;
|
||||
dest_window = CLAPPER_APP_WINDOW_CAST (clapper_app_window_new (gtk_app));
|
||||
}
|
||||
|
||||
clapper_app_apply_options_to_window (dest_window, options, src_window, settings);
|
||||
|
||||
if (clapper_app_utils_files_from_command_line (cmd_line, &files, &n_files)) {
|
||||
g_application_open (app, files, n_files,
|
||||
(g_variant_dict_contains (options, "enqueue")) ? "add-only" : "");
|
||||
clapper_app_utils_files_free (files);
|
||||
} else {
|
||||
g_application_activate (app);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_is_claps_file (GFile *file)
|
||||
{
|
||||
@@ -512,20 +702,40 @@ clapper_app_application_constructed (GObject *object)
|
||||
GApplication *app = G_APPLICATION (self);
|
||||
guint i;
|
||||
|
||||
static const GActionEntry app_entries[] = {
|
||||
const GOptionEntry app_options[] = {
|
||||
{ "new-window", 'n', 0, G_OPTION_ARG_NONE, NULL, _("Create a new window"), NULL },
|
||||
{ "enqueue", 0, 0, G_OPTION_ARG_NONE, NULL, _("Add media to queue in primary application instance"), NULL },
|
||||
{ "volume", 0, 0, G_OPTION_ARG_DOUBLE, NULL, _("Audio volume to set (0 - 2.0 range)"), NULL },
|
||||
{ "speed", 0, 0, G_OPTION_ARG_DOUBLE, NULL, _("Playback speed to set (0.05 - 2.0 range)"), NULL },
|
||||
{ "adaptive-start-bitrate", 0, 0, G_OPTION_ARG_INT, NULL, _("Initial bitrate for adaptive streaming"), NULL },
|
||||
{ "progression-mode", 0, 0, G_OPTION_ARG_INT, NULL, _("Initial queue progression mode (0=none, 1=consecutive, 2=repeat-item, 3=carousel, 4=shuffle)"), NULL },
|
||||
{ "fullscreen", 'f', 0, G_OPTION_ARG_NONE, NULL, _("Set window to be fullscreen"), NULL },
|
||||
{ "video-filter", 0, 0, G_OPTION_ARG_STRING, NULL, _("Video filter to use (\"none\" to disable)"), NULL },
|
||||
{ "audio-filter", 0, 0, G_OPTION_ARG_STRING, NULL, _("Audio filter to use (\"none\" to disable)"), NULL },
|
||||
{ "video-sink", 0, 0, G_OPTION_ARG_STRING, NULL, _("Video sink to use"), NULL },
|
||||
{ "audio-sink", 0, 0, G_OPTION_ARG_STRING, NULL, _("Audio sink to use"), NULL },
|
||||
{ NULL }
|
||||
};
|
||||
static const GActionEntry app_actions[] = {
|
||||
{ "add-files", add_files, NULL, NULL, NULL },
|
||||
{ "add-uri", add_uri, NULL, NULL, NULL },
|
||||
{ "new-window", new_window, NULL, NULL, NULL },
|
||||
{ "info", show_info, NULL, NULL, NULL },
|
||||
{ "pipeline", show_pipeline, NULL, NULL, NULL },
|
||||
{ "preferences", show_preferences, NULL, NULL, NULL },
|
||||
{ "about", show_about, NULL, NULL, NULL },
|
||||
};
|
||||
static const ClapperAppShortcut app_shortcuts[] = {
|
||||
{ "app.add-files", { "<Control>o", NULL, NULL }},
|
||||
{ "app.add-uri", { "<Control>u", NULL, NULL }},
|
||||
{ "app.new-window", { "<Control>n", NULL, NULL }},
|
||||
{ "app.info", { "<Control>i", NULL, NULL }},
|
||||
{ "app.pipeline", { "<Control><Shift>p", NULL, NULL }},
|
||||
{ "app.preferences", { "<Control>comma", NULL, NULL }},
|
||||
{ "app.about", { "F1", NULL, NULL }},
|
||||
{ "win.toggle-fullscreen", { "F11", "f", NULL }},
|
||||
{ "win.unfullscreen", { "Escape", NULL, NULL }},
|
||||
{ "win.auto-resize", { "<Super>r", NULL, NULL }},
|
||||
{ "win.show-help-overlay", { "<Control>question", NULL, NULL }},
|
||||
{ "window.close", { "<Control>q", "q", NULL }},
|
||||
};
|
||||
@@ -542,11 +752,14 @@ clapper_app_application_constructed (GObject *object)
|
||||
plugin_feature_ranks_settings_changed_cb (self->settings, NULL, NULL);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
||||
app_entries, G_N_ELEMENTS (app_entries), app);
|
||||
app_actions, G_N_ELEMENTS (app_actions), app);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (app_shortcuts); ++i)
|
||||
gtk_application_set_accels_for_action (GTK_APPLICATION (app), app_shortcuts[i].action, app_shortcuts[i].accels);
|
||||
|
||||
g_application_set_option_context_parameter_string (app, "[URI1|FILE1] [URI2|FILE2] …");
|
||||
|
||||
g_application_add_main_option_entries (app, app_options);
|
||||
g_application_add_option_group (app, gst_init_get_option_group ());
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||
@@ -581,5 +794,6 @@ clapper_app_application_class_init (ClapperAppApplicationClass *klass)
|
||||
|
||||
application_class->activate = clapper_app_application_activate;
|
||||
application_class->local_command_line = clapper_app_application_local_command_line;
|
||||
application_class->command_line = clapper_app_application_command_line;
|
||||
application_class->open = clapper_app_application_open;
|
||||
}
|
||||
|
@@ -80,8 +80,15 @@ _dialog_add_mime_types (GtkFileDialog *dialog, const gchar *filter_name,
|
||||
GtkFileFilter *filter = gtk_file_filter_new ();
|
||||
guint i;
|
||||
|
||||
for (i = 0; mime_types[i]; ++i)
|
||||
/* XXX: Windows does not support mime-types file
|
||||
* filters, so use file extensions instead */
|
||||
for (i = 0; mime_types[i]; ++i) {
|
||||
#ifndef G_OS_WIN32
|
||||
gtk_file_filter_add_mime_type (filter, mime_types[i]);
|
||||
#else
|
||||
gtk_file_filter_add_suffix (filter, mime_types[i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
gtk_file_filter_set_name (filter, filter_name);
|
||||
g_list_store_append (filters, filter);
|
||||
@@ -99,7 +106,11 @@ clapper_app_file_dialog_open_files (GtkApplication *gtk_app)
|
||||
GtkFileDialog *dialog = gtk_file_dialog_new ();
|
||||
|
||||
_dialog_add_mime_types (dialog, "Media Files",
|
||||
#ifndef G_OS_WIN32
|
||||
clapper_app_utils_get_mime_types ());
|
||||
#else
|
||||
clapper_app_utils_get_extensions ());
|
||||
#endif
|
||||
|
||||
gtk_file_dialog_set_modal (dialog, TRUE);
|
||||
gtk_file_dialog_set_title (dialog, "Add Files");
|
||||
@@ -118,7 +129,11 @@ clapper_app_file_dialog_open_subtitles (GtkApplication *gtk_app, ClapperMediaIte
|
||||
GtkFileDialog *dialog = gtk_file_dialog_new ();
|
||||
|
||||
_dialog_add_mime_types (dialog, "Subtitles",
|
||||
#ifndef G_OS_WIN32
|
||||
clapper_app_utils_get_subtitles_mime_types ());
|
||||
#else
|
||||
clapper_app_utils_get_subtitles_extensions ());
|
||||
#endif
|
||||
|
||||
gtk_file_dialog_set_modal (dialog, TRUE);
|
||||
gtk_file_dialog_set_title (dialog, "Open Subtitles");
|
||||
|
830
src/bin/clapper-app/clapper-app-pipeline-viewer.c
Normal file
830
src/bin/clapper-app/clapper-app-pipeline-viewer.c
Normal file
@@ -0,0 +1,830 @@
|
||||
/* Clapper Application
|
||||
* Copyright (C) 2024 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <graphviz/cgraph.h>
|
||||
#include <graphviz/gvc.h>
|
||||
#include <librsvg/rsvg.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "clapper-app-pipeline-viewer.h"
|
||||
|
||||
#define GST_CAT_DEFAULT clapper_app_pipeline_viewer_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
struct _ClapperAppPipelineViewer
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GtkAdjustment *hadjustment;
|
||||
GtkAdjustment *vadjustment;
|
||||
|
||||
GdkTexture *preview_texture;
|
||||
GdkTexture *texture;
|
||||
|
||||
RsvgHandle *handle;
|
||||
gdouble intrinsic_w;
|
||||
gdouble intrinsic_h;
|
||||
|
||||
graphene_rect_t viewport;
|
||||
|
||||
gdouble zoom;
|
||||
gboolean zooming;
|
||||
|
||||
gdouble pointer_x;
|
||||
gdouble pointer_y;
|
||||
|
||||
gdouble drag_adj_x;
|
||||
gdouble drag_adj_y;
|
||||
|
||||
gint allocated_width;
|
||||
gint allocated_height;
|
||||
|
||||
ClapperPlayer *player;
|
||||
GCancellable *cancellable;
|
||||
|
||||
gboolean running;
|
||||
gboolean pending_preview;
|
||||
gboolean pending_refresh;
|
||||
|
||||
guint refresh_id;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_HADJUSTMENT,
|
||||
PROP_VADJUSTMENT,
|
||||
PROP_HSCROLL_POLICY,
|
||||
PROP_VSCROLL_POLICY,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static void
|
||||
_scrollable_iface_init (GtkScrollableInterface *iface)
|
||||
{
|
||||
}
|
||||
|
||||
#define parent_class clapper_app_pipeline_viewer_parent_class
|
||||
G_DEFINE_TYPE_WITH_CODE (ClapperAppPipelineViewer, clapper_app_pipeline_viewer, GTK_TYPE_WIDGET,
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, _scrollable_iface_init));
|
||||
|
||||
static void clapper_app_pipeline_viewer_preview (ClapperAppPipelineViewer *self);
|
||||
static void clapper_app_pipeline_viewer_refresh (ClapperAppPipelineViewer *self);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ClapperPlayer *player;
|
||||
RsvgHandle *handle;
|
||||
gdouble intrinsic_w;
|
||||
gdouble intrinsic_h;
|
||||
graphene_rect_t viewport;
|
||||
gdouble zoom;
|
||||
gint scale_factor;
|
||||
} ClapperAppPipelineViewerData;
|
||||
|
||||
static ClapperAppPipelineViewerData *
|
||||
_thread_data_create (ClapperAppPipelineViewer *self)
|
||||
{
|
||||
ClapperAppPipelineViewerData *data;
|
||||
|
||||
data = g_new (ClapperAppPipelineViewerData, 1);
|
||||
data->player = gst_object_ref (self->player);
|
||||
data->handle = (self->handle) ? g_object_ref (self->handle) : NULL;
|
||||
data->intrinsic_w = self->intrinsic_w;
|
||||
data->intrinsic_h = self->intrinsic_h;
|
||||
graphene_rect_init_from_rect (&data->viewport, &self->viewport);
|
||||
data->zoom = self->zoom;
|
||||
data->scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (self));
|
||||
|
||||
GST_TRACE ("Created render data: %p", data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
_thread_data_free (ClapperAppPipelineViewerData *data)
|
||||
{
|
||||
GST_TRACE ("Freeing render data: %p", data);
|
||||
|
||||
gst_object_unref (data->player);
|
||||
g_clear_object (&data->handle);
|
||||
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_set_cancelled_error (GError **error)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR,
|
||||
G_IO_ERROR_CANCELLED, "Cancelled");
|
||||
}
|
||||
|
||||
static inline void
|
||||
_cancel_cancellable (ClapperAppPipelineViewer *self)
|
||||
{
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
|
||||
g_object_unref (self->cancellable);
|
||||
self->cancellable = g_cancellable_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
_invalidate_viewport (ClapperAppPipelineViewer *self)
|
||||
{
|
||||
g_clear_object (&self->texture);
|
||||
_cancel_cancellable (self);
|
||||
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
_refresh_viewport (ClapperAppPipelineViewer *self)
|
||||
{
|
||||
self->viewport.origin.x = gtk_adjustment_get_value (self->hadjustment);
|
||||
self->viewport.origin.y = gtk_adjustment_get_value (self->vadjustment);
|
||||
self->viewport.size.width = gtk_widget_get_width ((GtkWidget *) self);
|
||||
self->viewport.size.height = gtk_widget_get_height ((GtkWidget *) self);
|
||||
|
||||
clapper_app_pipeline_viewer_refresh (self);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
|
||||
self->refresh_id = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_set_refresh_viewport_timeout (ClapperAppPipelineViewer *self)
|
||||
{
|
||||
/* Wait a bit while adjustment still moves, then refresh */
|
||||
g_clear_handle_id (&self->refresh_id, g_source_remove);
|
||||
self->refresh_id = g_timeout_add_once (200, (GSourceOnceFunc) _refresh_viewport, self);
|
||||
}
|
||||
|
||||
static RsvgHandle *
|
||||
_load_pipeline_graph (ClapperAppPipelineViewer *self, ClapperPlayer *player,
|
||||
GstDebugGraphDetails details, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
RsvgHandle *handle = NULL;
|
||||
gchar *dot_data, *img_data = NULL;
|
||||
guint size = 0;
|
||||
|
||||
dot_data = clapper_player_make_pipeline_graph (player, details);
|
||||
|
||||
if (!g_cancellable_is_cancelled (cancellable)) {
|
||||
Agraph_t *graph;
|
||||
GVC_t *gvc;
|
||||
|
||||
graph = agmemread (dot_data);
|
||||
|
||||
gvc = gvContext ();
|
||||
gvLayout (gvc, graph, "dot");
|
||||
gvRenderData (gvc, graph, "svg", &img_data, &size);
|
||||
|
||||
agclose (graph);
|
||||
gvFreeContext (gvc);
|
||||
} else if (*error == NULL) {
|
||||
_set_cancelled_error (error);
|
||||
}
|
||||
|
||||
g_free (dot_data);
|
||||
|
||||
if (img_data) {
|
||||
if (!g_cancellable_is_cancelled (cancellable))
|
||||
handle = rsvg_handle_new_from_data ((const guint8 *) img_data, size, error);
|
||||
else if (*error == NULL)
|
||||
_set_cancelled_error (error);
|
||||
|
||||
g_free (img_data);
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
static inline GdkTexture *
|
||||
_create_texture_from_surface (cairo_surface_t *surface)
|
||||
{
|
||||
GdkTexture *texture;
|
||||
GBytes *bytes;
|
||||
|
||||
bytes = g_bytes_new_with_free_func (cairo_image_surface_get_data (surface),
|
||||
cairo_image_surface_get_height (surface) * cairo_image_surface_get_stride (surface),
|
||||
(GDestroyNotify) cairo_surface_destroy,
|
||||
cairo_surface_reference (surface));
|
||||
|
||||
texture = gdk_memory_texture_new (
|
||||
cairo_image_surface_get_width (surface),
|
||||
cairo_image_surface_get_height (surface),
|
||||
GDK_MEMORY_DEFAULT,
|
||||
bytes,
|
||||
cairo_image_surface_get_stride (surface));
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
static GdkTexture *
|
||||
_render_texture (RsvgHandle *handle, const graphene_rect_t *viewport, gint render_w, gint render_h,
|
||||
gint scale_factor, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
GdkTexture *texture = NULL;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
gint x, y, w, h;
|
||||
|
||||
x = floor (viewport->origin.x * scale_factor);
|
||||
y = floor (viewport->origin.y * scale_factor);
|
||||
w = ceil (viewport->size.width * scale_factor);
|
||||
h = ceil (viewport->size.height * scale_factor);
|
||||
|
||||
GST_DEBUG ("Creating surface, bb: (%i,%i,%i,%i)", x, y, w, h);
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h);
|
||||
cr = cairo_create (surface);
|
||||
|
||||
if (!g_cancellable_is_cancelled (cancellable)) {
|
||||
if (rsvg_handle_render_document (handle, cr, &(RsvgRectangle) {-x, -y, render_w, render_h}, error))
|
||||
texture = _create_texture_from_surface (surface);
|
||||
} else if (error == NULL) {
|
||||
_set_cancelled_error (error);
|
||||
}
|
||||
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
static void
|
||||
_preview_in_thread (GTask *task, ClapperAppPipelineViewer *self,
|
||||
ClapperAppPipelineViewerData *data, GCancellable *cancellable)
|
||||
{
|
||||
GdkTexture *texture = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
g_clear_object (&data->handle);
|
||||
if ((data->handle = _load_pipeline_graph (self,
|
||||
data->player, GST_DEBUG_GRAPH_SHOW_ALL, cancellable, &error))) {
|
||||
rsvg_handle_set_dpi (data->handle, 90);
|
||||
rsvg_handle_get_intrinsic_size_in_pixels (data->handle,
|
||||
&data->intrinsic_w, &data->intrinsic_h);
|
||||
|
||||
texture = _render_texture (data->handle,
|
||||
&GRAPHENE_RECT_INIT (0, 0, data->intrinsic_w, data->intrinsic_h),
|
||||
ceil (data->intrinsic_w), ceil (data->intrinsic_h),
|
||||
1, cancellable, &error);
|
||||
}
|
||||
|
||||
if (texture)
|
||||
g_task_return_pointer (task, texture, (GDestroyNotify) g_object_unref);
|
||||
else
|
||||
g_task_return_error (task, error);
|
||||
}
|
||||
|
||||
static void
|
||||
_refresh_in_thread (GTask *task, ClapperAppPipelineViewer *self,
|
||||
ClapperAppPipelineViewerData *data, GCancellable *cancellable)
|
||||
{
|
||||
GdkTexture *texture;
|
||||
GError *error = NULL;
|
||||
gint render_w, render_h;
|
||||
|
||||
render_w = ceil (data->zoom * data->intrinsic_w * data->scale_factor);
|
||||
render_h = ceil (data->zoom * data->intrinsic_h * data->scale_factor);
|
||||
|
||||
texture = _render_texture (data->handle, &data->viewport, render_w, render_h,
|
||||
data->scale_factor, cancellable, &error);
|
||||
|
||||
if (texture)
|
||||
g_task_return_pointer (task, texture, (GDestroyNotify) g_object_unref);
|
||||
else
|
||||
g_task_return_error (task, error);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_finish_texture_task (ClapperAppPipelineViewer *self, GTask *task, GdkTexture **texture)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gboolean cancelled = FALSE;
|
||||
|
||||
g_clear_object (texture);
|
||||
*texture = (GdkTexture *) g_task_propagate_pointer (task, &error);
|
||||
|
||||
if (error) {
|
||||
if (error->domain != G_IO_ERROR || error->code != G_IO_ERROR_CANCELLED) {
|
||||
GST_ERROR ("Error: %s", (error->message)
|
||||
? error->message : "Could not render pipeline graph");
|
||||
} else {
|
||||
GST_DEBUG ("Refresh cancelled");
|
||||
cancelled = TRUE;
|
||||
}
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
/* Resize will also trigger redraw. We need to always call resize,
|
||||
* because regenerated image has slightly different dimensions each time. */
|
||||
if (!cancelled)
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
|
||||
self->running = FALSE;
|
||||
|
||||
if (self->pending_preview) {
|
||||
clapper_app_pipeline_viewer_preview (self);
|
||||
self->pending_preview = FALSE;
|
||||
} else if (self->pending_refresh) {
|
||||
clapper_app_pipeline_viewer_refresh (self);
|
||||
self->pending_refresh = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_pipeline_viewer_preview_cb (ClapperAppPipelineViewer *self,
|
||||
GAsyncResult *res, gpointer user_data G_GNUC_UNUSED)
|
||||
{
|
||||
GTask *task = G_TASK (res);
|
||||
ClapperAppPipelineViewerData *data;
|
||||
|
||||
data = (ClapperAppPipelineViewerData *) g_task_get_task_data (task);
|
||||
|
||||
g_clear_object (&self->handle);
|
||||
self->handle = g_object_ref (data->handle);
|
||||
self->intrinsic_w = data->intrinsic_w;
|
||||
self->intrinsic_h = data->intrinsic_h;
|
||||
|
||||
_finish_texture_task (self, task, &self->preview_texture);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_pipeline_viewer_refresh_cb (ClapperAppPipelineViewer *self,
|
||||
GAsyncResult *res, gpointer user_data G_GNUC_UNUSED)
|
||||
{
|
||||
_finish_texture_task (self, G_TASK (res), &self->texture);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_pipeline_viewer_preview (ClapperAppPipelineViewer *self)
|
||||
{
|
||||
GTask *task;
|
||||
|
||||
_cancel_cancellable (self);
|
||||
|
||||
if (self->running) {
|
||||
self->pending_preview = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
self->running = TRUE;
|
||||
|
||||
task = g_task_new (self, self->cancellable,
|
||||
(GAsyncReadyCallback) clapper_app_pipeline_viewer_preview_cb, NULL);
|
||||
g_task_set_task_data (task, _thread_data_create (self),
|
||||
(GDestroyNotify) _thread_data_free);
|
||||
g_task_run_in_thread (task, (GTaskThreadFunc) _preview_in_thread);
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_pipeline_viewer_refresh (ClapperAppPipelineViewer *self)
|
||||
{
|
||||
GTask *task;
|
||||
|
||||
g_clear_object (&self->texture);
|
||||
_cancel_cancellable (self);
|
||||
|
||||
if (self->running) {
|
||||
self->pending_refresh = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
self->running = TRUE;
|
||||
|
||||
task = g_task_new (self, self->cancellable,
|
||||
(GAsyncReadyCallback) clapper_app_pipeline_viewer_refresh_cb, NULL);
|
||||
g_task_set_task_data (task, _thread_data_create (self),
|
||||
(GDestroyNotify) _thread_data_free);
|
||||
g_task_run_in_thread (task, (GTaskThreadFunc) _refresh_in_thread);
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
motion_cb (GtkEventControllerMotion *motion,
|
||||
gdouble x, gdouble y, ClapperAppPipelineViewer *self)
|
||||
{
|
||||
self->pointer_x = x;
|
||||
self->pointer_y = y;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
scroll_cb (GtkEventControllerScroll *scroll,
|
||||
gdouble dx, gdouble dy, ClapperAppPipelineViewer *self)
|
||||
{
|
||||
gdouble scale_factor, calc_scale, multiplier;
|
||||
gdouble event_x, event_y, x = 0, y = 0;
|
||||
|
||||
scale_factor = (dy > 0) ? 0.9 : (dy < 0) ? 1.1 : 0;
|
||||
if (scale_factor == 0)
|
||||
return TRUE;
|
||||
|
||||
calc_scale = CLAMP (self->zoom * scale_factor, 0.1, 10.0);
|
||||
|
||||
if (G_APPROX_VALUE (calc_scale, self->zoom, FLT_EPSILON))
|
||||
return TRUE;
|
||||
|
||||
GST_LOG_OBJECT (self, "Zoom to: %.2lf", calc_scale);
|
||||
|
||||
multiplier = calc_scale / self->zoom;
|
||||
|
||||
event_x = self->pointer_x - gtk_adjustment_get_value (self->hadjustment) * multiplier;
|
||||
event_y = self->pointer_y - gtk_adjustment_get_value (self->vadjustment) * multiplier;
|
||||
|
||||
x = self->pointer_x * multiplier - event_x;
|
||||
y = self->pointer_y * multiplier - event_y;
|
||||
|
||||
/* Do not act on adjustment changes here */
|
||||
self->zooming = TRUE;
|
||||
|
||||
self->zoom = calc_scale;
|
||||
|
||||
_invalidate_viewport (self);
|
||||
|
||||
gtk_adjustment_set_upper (self->hadjustment, G_MAXDOUBLE);
|
||||
gtk_adjustment_set_upper (self->vadjustment, G_MAXDOUBLE);
|
||||
|
||||
gtk_adjustment_set_value (self->hadjustment, x);
|
||||
gtk_adjustment_set_value (self->vadjustment, y);
|
||||
|
||||
_set_refresh_viewport_timeout (self);
|
||||
|
||||
self->zooming = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
drag_begin_cb (GtkGestureDrag *drag, gdouble start_x, gdouble start_y,
|
||||
ClapperAppPipelineViewer *self)
|
||||
{
|
||||
GdkCursor *cursor;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Drag begin");
|
||||
|
||||
cursor = gdk_cursor_new_from_name ("all-scroll", NULL);
|
||||
gtk_widget_set_cursor (GTK_WIDGET (self), cursor);
|
||||
g_object_unref (cursor);
|
||||
|
||||
self->drag_adj_x = gtk_adjustment_get_value (self->hadjustment);
|
||||
self->drag_adj_y = gtk_adjustment_get_value (self->vadjustment);
|
||||
}
|
||||
|
||||
static void
|
||||
drag_update_cb (GtkGestureDrag *drag, gdouble offset_x, gdouble offset_y,
|
||||
ClapperAppPipelineViewer *self)
|
||||
{
|
||||
gtk_adjustment_set_value (self->hadjustment, self->drag_adj_x - offset_x);
|
||||
gtk_adjustment_set_value (self->vadjustment, self->drag_adj_y - offset_y);
|
||||
}
|
||||
|
||||
static void
|
||||
drag_end_cb (GtkGestureDrag *drag, gdouble offset_x, gdouble offset_y,
|
||||
ClapperAppPipelineViewer *self)
|
||||
{
|
||||
GdkCursor *cursor;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Drag end");
|
||||
|
||||
cursor = gdk_cursor_new_from_name ("default", NULL);
|
||||
gtk_widget_set_cursor (GTK_WIDGET (self), cursor);
|
||||
g_object_unref (cursor);
|
||||
}
|
||||
|
||||
static void
|
||||
_adjustment_value_changed_cb (GtkAdjustment *adjustment, ClapperAppPipelineViewer *self)
|
||||
{
|
||||
if (self->zooming)
|
||||
return;
|
||||
|
||||
_invalidate_viewport (self);
|
||||
_set_refresh_viewport_timeout (self);
|
||||
|
||||
gtk_widget_queue_allocate ((GtkWidget *) self);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_widget_size_changed (ClapperAppPipelineViewer *self)
|
||||
{
|
||||
if (!self->preview_texture)
|
||||
return;
|
||||
|
||||
_invalidate_viewport (self);
|
||||
_set_refresh_viewport_timeout (self);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_set_adjustment (ClapperAppPipelineViewer *self,
|
||||
GtkAdjustment **dest_adjustment, GtkAdjustment *adjustment)
|
||||
{
|
||||
if (*dest_adjustment)
|
||||
g_signal_handlers_disconnect_by_func (*dest_adjustment, _adjustment_value_changed_cb, self);
|
||||
|
||||
if (!adjustment)
|
||||
adjustment = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
g_clear_object (dest_adjustment);
|
||||
*dest_adjustment = g_object_ref_sink (adjustment);
|
||||
|
||||
g_signal_connect (*dest_adjustment, "value-changed", G_CALLBACK (_adjustment_value_changed_cb), self);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_set_adjustment_values (ClapperAppPipelineViewer *self, GtkAdjustment *adjustment,
|
||||
gboolean is_rtl, gint viewport_size, gint upper)
|
||||
{
|
||||
gdouble value = gtk_adjustment_get_value (adjustment);
|
||||
|
||||
/* We clamp to the left in RTL mode */
|
||||
if (adjustment == self->hadjustment && is_rtl) {
|
||||
gdouble dist = gtk_adjustment_get_upper (adjustment) - value - gtk_adjustment_get_page_size (adjustment);
|
||||
value = upper - dist - viewport_size;
|
||||
}
|
||||
|
||||
gtk_adjustment_configure (adjustment, value, 0, upper,
|
||||
viewport_size * 0.1, viewport_size * 0.9, viewport_size);
|
||||
}
|
||||
|
||||
void
|
||||
clapper_app_pipeline_viewer_set_player (ClapperAppPipelineViewer *self, ClapperPlayer *player)
|
||||
{
|
||||
gst_object_replace ((GstObject **) &self->player, GST_OBJECT_CAST (player));
|
||||
clapper_app_pipeline_viewer_preview (self);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_pipeline_viewer_size_allocate (GtkWidget *widget,
|
||||
gint width, gint height, gint baseline)
|
||||
{
|
||||
ClapperAppPipelineViewer *self = CLAPPER_APP_PIPELINE_VIEWER_CAST (widget);
|
||||
gint sizes[2] = { width, height };
|
||||
gboolean visible, is_rtl;
|
||||
|
||||
visible = gtk_widget_get_visible (widget);
|
||||
is_rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
|
||||
|
||||
/* Update both at once, then notify */
|
||||
g_object_freeze_notify (G_OBJECT (self->hadjustment));
|
||||
g_object_freeze_notify (G_OBJECT (self->vadjustment));
|
||||
|
||||
if (visible) {
|
||||
gint min = 0, nat = 0;
|
||||
|
||||
if (width != self->allocated_width || height != self->allocated_height)
|
||||
_on_widget_size_changed (self);
|
||||
|
||||
gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL, -1, &min, &nat, NULL, NULL);
|
||||
sizes[1] = MAX (sizes[1], nat);
|
||||
|
||||
gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL, sizes[1], &min, &nat, NULL, NULL);
|
||||
sizes[0] = MAX (sizes[0], nat);
|
||||
}
|
||||
|
||||
_set_adjustment_values (self, self->hadjustment, is_rtl, width, sizes[0]);
|
||||
_set_adjustment_values (self, self->vadjustment, is_rtl, height, sizes[1]);
|
||||
|
||||
self->allocated_width = width;
|
||||
self->allocated_height = height;
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (self->hadjustment));
|
||||
g_object_thaw_notify (G_OBJECT (self->vadjustment));
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_pipeline_viewer_measure (GtkWidget *widget, GtkOrientation orientation,
|
||||
gint for_size, gint *minimum, gint *natural,
|
||||
gint *minimum_baseline, gint *natural_baseline)
|
||||
{
|
||||
ClapperAppPipelineViewer *self = CLAPPER_APP_PIPELINE_VIEWER_CAST (widget);
|
||||
|
||||
if (self->preview_texture) {
|
||||
gdouble size;
|
||||
|
||||
size = (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
? self->intrinsic_w
|
||||
: self->intrinsic_h;
|
||||
|
||||
*minimum = *natural = ceil (self->zoom * size);
|
||||
} else {
|
||||
GTK_WIDGET_CLASS (parent_class)->measure (widget, orientation,
|
||||
for_size, minimum, natural, minimum_baseline, natural_baseline);
|
||||
}
|
||||
}
|
||||
|
||||
static GtkSizeRequestMode
|
||||
clapper_app_pipeline_viewer_get_request_mode (GtkWidget *widget)
|
||||
{
|
||||
return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_pipeline_viewer_snapshot (GtkWidget *widget, GtkSnapshot *snapshot)
|
||||
{
|
||||
ClapperAppPipelineViewer *self = CLAPPER_APP_PIPELINE_VIEWER_CAST (widget);
|
||||
gint w, h, offset_x, offset_y;
|
||||
gint widget_w, widget_h;
|
||||
|
||||
if (!self->preview_texture)
|
||||
return;
|
||||
|
||||
GST_ERROR ("SNAPSHOT");
|
||||
|
||||
w = ceil (self->zoom * self->intrinsic_w);
|
||||
h = ceil (self->zoom * self->intrinsic_h);
|
||||
|
||||
widget_w = gtk_widget_get_width (widget);
|
||||
widget_h = gtk_widget_get_height (widget);
|
||||
|
||||
if (widget_w > w)
|
||||
offset_x = floor ((gdouble) (widget_w - w) / 2);
|
||||
else
|
||||
offset_x = -floor (gtk_adjustment_get_value (self->hadjustment));
|
||||
|
||||
if (widget_h > h)
|
||||
offset_y = floor ((gdouble) (widget_h - h) / 2);
|
||||
else
|
||||
offset_y = -floor (gtk_adjustment_get_value (self->vadjustment));
|
||||
|
||||
gtk_snapshot_push_clip (snapshot, &GRAPHENE_RECT_INIT (0, 0, widget_w, widget_h));
|
||||
gtk_snapshot_save (snapshot);
|
||||
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (offset_x, offset_y));
|
||||
|
||||
if (self->texture)
|
||||
gtk_snapshot_append_texture (snapshot, self->texture, &self->viewport);
|
||||
else
|
||||
gtk_snapshot_append_texture (snapshot, self->preview_texture, &GRAPHENE_RECT_INIT (0, 0, w, h));
|
||||
|
||||
gtk_snapshot_restore (snapshot);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_pipeline_viewer_unrealize (GtkWidget *widget)
|
||||
{
|
||||
ClapperAppPipelineViewer *self = CLAPPER_APP_PIPELINE_VIEWER_CAST (widget);
|
||||
|
||||
GST_TRACE_OBJECT (self, "Unrealize");
|
||||
|
||||
g_clear_handle_id (&self->refresh_id, g_source_remove);
|
||||
|
||||
_cancel_cancellable (self);
|
||||
|
||||
GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_pipeline_viewer_init (ClapperAppPipelineViewer *self)
|
||||
{
|
||||
GtkEventController *controller;
|
||||
|
||||
_set_adjustment (self, &self->hadjustment, NULL);
|
||||
_set_adjustment (self, &self->vadjustment, NULL);
|
||||
|
||||
graphene_rect_init (&self->viewport, 0, 0, 1, 1);
|
||||
self->zoom = 0.5;
|
||||
self->cancellable = g_cancellable_new ();
|
||||
|
||||
controller = gtk_event_controller_motion_new ();
|
||||
g_signal_connect (controller, "motion", G_CALLBACK (motion_cb), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||
|
||||
controller = gtk_event_controller_scroll_new (GTK_EVENT_CONTROLLER_SCROLL_VERTICAL);
|
||||
gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_CAPTURE);
|
||||
g_signal_connect (controller, "scroll", G_CALLBACK (scroll_cb), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||
|
||||
controller = GTK_EVENT_CONTROLLER (gtk_gesture_drag_new ());
|
||||
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (controller), FALSE);
|
||||
g_signal_connect (controller, "drag-begin", G_CALLBACK (drag_begin_cb), self);
|
||||
g_signal_connect (controller, "drag-update", G_CALLBACK (drag_update_cb), self);
|
||||
g_signal_connect (controller, "drag-end", G_CALLBACK (drag_end_cb), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_pipeline_viewer_dispose (GObject *object)
|
||||
{
|
||||
ClapperAppPipelineViewer *self = CLAPPER_APP_PIPELINE_VIEWER_CAST (object);
|
||||
|
||||
if (self->hadjustment) {
|
||||
g_signal_handlers_disconnect_by_func (self->hadjustment, _adjustment_value_changed_cb, self);
|
||||
g_clear_object (&self->hadjustment);
|
||||
}
|
||||
if (self->vadjustment) {
|
||||
g_signal_handlers_disconnect_by_func (self->vadjustment, _adjustment_value_changed_cb, self);
|
||||
g_clear_object (&self->vadjustment);
|
||||
}
|
||||
|
||||
g_clear_object (&self->preview_texture);
|
||||
g_clear_object (&self->texture);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_pipeline_viewer_finalize (GObject *object)
|
||||
{
|
||||
ClapperAppPipelineViewer *self = CLAPPER_APP_PIPELINE_VIEWER_CAST (object);
|
||||
|
||||
GST_TRACE_OBJECT (self, "Finalize");
|
||||
|
||||
g_clear_object (&self->cancellable);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_pipeline_viewer_get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
ClapperAppPipelineViewer *self = CLAPPER_APP_PIPELINE_VIEWER_CAST (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_HADJUSTMENT:
|
||||
g_value_set_object (value, self->hadjustment);
|
||||
break;
|
||||
case PROP_VADJUSTMENT:
|
||||
g_value_set_object (value, self->vadjustment);
|
||||
break;
|
||||
case PROP_HSCROLL_POLICY:
|
||||
case PROP_VSCROLL_POLICY:
|
||||
g_value_set_enum (value, GTK_SCROLL_NATURAL);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_pipeline_viewer_set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
ClapperAppPipelineViewer *self = CLAPPER_APP_PIPELINE_VIEWER_CAST (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_HADJUSTMENT:
|
||||
_set_adjustment (self, &self->hadjustment, g_value_get_object (value));
|
||||
break;
|
||||
case PROP_VADJUSTMENT:
|
||||
_set_adjustment (self, &self->vadjustment, g_value_get_object (value));
|
||||
break;
|
||||
case PROP_HSCROLL_POLICY:
|
||||
case PROP_VSCROLL_POLICY:
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_pipeline_viewer_class_init (ClapperAppPipelineViewerClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
GtkWidgetClass *widget_class = (GtkWidgetClass *) klass;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperapppipelineviewer", 0,
|
||||
"Clapper App Pipeline Viewer");
|
||||
|
||||
gobject_class->get_property = clapper_app_pipeline_viewer_get_property;
|
||||
gobject_class->set_property = clapper_app_pipeline_viewer_set_property;
|
||||
gobject_class->dispose = clapper_app_pipeline_viewer_dispose;
|
||||
gobject_class->finalize = clapper_app_pipeline_viewer_finalize;
|
||||
|
||||
g_object_class_override_property (gobject_class, PROP_HADJUSTMENT, "hadjustment");
|
||||
g_object_class_override_property (gobject_class, PROP_VADJUSTMENT, "vadjustment");
|
||||
g_object_class_override_property (gobject_class, PROP_HSCROLL_POLICY, "hscroll-policy");
|
||||
g_object_class_override_property (gobject_class, PROP_VSCROLL_POLICY, "vscroll-policy");
|
||||
|
||||
widget_class->size_allocate = clapper_app_pipeline_viewer_size_allocate;
|
||||
widget_class->measure = clapper_app_pipeline_viewer_measure;
|
||||
widget_class->get_request_mode = clapper_app_pipeline_viewer_get_request_mode;
|
||||
widget_class->snapshot = clapper_app_pipeline_viewer_snapshot;
|
||||
widget_class->unrealize = clapper_app_pipeline_viewer_unrealize;
|
||||
|
||||
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_IMG);
|
||||
}
|
41
src/bin/clapper-app/clapper-app-pipeline-viewer.h
Normal file
41
src/bin/clapper-app/clapper-app-pipeline-viewer.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/* Clapper Application
|
||||
* Copyright (C) 2024 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gio/gio.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <clapper/clapper.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLAPPER_APP_TYPE_PIPELINE_VIEWER (clapper_app_pipeline_viewer_get_type())
|
||||
#define CLAPPER_APP_PIPELINE_VIEWER_CAST(obj) ((ClapperAppPipelineViewer *)(obj))
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ClapperAppPipelineViewer, clapper_app_pipeline_viewer, CLAPPER_APP, PIPELINE_VIEWER, GtkWidget)
|
||||
|
||||
void clapper_app_pipeline_viewer_set_player (ClapperAppPipelineViewer *pipeline_viewer, ClapperPlayer *player);
|
||||
|
||||
gboolean clapper_app_pipeline_viewer_focus (ClapperAppPipelineViewer *pipeline_viewer, const graphene_rect_t *viewport, gdouble zoom);
|
||||
|
||||
void clapper_app_pipeline_viewer_invalidate_viewport (ClapperAppPipelineViewer *pipeline_viewer);
|
||||
|
||||
gdouble clapper_app_pipeline_viewer_get_zoom (ClapperAppPipelineViewer *pipeline_viewer);
|
||||
|
||||
G_END_DECLS
|
103
src/bin/clapper-app/clapper-app-pipeline-window.c
Normal file
103
src/bin/clapper-app/clapper-app-pipeline-window.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/* Clapper Application
|
||||
* Copyright (C) 2024 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clapper-app-pipeline-window.h"
|
||||
#include "clapper-app-pipeline-viewer.h"
|
||||
|
||||
#define GST_CAT_DEFAULT clapper_app_pipeline_window_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
struct _ClapperAppPipelineWindow
|
||||
{
|
||||
AdwWindow parent;
|
||||
|
||||
ClapperAppPipelineViewer *pipeline_viewer;
|
||||
};
|
||||
|
||||
#define parent_class clapper_app_pipeline_window_parent_class
|
||||
G_DEFINE_TYPE (ClapperAppPipelineWindow, clapper_app_pipeline_window, ADW_TYPE_WINDOW);
|
||||
|
||||
static gboolean
|
||||
close_cb (GtkWidget *widget, GVariant *args G_GNUC_UNUSED,
|
||||
gpointer user_data G_GNUC_UNUSED)
|
||||
{
|
||||
gtk_window_close (GTK_WINDOW (widget));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
clapper_app_pipeline_window_new (GtkApplication *gtk_app, ClapperPlayer *player)
|
||||
{
|
||||
ClapperAppPipelineWindow *window;
|
||||
|
||||
window = g_object_new (CLAPPER_APP_TYPE_PIPELINE_WINDOW,
|
||||
"application", gtk_app,
|
||||
"transient-for", gtk_application_get_active_window (gtk_app),
|
||||
NULL);
|
||||
clapper_app_pipeline_viewer_set_player (window->pipeline_viewer, player);
|
||||
|
||||
return GTK_WIDGET (window);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_pipeline_window_init (ClapperAppPipelineWindow *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_pipeline_window_dispose (GObject *object)
|
||||
{
|
||||
gtk_widget_dispose_template (GTK_WIDGET (object), CLAPPER_APP_TYPE_PIPELINE_WINDOW);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_pipeline_window_finalize (GObject *object)
|
||||
{
|
||||
ClapperAppPipelineWindow *self = CLAPPER_APP_PIPELINE_WINDOW_CAST (object);
|
||||
|
||||
GST_TRACE_OBJECT (self, "Finalize");
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_pipeline_window_class_init (ClapperAppPipelineWindowClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
GtkWidgetClass *widget_class = (GtkWidgetClass *) klass;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperapppipelinewindow", 0,
|
||||
"Clapper App Pipeline Window");
|
||||
|
||||
gobject_class->dispose = clapper_app_pipeline_window_dispose;
|
||||
gobject_class->finalize = clapper_app_pipeline_window_finalize;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class,
|
||||
CLAPPER_APP_RESOURCE_PREFIX "/ui/clapper-app-pipeline-window.ui");
|
||||
|
||||
gtk_widget_class_add_binding (widget_class, GDK_KEY_Escape, 0, close_cb, NULL);
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, ClapperAppPipelineWindow, pipeline_viewer);
|
||||
|
||||
//gtk_widget_class_bind_template_callback (widget_class, refresh_button_clicked_cb);
|
||||
}
|
36
src/bin/clapper-app/clapper-app-pipeline-window.h
Normal file
36
src/bin/clapper-app/clapper-app-pipeline-window.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/* Clapper Application
|
||||
* Copyright (C) 2024 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <adwaita.h>
|
||||
#include <clapper/clapper.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLAPPER_APP_TYPE_PIPELINE_WINDOW (clapper_app_pipeline_window_get_type())
|
||||
#define CLAPPER_APP_PIPELINE_WINDOW_CAST(obj) ((ClapperAppPipelineWindow *)(obj))
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ClapperAppPipelineWindow, clapper_app_pipeline_window, CLAPPER_APP, PIPELINE_WINDOW, AdwWindow)
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GtkWidget * clapper_app_pipeline_window_new (GtkApplication *gtk_app, ClapperPlayer *player);
|
||||
|
||||
G_END_DECLS
|
42
src/bin/clapper-app/clapper-app-types.c
Normal file
42
src/bin/clapper-app/clapper-app-types.c
Normal file
@@ -0,0 +1,42 @@
|
||||
/* Clapper Application
|
||||
* Copyright (C) 2024 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "clapper-app-types.h"
|
||||
|
||||
#include "clapper-app-headerbar.h"
|
||||
#include "clapper-app-media-item-box.h"
|
||||
#include "clapper-app-property-row.h"
|
||||
#include "clapper-app-queue-list.h"
|
||||
#include "clapper-app-queue-progression-model.h"
|
||||
#include "clapper-app-window-state-buttons.h"
|
||||
|
||||
/*
|
||||
* clapper_app_types_init:
|
||||
*
|
||||
* Ensure private types that appear in UI files in order for
|
||||
* GtkBuilder to be able to find them when building templates.
|
||||
*/
|
||||
inline void
|
||||
clapper_app_types_init (void)
|
||||
{
|
||||
g_type_ensure (CLAPPER_APP_TYPE_HEADERBAR);
|
||||
g_type_ensure (CLAPPER_APP_TYPE_MEDIA_ITEM_BOX);
|
||||
g_type_ensure (CLAPPER_APP_TYPE_PROPERTY_ROW);
|
||||
g_type_ensure (CLAPPER_APP_TYPE_QUEUE_LIST);
|
||||
g_type_ensure (CLAPPER_APP_TYPE_QUEUE_PROGRESSION_MODEL);
|
||||
g_type_ensure (CLAPPER_APP_TYPE_WINDOW_STATE_BUTTONS);
|
||||
}
|
27
src/bin/clapper-app/clapper-app-types.h
Normal file
27
src/bin/clapper-app/clapper-app-types.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/* Clapper Application
|
||||
* Copyright (C) 2024 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_app_types_init (void);
|
||||
|
||||
G_END_DECLS
|
@@ -23,6 +23,30 @@
|
||||
#include "clapper-app-utils.h"
|
||||
#include "clapper-app-media-item-box.h"
|
||||
|
||||
/* Useful only on Windows */
|
||||
#ifdef G_OS_WIN32
|
||||
const gchar *const *
|
||||
clapper_app_utils_get_extensions (void)
|
||||
{
|
||||
static const gchar *const all_extensions[] = {
|
||||
"avi", "claps", "m2ts", "mkv", "mov",
|
||||
"mp4", "webm", "wmv", NULL
|
||||
};
|
||||
|
||||
return all_extensions;
|
||||
}
|
||||
|
||||
const gchar *const *
|
||||
clapper_app_utils_get_subtitles_extensions (void)
|
||||
{
|
||||
static const gchar *const subs_extensions[] = {
|
||||
"srt", "vtt", NULL
|
||||
};
|
||||
|
||||
return subs_extensions;
|
||||
}
|
||||
#endif
|
||||
|
||||
const gchar *const *
|
||||
clapper_app_utils_get_mime_types (void)
|
||||
{
|
||||
@@ -197,6 +221,30 @@ clapper_app_utils_files_from_string (const gchar *string, GFile ***files, gint *
|
||||
return success;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clapper_app_utils_files_from_command_line (GApplicationCommandLine *cmd_line, GFile ***files, gint *n_files)
|
||||
{
|
||||
GSList *slist = NULL;
|
||||
gchar **argv;
|
||||
gint i, argc = 0;
|
||||
gboolean success;
|
||||
|
||||
argv = g_application_command_line_get_arguments (cmd_line, &argc);
|
||||
|
||||
for (i = 1; i < argc; ++i)
|
||||
slist = g_slist_append (slist, g_application_command_line_create_file_for_arg (cmd_line, argv[i]));
|
||||
|
||||
g_strfreev (argv);
|
||||
|
||||
if (!slist)
|
||||
return FALSE;
|
||||
|
||||
success = clapper_app_utils_files_from_slist (slist, files, n_files);
|
||||
g_slist_free_full (slist, g_object_unref);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
_files_from_file (GFile *file, GFile ***files, gint *n_files)
|
||||
{
|
||||
@@ -336,3 +384,29 @@ parse_overrides:
|
||||
|
||||
g_free (stored_overrides);
|
||||
}
|
||||
|
||||
GstElement *
|
||||
clapper_app_utils_make_element (const gchar *string)
|
||||
{
|
||||
gchar *char_loc;
|
||||
|
||||
if (strcmp (string, "none") == 0)
|
||||
return NULL;
|
||||
|
||||
char_loc = strchr (string, ' ');
|
||||
|
||||
if (char_loc) {
|
||||
GstElement *element;
|
||||
GError *error = NULL;
|
||||
|
||||
element = gst_parse_bin_from_description (string, TRUE, &error);
|
||||
if (error) {
|
||||
GST_ERROR ("Bin parse error: \"%s\", reason: %s", string, error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
return gst_element_factory_make (string, NULL);
|
||||
}
|
||||
|
@@ -26,6 +26,14 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef void (* ClapperAppUtilsIterRanks) (const gchar *feature_name, GstRank rank, gboolean from_env, gpointer user_data);
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
G_GNUC_INTERNAL
|
||||
const gchar *const * clapper_app_utils_get_extensions (void);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
const gchar *const * clapper_app_utils_get_subtitles_extensions (void);
|
||||
#endif
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
const gchar *const * clapper_app_utils_get_mime_types (void);
|
||||
|
||||
@@ -50,6 +58,9 @@ gboolean clapper_app_utils_files_from_slist (GSList *file_list, GFile ***files,
|
||||
G_GNUC_INTERNAL
|
||||
gboolean clapper_app_utils_files_from_string (const gchar *string, GFile ***files, gint *n_files);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean clapper_app_utils_files_from_command_line (GApplicationCommandLine *cmd_line, GFile ***files, gint *n_files);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean clapper_app_utils_files_from_value (const GValue *value, GFile ***files, gint *n_files);
|
||||
|
||||
@@ -59,4 +70,7 @@ void clapper_app_utils_files_free (GFile **files);
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_app_utils_iterate_plugin_feature_ranks (GSettings *settings, ClapperAppUtilsIterRanks callback, gpointer user_data);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstElement * clapper_app_utils_make_element (const gchar *string);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -28,6 +28,9 @@
|
||||
#include "clapper-app-file-dialog.h"
|
||||
#include "clapper-app-utils.h"
|
||||
|
||||
#define MIN_WINDOW_WIDTH 352
|
||||
#define MIN_WINDOW_HEIGHT 198
|
||||
|
||||
#define DEFAULT_WINDOW_WIDTH 1024
|
||||
#define DEFAULT_WINDOW_HEIGHT 576
|
||||
|
||||
@@ -40,6 +43,8 @@
|
||||
#define PERCENTAGE_ROUND(a) (round ((gdouble) a / 0.01) * 0.01)
|
||||
#define AXIS_WINS_OVER(a,b) ((a > 0 && a - 0.3 > b) || (a < 0 && a + 0.3 < b))
|
||||
|
||||
#define MIN_STEP_DELAY 12000
|
||||
|
||||
#define GST_CAT_DEFAULT clapper_app_window_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
@@ -59,6 +64,7 @@ struct _ClapperAppWindow
|
||||
GSettings *settings;
|
||||
|
||||
guint seek_timeout;
|
||||
guint resize_tick_id;
|
||||
|
||||
gboolean key_held;
|
||||
gboolean scrolling;
|
||||
@@ -74,6 +80,36 @@ struct _ClapperAppWindow
|
||||
#define parent_class clapper_app_window_parent_class
|
||||
G_DEFINE_TYPE (ClapperAppWindow, clapper_app_window, GTK_TYPE_APPLICATION_WINDOW)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gint dest_width, dest_height;
|
||||
gint64 last_tick;
|
||||
} ClapperAppWindowResizeData;
|
||||
|
||||
#if CLAPPER_HAVE_MPRIS
|
||||
static guint16 instance_count = 0;
|
||||
#endif
|
||||
|
||||
static inline GQuark
|
||||
clapper_app_window_extra_options_get_quark (void)
|
||||
{
|
||||
return g_quark_from_static_string ("clapper-app-window-extra-options-quark");
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_window_extra_options_free (ClapperAppWindowExtraOptions *extra_opts)
|
||||
{
|
||||
GST_TRACE ("Freeing window extra options: %p", extra_opts);
|
||||
|
||||
g_free (extra_opts->video_filter);
|
||||
g_free (extra_opts->audio_filter);
|
||||
|
||||
g_free (extra_opts->video_sink);
|
||||
g_free (extra_opts->audio_sink);
|
||||
|
||||
g_free (extra_opts);
|
||||
}
|
||||
|
||||
static void
|
||||
_media_item_title_changed_cb (ClapperMediaItem *item,
|
||||
GParamSpec *pspec G_GNUC_UNUSED, ClapperAppWindow *self)
|
||||
@@ -115,6 +151,15 @@ _queue_current_item_changed_cb (ClapperQueue *queue,
|
||||
gst_clear_object (¤t_item);
|
||||
}
|
||||
|
||||
static void
|
||||
_player_adaptive_bandwidth_changed_cb (ClapperPlayer *player,
|
||||
GParamSpec *pspec G_GNUC_UNUSED, gpointer *user_data G_GNUC_UNUSED)
|
||||
{
|
||||
/* Do not take whole bandwidth */
|
||||
clapper_player_set_adaptive_start_bitrate (player,
|
||||
clapper_player_get_adaptive_bandwidth (player) * 0.8);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_get_seek_method_mapping (GValue *value,
|
||||
GVariant *variant, gpointer user_data G_GNUC_UNUSED)
|
||||
@@ -224,12 +269,16 @@ _open_subtitles_cb (ClapperGtkExtraMenuButton *button G_GNUC_UNUSED,
|
||||
}
|
||||
|
||||
static void
|
||||
right_click_pressed_cb (GtkGestureClick *click, gint n_press,
|
||||
click_pressed_cb (GtkGestureClick *click, gint n_press,
|
||||
gdouble x, gdouble y, ClapperAppWindow *self)
|
||||
{
|
||||
GdkCursor *cursor;
|
||||
const gchar *cursor_name = NULL;
|
||||
|
||||
if (gtk_gesture_single_get_current_button (
|
||||
GTK_GESTURE_SINGLE (click)) != GDK_BUTTON_SECONDARY)
|
||||
return;
|
||||
|
||||
GST_LOG_OBJECT (self, "Right click pressed");
|
||||
|
||||
if ((cursor = gtk_widget_get_cursor (self->video)))
|
||||
@@ -244,9 +293,152 @@ right_click_pressed_cb (GtkGestureClick *click, gint n_press,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_resize_tick (GtkWidget *widget, GdkFrameClock *frame_clock,
|
||||
ClapperAppWindowResizeData *resize_data)
|
||||
{
|
||||
gint64 now = gdk_frame_clock_get_frame_time (frame_clock);
|
||||
|
||||
if (now - resize_data->last_tick >= MIN_STEP_DELAY) {
|
||||
ClapperAppWindow *self = CLAPPER_APP_WINDOW_CAST (widget);
|
||||
gint win_width, win_height;
|
||||
|
||||
GST_LOG_OBJECT (self, "Resize step, last: %" G_GINT64_FORMAT
|
||||
", now: %" G_GINT64_FORMAT, resize_data->last_tick, now);
|
||||
|
||||
gtk_window_get_default_size (GTK_WINDOW (self), &win_width, &win_height);
|
||||
|
||||
if (win_width != resize_data->dest_width) {
|
||||
gint width_diff = ABS (win_width - resize_data->dest_width);
|
||||
gint step_size = (width_diff > 180) ? 120 : MAX (width_diff / 4, 1);
|
||||
|
||||
win_width += (win_width > resize_data->dest_width) ? -step_size : step_size;
|
||||
}
|
||||
if (win_height != resize_data->dest_height) {
|
||||
gint height_diff = ABS (win_height - resize_data->dest_height);
|
||||
gint step_size = (height_diff > 180) ? 120 : MAX (height_diff / 4, 1);
|
||||
|
||||
win_height += (win_height > resize_data->dest_height) ? -step_size : step_size;
|
||||
}
|
||||
|
||||
gtk_window_set_default_size (GTK_WINDOW (self), win_width, win_height);
|
||||
|
||||
if (win_width == resize_data->dest_width
|
||||
&& win_height == resize_data->dest_height) {
|
||||
GST_DEBUG_OBJECT (self, "Window resize finish");
|
||||
self->resize_tick_id = 0;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
resize_data->last_tick = now;
|
||||
}
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
right_click_released_cb (GtkGestureClick *click, gint n_press,
|
||||
gdouble x, gdouble y, ClapperAppWindow *self)
|
||||
_calculate_win_resize (gint win_w, gint win_h,
|
||||
gint vid_w, gint vid_h, gint *dest_w, gint *dest_h)
|
||||
{
|
||||
gdouble win_aspect = (gdouble) win_w / win_h;
|
||||
gdouble vid_aspect = (gdouble) vid_w / vid_h;
|
||||
|
||||
if (win_aspect < vid_aspect) {
|
||||
while (!G_APPROX_VALUE (fmod (win_w, vid_aspect), 0, FLT_EPSILON))
|
||||
win_w++;
|
||||
|
||||
win_h = round ((gdouble) win_w / vid_aspect);
|
||||
|
||||
if (win_h < MIN_WINDOW_HEIGHT) {
|
||||
_calculate_win_resize (G_MAXINT, MIN_WINDOW_HEIGHT, vid_w, vid_h, dest_w, dest_h);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
while (!G_APPROX_VALUE (fmod (win_h * vid_aspect, 1.0), 0, FLT_EPSILON))
|
||||
win_h++;
|
||||
|
||||
win_w = round ((gdouble) win_h * vid_aspect);
|
||||
|
||||
if (win_w < MIN_WINDOW_WIDTH) {
|
||||
_calculate_win_resize (MIN_WINDOW_WIDTH, G_MAXINT, vid_w, vid_h, dest_w, dest_h);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
*dest_w = win_w;
|
||||
*dest_h = win_h;
|
||||
}
|
||||
|
||||
static void
|
||||
_resize_window (ClapperAppWindow *self)
|
||||
{
|
||||
ClapperPlayer *player;
|
||||
ClapperStreamList *vstreams;
|
||||
ClapperVideoStream *vstream;
|
||||
GdkToplevelState toplevel_state, disallowed;
|
||||
|
||||
if (self->resize_tick_id != 0)
|
||||
return;
|
||||
|
||||
toplevel_state = gdk_toplevel_get_state (GDK_TOPLEVEL (
|
||||
gtk_native_get_surface (GTK_NATIVE (self))));
|
||||
disallowed = (GDK_TOPLEVEL_STATE_MINIMIZED
|
||||
| GDK_TOPLEVEL_STATE_MAXIMIZED
|
||||
| GDK_TOPLEVEL_STATE_FULLSCREEN
|
||||
| GDK_TOPLEVEL_STATE_TILED);
|
||||
|
||||
if ((toplevel_state & disallowed) > 0) {
|
||||
GST_DEBUG_OBJECT (self, "Cannot resize window in disallowed state");
|
||||
return;
|
||||
}
|
||||
|
||||
player = clapper_app_window_get_player (self);
|
||||
vstreams = clapper_player_get_video_streams (player);
|
||||
vstream = CLAPPER_VIDEO_STREAM_CAST (
|
||||
clapper_stream_list_get_current_stream (vstreams));
|
||||
|
||||
if (vstream) {
|
||||
gint video_width = clapper_video_stream_get_width (vstream);
|
||||
gint video_height = clapper_video_stream_get_height (vstream);
|
||||
|
||||
if (G_LIKELY (video_width > 0 && video_height > 0)) {
|
||||
gint win_width, win_height, dest_width, dest_height;
|
||||
|
||||
gtk_window_get_default_size (GTK_WINDOW (self), &win_width, &win_height);
|
||||
|
||||
_calculate_win_resize (win_width, win_height,
|
||||
video_width, video_height, &dest_width, &dest_height);
|
||||
|
||||
/* Only begin resize when not already at perfect size */
|
||||
if (dest_width != win_width || dest_height != win_height) {
|
||||
ClapperAppWindowResizeData *resize_data;
|
||||
|
||||
resize_data = g_new0 (ClapperAppWindowResizeData, 1);
|
||||
resize_data->dest_width = dest_width;
|
||||
resize_data->dest_height = dest_height;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Window resize start, dest: %ix%i",
|
||||
resize_data->dest_width, resize_data->dest_height);
|
||||
|
||||
self->resize_tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self),
|
||||
(GtkTickCallback) _resize_tick, resize_data, g_free);
|
||||
}
|
||||
}
|
||||
|
||||
gst_object_unref (vstream);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_handle_middle_click (ClapperAppWindow *self, GtkGestureClick *click)
|
||||
{
|
||||
_resize_window (self);
|
||||
gtk_gesture_set_state (GTK_GESTURE (click), GTK_EVENT_SEQUENCE_CLAIMED);
|
||||
}
|
||||
|
||||
static void
|
||||
_handle_right_click (ClapperAppWindow *self, GtkGestureClick *click)
|
||||
{
|
||||
GdkSurface *surface;
|
||||
GdkEventSequence *sequence;
|
||||
@@ -267,6 +459,22 @@ right_click_released_cb (GtkGestureClick *click, gint n_press,
|
||||
gtk_gesture_set_state (GTK_GESTURE (click), GTK_EVENT_SEQUENCE_CLAIMED);
|
||||
}
|
||||
|
||||
static void
|
||||
click_released_cb (GtkGestureClick *click, gint n_press,
|
||||
gdouble x, gdouble y, ClapperAppWindow *self)
|
||||
{
|
||||
switch (gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (click))) {
|
||||
case GDK_BUTTON_MIDDLE:
|
||||
_handle_middle_click (self, click);
|
||||
break;
|
||||
case GDK_BUTTON_SECONDARY:
|
||||
_handle_right_click (self, click);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
drag_begin_cb (GtkGestureDrag *drag,
|
||||
gdouble start_x, gdouble start_y, ClapperAppWindow *self)
|
||||
@@ -866,6 +1074,23 @@ toggle_fullscreen (GSimpleAction *action, GVariant *param, gpointer user_data)
|
||||
video_toggle_fullscreen_cb (CLAPPER_GTK_VIDEO_CAST (self->video), self);
|
||||
}
|
||||
|
||||
static void
|
||||
unfullscreen (GSimpleAction *action, GVariant *param, gpointer user_data)
|
||||
{
|
||||
GtkWindow *window = GTK_WINDOW (user_data);
|
||||
|
||||
if (gtk_window_is_fullscreen (window)) {
|
||||
ClapperAppWindow *self = CLAPPER_APP_WINDOW_CAST (window);
|
||||
video_toggle_fullscreen_cb (CLAPPER_GTK_VIDEO_CAST (self->video), self);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
auto_resize (GSimpleAction *action, GVariant *param, gpointer user_data)
|
||||
{
|
||||
_resize_window (CLAPPER_APP_WINDOW_CAST (user_data));
|
||||
}
|
||||
|
||||
static void
|
||||
show_help_overlay (GSimpleAction *action, GVariant *param, gpointer user_data)
|
||||
{
|
||||
@@ -903,6 +1128,13 @@ clapper_app_window_get_player (ClapperAppWindow *self)
|
||||
return clapper_gtk_video_get_player (CLAPPER_GTK_VIDEO_CAST (self->video));
|
||||
}
|
||||
|
||||
ClapperAppWindowExtraOptions *
|
||||
clapper_app_window_get_extra_options (ClapperAppWindow *self)
|
||||
{
|
||||
return g_object_get_qdata ((GObject *) self,
|
||||
clapper_app_window_extra_options_get_quark ());
|
||||
}
|
||||
|
||||
void
|
||||
clapper_app_window_ensure_no_initial_state (ClapperAppWindow *self)
|
||||
{
|
||||
@@ -964,10 +1196,21 @@ clapper_app_window_unrealize (GtkWidget *widget)
|
||||
static void
|
||||
clapper_app_window_init (ClapperAppWindow *self)
|
||||
{
|
||||
ClapperAppWindowExtraOptions *extra_opts;
|
||||
GtkSettings *settings;
|
||||
GtkWidget *dummy_titlebar;
|
||||
gint distance = 0;
|
||||
|
||||
gtk_widget_set_size_request (GTK_WIDGET (self),
|
||||
MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT);
|
||||
|
||||
extra_opts = g_new0 (ClapperAppWindowExtraOptions, 1);
|
||||
GST_TRACE ("Created window extra options: %p", extra_opts);
|
||||
|
||||
g_object_set_qdata_full ((GObject *) self,
|
||||
clapper_app_window_extra_options_get_quark (),
|
||||
extra_opts, (GDestroyNotify) clapper_app_window_extra_options_free);
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
/* Make double tap easier to perform */
|
||||
@@ -1001,20 +1244,26 @@ clapper_app_window_constructed (GObject *object)
|
||||
|
||||
static const GActionEntry win_entries[] = {
|
||||
{ "toggle-fullscreen", toggle_fullscreen, NULL, NULL, NULL },
|
||||
{ "unfullscreen", unfullscreen, NULL, NULL, NULL },
|
||||
{ "auto-resize", auto_resize, NULL, NULL, NULL },
|
||||
{ "show-help-overlay", show_help_overlay, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
#if (CLAPPER_HAVE_MPRIS || CLAPPER_HAVE_SERVER || CLAPPER_HAVE_DISCOVERER)
|
||||
ClapperFeature *feature = NULL;
|
||||
#endif
|
||||
#if CLAPPER_HAVE_MPRIS
|
||||
gchar mpris_name[45];
|
||||
g_snprintf (mpris_name, sizeof (mpris_name),
|
||||
"org.mpris.MediaPlayer2.Clapper.instance%" G_GUINT16_FORMAT, instance_count++);
|
||||
#endif
|
||||
|
||||
self->settings = g_settings_new (CLAPPER_APP_ID);
|
||||
self->last_volume = PERCENTAGE_ROUND (g_settings_get_double (self->settings, "volume"));
|
||||
|
||||
#if CLAPPER_HAVE_MPRIS
|
||||
feature = CLAPPER_FEATURE (clapper_mpris_new (
|
||||
"org.mpris.MediaPlayer2.Clapper",
|
||||
"Clapper", CLAPPER_APP_ID));
|
||||
mpris_name, CLAPPER_APP_NAME, CLAPPER_APP_ID));
|
||||
clapper_mpris_set_queue_controllable (CLAPPER_MPRIS (feature), TRUE);
|
||||
clapper_player_add_feature (player, feature);
|
||||
gst_object_unref (feature);
|
||||
@@ -1040,10 +1289,12 @@ clapper_app_window_constructed (GObject *object)
|
||||
|
||||
clapper_player_set_autoplay (player, TRUE);
|
||||
|
||||
/* No need to also call this here, as item is selected
|
||||
/* No need to also call these here, as they only change
|
||||
* after application window is contructed */
|
||||
g_signal_connect (queue, "notify::current-item",
|
||||
G_CALLBACK (_queue_current_item_changed_cb), self);
|
||||
g_signal_connect (player, "notify::adaptive-bandwidth",
|
||||
G_CALLBACK (_player_adaptive_bandwidth_changed_cb), NULL);
|
||||
|
||||
g_settings_bind (self->settings, "audio-offset",
|
||||
player, "audio-offset", G_SETTINGS_BIND_GET);
|
||||
@@ -1081,6 +1332,11 @@ clapper_app_window_dispose (GObject *object)
|
||||
{
|
||||
ClapperAppWindow *self = CLAPPER_APP_WINDOW_CAST (object);
|
||||
|
||||
if (self->resize_tick_id != 0) {
|
||||
gtk_widget_remove_tick_callback (GTK_WIDGET (self), self->resize_tick_id);
|
||||
self->resize_tick_id = 0;
|
||||
}
|
||||
|
||||
g_clear_handle_id (&self->seek_timeout, g_source_remove);
|
||||
|
||||
gtk_widget_dispose_template (GTK_WIDGET (object), CLAPPER_APP_TYPE_WINDOW);
|
||||
@@ -1140,8 +1396,8 @@ clapper_app_window_class_init (ClapperAppWindowClass *klass)
|
||||
gtk_widget_class_bind_template_callback (widget_class, key_pressed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, key_released_cb);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, right_click_pressed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, right_click_released_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, click_pressed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, click_released_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, drag_begin_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, drag_update_cb);
|
||||
|
||||
|
@@ -27,6 +27,15 @@ G_BEGIN_DECLS
|
||||
#define CLAPPER_APP_TYPE_WINDOW (clapper_app_window_get_type())
|
||||
#define CLAPPER_APP_WINDOW_CAST(obj) ((ClapperAppWindow *)(obj))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gchar *video_filter;
|
||||
gchar *audio_filter;
|
||||
|
||||
gchar *video_sink;
|
||||
gchar *audio_sink;
|
||||
} ClapperAppWindowExtraOptions;
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ClapperAppWindow, clapper_app_window, CLAPPER_APP, WINDOW, GtkApplicationWindow)
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
@@ -38,6 +47,9 @@ GtkWidget * clapper_app_window_get_video (ClapperAppWindow *window);
|
||||
G_GNUC_INTERNAL
|
||||
ClapperPlayer * clapper_app_window_get_player (ClapperAppWindow *window);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
ClapperAppWindowExtraOptions * clapper_app_window_get_extra_options (ClapperAppWindow *window);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_app_window_ensure_no_initial_state (ClapperAppWindow *window);
|
||||
|
||||
|
@@ -7,6 +7,7 @@
|
||||
<file preprocess="xml-stripblanks">ui/clapper-app-headerbar.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/clapper-app-help-overlay.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/clapper-app-info-window.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/clapper-app-pipeline-window.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/clapper-app-queue-list.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/clapper-app-queue-list-item.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/clapper-app-queue-progression-item.ui</file>
|
||||
|
@@ -1,8 +1,3 @@
|
||||
window.app {
|
||||
min-width: 352px;
|
||||
min-height: 198px;
|
||||
}
|
||||
|
||||
window .initialstate {
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
@@ -23,6 +18,10 @@ window.info .subcontent streamlist preferencesgroup {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
window.pipeline scrolledwindow {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
window.preferences .subcontent {
|
||||
margin: 16px;
|
||||
}
|
||||
|
@@ -14,3 +14,8 @@ Type=Application
|
||||
Keywords=Video;Movie;Film;Clip;Series;Player;Playlist;DVD;TV;Disc;Album;Music;GNOME;Clapper;
|
||||
# Translators: Do NOT translate or transliterate this text (these are enum types)!
|
||||
X-Purism-FormFactor=Workstation;Mobile;
|
||||
Actions=new-window;
|
||||
|
||||
[Desktop Action new-window]
|
||||
Name=New Window
|
||||
Exec=clapper --new-window
|
||||
|
@@ -49,6 +49,10 @@
|
||||
<default>1.0</default>
|
||||
<summary>Stores last speed value to apply on startup</summary>
|
||||
</key>
|
||||
<key name="adaptive-start-bitrate" type="i">
|
||||
<default>1600000</default>
|
||||
<summary>Stores initial adaptive streaming bitrate to apply on startup</summary>
|
||||
</key>
|
||||
<key name="progression-mode" type="i">
|
||||
<default>1</default>
|
||||
<summary>Stores last queue progression mode used to apply on startup</summary>
|
||||
|
@@ -1,7 +1,3 @@
|
||||
if not ['linux'].contains(host_machine.system())
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
appstream_util = find_program('appstream-util', required: false)
|
||||
if appstream_util.found()
|
||||
test('Validate appstream file',
|
||||
@@ -29,22 +25,31 @@ endif
|
||||
install_subdir('icons',
|
||||
install_dir: join_paths(prefix, datadir)
|
||||
)
|
||||
install_subdir('mime',
|
||||
install_dir: join_paths(prefix, datadir)
|
||||
)
|
||||
install_subdir('applications',
|
||||
install_dir: join_paths(prefix, datadir)
|
||||
)
|
||||
install_subdir('metainfo',
|
||||
install_dir: join_paths(prefix, datadir)
|
||||
)
|
||||
|
||||
is_linux = ['linux'].contains(host_machine.system())
|
||||
is_windows = ['windows'].contains(host_machine.system())
|
||||
|
||||
if is_linux
|
||||
install_subdir('applications',
|
||||
install_dir: join_paths(prefix, datadir)
|
||||
)
|
||||
subdir('dbus-1')
|
||||
endif
|
||||
|
||||
if not is_windows
|
||||
install_subdir('mime',
|
||||
install_dir: join_paths(prefix, datadir)
|
||||
)
|
||||
endif
|
||||
|
||||
subdir('glib-2.0/schemas')
|
||||
subdir('dbus-1')
|
||||
|
||||
gnome.post_install(
|
||||
glib_compile_schemas: true,
|
||||
gtk_update_icon_cache: true,
|
||||
update_desktop_database: true,
|
||||
update_mime_database: true,
|
||||
update_desktop_database: is_linux,
|
||||
update_mime_database: not is_windows,
|
||||
)
|
||||
|
@@ -59,11 +59,6 @@
|
||||
<category>Video</category>
|
||||
</categories>
|
||||
<releases>
|
||||
<release version="0.6.1" date="2024-07-01">
|
||||
<description>
|
||||
<p>Bug fixes and translation updates</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.6.0" date="2024-04-22">
|
||||
<description>
|
||||
<p>
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include <clapper/clapper.h>
|
||||
|
||||
#include "clapper-app-application.h"
|
||||
#include "clapper-app-types.h"
|
||||
|
||||
gint
|
||||
main (gint argc, gchar **argv)
|
||||
@@ -46,6 +47,8 @@ main (gint argc, gchar **argv)
|
||||
gtk_init ();
|
||||
adw_init ();
|
||||
|
||||
clapper_app_types_init ();
|
||||
|
||||
g_set_application_name ("Clapper");
|
||||
|
||||
application = clapper_app_application_new ();
|
||||
|
@@ -15,6 +15,10 @@ clapperapp_deps = [
|
||||
libadwaita_dep,
|
||||
glib_dep,
|
||||
gobject_dep,
|
||||
libm,
|
||||
dependency('libcgraph', required: false),
|
||||
dependency('libgvc', required: false),
|
||||
dependency('librsvg-2.0', version: '>= 2.52', required: false),
|
||||
]
|
||||
|
||||
foreach dep : clapperapp_deps
|
||||
@@ -61,12 +65,15 @@ clapperapp_sources = [
|
||||
'clapper-app-info-window.c',
|
||||
'clapper-app-list-item-utils.c',
|
||||
'clapper-app-media-item-box.c',
|
||||
'clapper-app-pipeline-viewer.c',
|
||||
'clapper-app-pipeline-window.c',
|
||||
'clapper-app-preferences-window.c',
|
||||
'clapper-app-property-row.c',
|
||||
'clapper-app-queue-list.c',
|
||||
'clapper-app-queue-progression-item.c',
|
||||
'clapper-app-queue-progression-model.c',
|
||||
'clapper-app-queue-selection.c',
|
||||
'clapper-app-types.c',
|
||||
'clapper-app-uri-dialog.c',
|
||||
'clapper-app-utils.c',
|
||||
'clapper-app-window.c',
|
||||
@@ -87,5 +94,18 @@ executable(
|
||||
c_args: clapperapp_c_args,
|
||||
install: true,
|
||||
install_dir: bindir,
|
||||
win_subsystem: 'windows',
|
||||
)
|
||||
if ['windows'].contains(host_machine.system())
|
||||
executable(
|
||||
meson.project_name() + '-console',
|
||||
clapperapp_sources,
|
||||
dependencies: clapperapp_deps,
|
||||
include_directories: clapperapp_conf_inc,
|
||||
c_args: clapperapp_c_args,
|
||||
install: true,
|
||||
install_dir: bindir,
|
||||
win_subsystem: 'console',
|
||||
)
|
||||
endif
|
||||
build_clapperapp = true
|
||||
|
@@ -10,6 +10,7 @@ src/bin/clapper-app/ui/clapper-app-uri-dialog.ui
|
||||
src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui
|
||||
|
||||
src/bin/clapper-app/clapper-app-about-window.c
|
||||
src/bin/clapper-app/clapper-app-application.c
|
||||
src/bin/clapper-app/clapper-app-info-window.c
|
||||
src/bin/clapper-app/clapper-app-list-item-utils.c
|
||||
src/bin/clapper-app/clapper-app-preferences-window.c
|
||||
|
@@ -3,7 +3,7 @@ msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-04-21 20:22+0200\n"
|
||||
"PO-Revision-Date: 2024-04-21 20:51\n"
|
||||
"PO-Revision-Date: 2024-08-12 08:36\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Czech\n"
|
||||
"Language: cs_CZ\n"
|
||||
@@ -20,7 +20,7 @@ msgstr ""
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:14
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:14
|
||||
msgid "Codec"
|
||||
msgstr ""
|
||||
msgstr "Kodek"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:24
|
||||
msgid "Channels"
|
||||
@@ -28,21 +28,21 @@ msgstr "Kanály"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:36
|
||||
msgid "Sample Format"
|
||||
msgstr ""
|
||||
msgstr "Vzorkovací Formát"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:46
|
||||
msgid "Sample Rate"
|
||||
msgstr ""
|
||||
msgstr "Vzorkovací Frekvence"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:58
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:51
|
||||
msgid "Bitrate"
|
||||
msgstr ""
|
||||
msgstr "Datový Tok"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:70
|
||||
#: src/bin/clapper-app/ui/clapper-app-subtitle-stream-list-item.ui:24
|
||||
msgid "Language"
|
||||
msgstr ""
|
||||
msgstr "Jazyk"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-headerbar.ui:183
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:80
|
||||
@@ -52,7 +52,7 @@ msgstr "Předvolby"
|
||||
#: src/bin/clapper-app/ui/clapper-app-headerbar.ui:187
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:84
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Klávesové Zkratky"
|
||||
|
||||
#. TRANSLATORS: Please do not translate application name
|
||||
#: src/bin/clapper-app/ui/clapper-app-headerbar.ui:194
|
||||
@@ -71,7 +71,7 @@ msgstr "Zobrazit klávesové zkratky"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:19
|
||||
msgid "Open preferences"
|
||||
msgstr ""
|
||||
msgstr "Otevřít předvolby"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:25
|
||||
msgid "Toggle fullscreen"
|
||||
@@ -94,17 +94,17 @@ msgstr "Média"
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:55
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:178
|
||||
msgid "Add Files…"
|
||||
msgstr ""
|
||||
msgstr "Přidat Soubory…"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:49
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:65
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:182
|
||||
msgid "Add URI…"
|
||||
msgstr ""
|
||||
msgstr "Přidat URI…"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:57
|
||||
msgid "Queue"
|
||||
msgstr ""
|
||||
msgstr "Fronta"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:61
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:68
|
||||
@@ -118,7 +118,7 @@ msgstr "Předchozí položka"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:88
|
||||
msgid "Change progression mode"
|
||||
msgstr ""
|
||||
msgstr "Změnit způsob postupování"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:96
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:76
|
||||
@@ -131,7 +131,7 @@ msgstr "Přepnout přehrávání"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:100
|
||||
msgid "Tap | Left click"
|
||||
msgstr ""
|
||||
msgstr "Klepnutím | Levým tlačítkem"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:107
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:115
|
||||
@@ -141,12 +141,12 @@ msgstr "Přetočit vpřed"
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:108
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:132
|
||||
msgid "Double tap (right side) | Scroll right"
|
||||
msgstr ""
|
||||
msgstr "Dvojitě klepnout (pravá strana) | Posun vpravo"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:116
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:124
|
||||
msgid "Double tap (left side) | Scroll left"
|
||||
msgstr ""
|
||||
msgstr "Dvojitě klepnout (levá strana) | Posun vlevo"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:123
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:131
|
||||
@@ -159,7 +159,7 @@ msgstr "Zesílit"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:139
|
||||
msgid "Scroll up"
|
||||
msgstr ""
|
||||
msgstr "Posun nahoru"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:145
|
||||
msgid "Volume down"
|
||||
@@ -167,7 +167,7 @@ msgstr "Zeslabit"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:146
|
||||
msgid "Scroll down"
|
||||
msgstr ""
|
||||
msgstr "Posun dolů"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:152
|
||||
msgid "Toggle mute"
|
||||
@@ -175,11 +175,11 @@ msgstr "Vypnout/zapnout zvuk"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:158
|
||||
msgid "Speed up"
|
||||
msgstr ""
|
||||
msgstr "Zrychlit"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:164
|
||||
msgid "Speed down"
|
||||
msgstr ""
|
||||
msgstr "Zpomalit"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:171
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:178
|
||||
@@ -193,7 +193,7 @@ msgstr "Předchozí kapitola"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:13
|
||||
msgid "Info"
|
||||
msgstr ""
|
||||
msgstr "Informace"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:35
|
||||
#: src/bin/clapper-app/ui/clapper-app-subtitle-stream-list-item.ui:14
|
||||
@@ -202,20 +202,20 @@ msgstr "Název"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:49
|
||||
msgid "Container Format"
|
||||
msgstr ""
|
||||
msgstr "Formát Kontejneru"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:63
|
||||
msgid "Duration"
|
||||
msgstr ""
|
||||
msgstr "Doba Trvání"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:81
|
||||
msgid "Streams"
|
||||
msgstr ""
|
||||
msgstr "Kanály"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:84
|
||||
#: src/bin/clapper-app/clapper-app-list-item-utils.c:36
|
||||
msgid "Video"
|
||||
msgstr ""
|
||||
msgstr "Video"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:107
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:80
|
||||
@@ -231,42 +231,42 @@ msgstr "Titulky"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:155
|
||||
msgid "Video Playback"
|
||||
msgstr ""
|
||||
msgstr "Přehrávání Videa"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:158
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:199
|
||||
msgid "Decoder"
|
||||
msgstr ""
|
||||
msgstr "Dekodér"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:170
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:211
|
||||
msgid "Filter"
|
||||
msgstr ""
|
||||
msgstr "Filtr"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:182
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:223
|
||||
msgid "Sink"
|
||||
msgstr ""
|
||||
msgstr "Sink"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:196
|
||||
msgid "Audio Playback"
|
||||
msgstr ""
|
||||
msgstr "Přehrávání Audia"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:247
|
||||
msgid "Video Streams"
|
||||
msgstr ""
|
||||
msgstr "Video Kanály"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:290
|
||||
msgid "Audio Streams"
|
||||
msgstr ""
|
||||
msgstr "Audio Kanály"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:333
|
||||
msgid "Subtitle Streams"
|
||||
msgstr ""
|
||||
msgstr "Titulkové Kanály"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:46
|
||||
msgid "Start by adding media to playback queue"
|
||||
msgstr ""
|
||||
msgstr "Začněte přidáním média do přehrávací fronty"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:15
|
||||
msgid "Seeking"
|
||||
@@ -274,11 +274,11 @@ msgstr "Přetáčení"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:18
|
||||
msgid "Method"
|
||||
msgstr ""
|
||||
msgstr "Způsob"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:19
|
||||
msgid "A preferred method used for seeking"
|
||||
msgstr ""
|
||||
msgstr "Upřednostňovaný způsob použitý pro přetáčení"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:32
|
||||
msgid "Value"
|
||||
@@ -286,7 +286,7 @@ msgstr "Hodnota"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:33
|
||||
msgid "Value used for seeking forward/backward"
|
||||
msgstr ""
|
||||
msgstr "Hodnota použitá pro přetáčení dopředu/dozadu"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:46
|
||||
msgid "Unit"
|
||||
@@ -294,7 +294,7 @@ msgstr "Jednotka"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:47
|
||||
msgid "An unit of a seek forward/backward value"
|
||||
msgstr ""
|
||||
msgstr "Jednotka hodnoty pro přetáčení dopředu/dozadu"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:51
|
||||
msgid "Second"
|
||||
@@ -310,7 +310,7 @@ msgstr "Procenta"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:63
|
||||
msgid "Features"
|
||||
msgstr ""
|
||||
msgstr "Funkce"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:66
|
||||
msgid "Server"
|
||||
@@ -323,15 +323,15 @@ msgstr "Vzdáleně ovládat přehrávač"
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:83
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:103
|
||||
msgid "Offset"
|
||||
msgstr ""
|
||||
msgstr "Posun"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:84
|
||||
msgid "Synchronisation offset in seconds between the audio and video streams"
|
||||
msgstr ""
|
||||
msgstr "Synchronizační posun v sekundách mezi audio a video kanály"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:104
|
||||
msgid "Synchronisation offset in seconds between the subtitle and video streams"
|
||||
msgstr ""
|
||||
msgstr "Synchronizační posun v sekundách mezi titulkovými a video kanály"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:118
|
||||
msgid "Default font"
|
||||
@@ -339,7 +339,7 @@ msgstr "Výchozí styl písma"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:119
|
||||
msgid "Text font used for subtitles when media does not explicitly specify one"
|
||||
msgstr ""
|
||||
msgstr "Písmo používané pro titulky, když jej médium výslovně neupřesní"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:137
|
||||
msgid "Tweaks"
|
||||
@@ -355,48 +355,48 @@ msgstr "Změna výchozího pořadí zásuvných modulů GStreameru"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:164
|
||||
msgid "Plugin Ranking"
|
||||
msgstr ""
|
||||
msgstr "Pořadí Pluginů"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:182
|
||||
msgid "Available plugins"
|
||||
msgstr ""
|
||||
msgstr "Dostupné pluginy"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:183
|
||||
msgid "Select a plugin and its feature to override rank for. When multiple elements have similiar capabilities, the one with highest value is preferred."
|
||||
msgstr ""
|
||||
msgstr "Vyberte plugin a jeho funkci, pro kterou chcete přepsat pořadí. Pokud má více prvků podobnou schopnost, je preferována ta s nejvyšší hodnotou."
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:186
|
||||
msgid "Plugin"
|
||||
msgstr ""
|
||||
msgstr "Plugin"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:195
|
||||
msgid "Plugin feature"
|
||||
msgstr ""
|
||||
msgstr "Funkce pluginy"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:213
|
||||
msgid "Add override"
|
||||
msgstr ""
|
||||
msgstr "Přidat přepsání"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:229
|
||||
msgid "Rank overrides"
|
||||
msgstr ""
|
||||
msgstr "Pořadí přepsání"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:60
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:23
|
||||
msgid "Add"
|
||||
msgstr ""
|
||||
msgstr "Přidat"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:87
|
||||
msgid "Queue progression"
|
||||
msgstr ""
|
||||
msgstr "Postup fronty"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:6
|
||||
msgid "Add URI"
|
||||
msgstr ""
|
||||
msgstr "Přidat URI"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:7
|
||||
msgid "Insert an URI to be added to playback queue"
|
||||
msgstr ""
|
||||
msgstr "Vložte URI, která bude přidána do fronty přehrávání"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:18
|
||||
msgid "Enter or drop URI here"
|
||||
@@ -408,15 +408,15 @@ msgstr "Zrušit"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:24
|
||||
msgid "Resolution"
|
||||
msgstr ""
|
||||
msgstr "Rozlišení"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:39
|
||||
msgid "Framerate"
|
||||
msgstr ""
|
||||
msgstr "Snímky za sekundu"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:63
|
||||
msgid "Pixel Format"
|
||||
msgstr ""
|
||||
msgstr "Formát Pixelu"
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/bin/clapper-app/clapper-app-about-window.c:43
|
||||
@@ -425,11 +425,11 @@ msgstr "Vojtěch Perník <translations@pervoj.cz>"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-info-window.c:86
|
||||
msgid "Hardware"
|
||||
msgstr ""
|
||||
msgstr "Hardware"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-info-window.c:86
|
||||
msgid "Software"
|
||||
msgstr ""
|
||||
msgstr "Software"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-preferences-window.c:441
|
||||
msgid "Accurate"
|
||||
@@ -445,25 +445,25 @@ msgstr "Rychlý"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:66
|
||||
msgid "No progression"
|
||||
msgstr ""
|
||||
msgstr "Žádný postup"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:67
|
||||
msgid "Consecutive"
|
||||
msgstr ""
|
||||
msgstr "Po sobě"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:68
|
||||
msgid "Repeat item"
|
||||
msgstr ""
|
||||
msgstr "Opakovat položku"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:69
|
||||
msgid "Carousel"
|
||||
msgstr ""
|
||||
msgstr "Opakovat frontu"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:70
|
||||
msgid "Shuffle"
|
||||
msgstr ""
|
||||
msgstr "Náhodně"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-window.c:828
|
||||
msgid "Drop on title bar to play now or anywhere else to enqueue."
|
||||
msgstr ""
|
||||
msgstr "Přetáhněte na titulní lištu pro okamžité přehrání nebo kdekoliv jinde pro zařazení."
|
||||
|
||||
|
@@ -3,7 +3,7 @@ msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-04-21 20:22+0200\n"
|
||||
"PO-Revision-Date: 2024-04-21 20:51\n"
|
||||
"PO-Revision-Date: 2024-09-07 11:10\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Persian\n"
|
||||
"Language: fa_IR\n"
|
||||
@@ -20,7 +20,7 @@ msgstr ""
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:14
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:14
|
||||
msgid "Codec"
|
||||
msgstr ""
|
||||
msgstr "رمزینه"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:24
|
||||
msgid "Channels"
|
||||
@@ -28,21 +28,21 @@ msgstr "کانالها"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:36
|
||||
msgid "Sample Format"
|
||||
msgstr ""
|
||||
msgstr "قالب نمونه"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:46
|
||||
msgid "Sample Rate"
|
||||
msgstr ""
|
||||
msgstr "نرخ نمونه"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:58
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:51
|
||||
msgid "Bitrate"
|
||||
msgstr ""
|
||||
msgstr "نرخ بیت"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:70
|
||||
#: src/bin/clapper-app/ui/clapper-app-subtitle-stream-list-item.ui:24
|
||||
msgid "Language"
|
||||
msgstr ""
|
||||
msgstr "زبان"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-headerbar.ui:183
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:80
|
||||
@@ -52,13 +52,13 @@ msgstr "ترجیحات"
|
||||
#: src/bin/clapper-app/ui/clapper-app-headerbar.ui:187
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:84
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr ""
|
||||
msgstr "میانبرهای صفحهکلید"
|
||||
|
||||
#. TRANSLATORS: Please do not translate application name
|
||||
#: src/bin/clapper-app/ui/clapper-app-headerbar.ui:194
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:91
|
||||
msgid "About Clapper"
|
||||
msgstr "دربارهٔ کلَپِر"
|
||||
msgstr "دربارهٔ کلپِر"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:10
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:11
|
||||
@@ -71,7 +71,7 @@ msgstr "نمایش میانبرها"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:19
|
||||
msgid "Open preferences"
|
||||
msgstr ""
|
||||
msgstr "گشودن ترجیحات"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:25
|
||||
msgid "Toggle fullscreen"
|
||||
@@ -94,17 +94,17 @@ msgstr "رسانه"
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:55
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:178
|
||||
msgid "Add Files…"
|
||||
msgstr ""
|
||||
msgstr "افزودن پروندهها…"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:49
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:65
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:182
|
||||
msgid "Add URI…"
|
||||
msgstr ""
|
||||
msgstr "افزودن نشانی…"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:57
|
||||
msgid "Queue"
|
||||
msgstr ""
|
||||
msgstr "صف"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:61
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:68
|
||||
@@ -118,7 +118,7 @@ msgstr "مورد قبل"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:88
|
||||
msgid "Change progression mode"
|
||||
msgstr ""
|
||||
msgstr "تغییر خالت پیشرفت"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:96
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:76
|
||||
@@ -131,7 +131,7 @@ msgstr "تغییر پخش"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:100
|
||||
msgid "Tap | Left click"
|
||||
msgstr ""
|
||||
msgstr "ضربه | کلیک راست"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:107
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:115
|
||||
@@ -141,12 +141,12 @@ msgstr "پیمایش به جلو"
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:108
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:132
|
||||
msgid "Double tap (right side) | Scroll right"
|
||||
msgstr ""
|
||||
msgstr "دوبار ضربه (سمت راست) | لغزش راست"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:116
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:124
|
||||
msgid "Double tap (left side) | Scroll left"
|
||||
msgstr ""
|
||||
msgstr "دوبار ضربه (سمت چپ) | لغزش چپ"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:123
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:131
|
||||
@@ -159,7 +159,7 @@ msgstr "افزایش صدا"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:139
|
||||
msgid "Scroll up"
|
||||
msgstr ""
|
||||
msgstr "لغزش به بالا"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:145
|
||||
msgid "Volume down"
|
||||
@@ -167,7 +167,7 @@ msgstr "کاهش صدا"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:146
|
||||
msgid "Scroll down"
|
||||
msgstr ""
|
||||
msgstr "لغزش به پایین"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:152
|
||||
msgid "Toggle mute"
|
||||
@@ -175,11 +175,11 @@ msgstr "تغییر وضعیت بیصدا"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:158
|
||||
msgid "Speed up"
|
||||
msgstr ""
|
||||
msgstr "سرعت بخشیدن"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:164
|
||||
msgid "Speed down"
|
||||
msgstr ""
|
||||
msgstr "کاهش سرعت"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:171
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:178
|
||||
@@ -193,7 +193,7 @@ msgstr "بخش قبلی"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:13
|
||||
msgid "Info"
|
||||
msgstr ""
|
||||
msgstr "اطّلاعات"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:35
|
||||
#: src/bin/clapper-app/ui/clapper-app-subtitle-stream-list-item.ui:14
|
||||
@@ -202,26 +202,26 @@ msgstr "عنوان"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:49
|
||||
msgid "Container Format"
|
||||
msgstr ""
|
||||
msgstr "قالب بارگنج"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:63
|
||||
msgid "Duration"
|
||||
msgstr ""
|
||||
msgstr "مدّت"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:81
|
||||
msgid "Streams"
|
||||
msgstr ""
|
||||
msgstr "جریانها"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:84
|
||||
#: src/bin/clapper-app/clapper-app-list-item-utils.c:36
|
||||
msgid "Video"
|
||||
msgstr ""
|
||||
msgstr "ویدیو"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:107
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:80
|
||||
#: src/bin/clapper-app/clapper-app-list-item-utils.c:39
|
||||
msgid "Audio"
|
||||
msgstr "صوتی"
|
||||
msgstr "صدا"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:130
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:100
|
||||
@@ -231,42 +231,42 @@ msgstr "زیرنویسها"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:155
|
||||
msgid "Video Playback"
|
||||
msgstr ""
|
||||
msgstr "پخش ویدیو"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:158
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:199
|
||||
msgid "Decoder"
|
||||
msgstr ""
|
||||
msgstr "رمزگشا"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:170
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:211
|
||||
msgid "Filter"
|
||||
msgstr ""
|
||||
msgstr "پالایه"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:182
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:223
|
||||
msgid "Sink"
|
||||
msgstr ""
|
||||
msgstr "سینک"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:196
|
||||
msgid "Audio Playback"
|
||||
msgstr ""
|
||||
msgstr "پخش صدا"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:247
|
||||
msgid "Video Streams"
|
||||
msgstr ""
|
||||
msgstr "جریانهای ویدیویی"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:290
|
||||
msgid "Audio Streams"
|
||||
msgstr ""
|
||||
msgstr "جریانهای صوتی"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:333
|
||||
msgid "Subtitle Streams"
|
||||
msgstr ""
|
||||
msgstr "جریانهای زیرنویس"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:46
|
||||
msgid "Start by adding media to playback queue"
|
||||
msgstr ""
|
||||
msgstr "آغزا با افزودن رسانه به صف پخش"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:15
|
||||
msgid "Seeking"
|
||||
@@ -274,11 +274,11 @@ msgstr "پوییدن"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:18
|
||||
msgid "Method"
|
||||
msgstr ""
|
||||
msgstr "روش"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:19
|
||||
msgid "A preferred method used for seeking"
|
||||
msgstr ""
|
||||
msgstr "روشی ترجیحی برای جویش"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:32
|
||||
msgid "Value"
|
||||
@@ -286,7 +286,7 @@ msgstr "مقدار"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:33
|
||||
msgid "Value used for seeking forward/backward"
|
||||
msgstr ""
|
||||
msgstr "یکای استفاده شده برای جویش به پیش و پ"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:46
|
||||
msgid "Unit"
|
||||
@@ -294,7 +294,7 @@ msgstr "واحد"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:47
|
||||
msgid "An unit of a seek forward/backward value"
|
||||
msgstr ""
|
||||
msgstr "یکای مقدار جویش به پیش و پس"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:51
|
||||
msgid "Second"
|
||||
@@ -310,97 +310,97 @@ msgstr "درصد"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:63
|
||||
msgid "Features"
|
||||
msgstr ""
|
||||
msgstr "ویژگیها"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:66
|
||||
msgid "Server"
|
||||
msgstr "سرور"
|
||||
msgstr "کارساز"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:67
|
||||
msgid "Control player remotely"
|
||||
msgstr "کنترل پخشکننده از راه دور"
|
||||
msgstr "واپایش پخشکننده از راه دور"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:83
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:103
|
||||
msgid "Offset"
|
||||
msgstr ""
|
||||
msgstr "انحراف از مبدأ"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:84
|
||||
msgid "Synchronisation offset in seconds between the audio and video streams"
|
||||
msgstr ""
|
||||
msgstr "همگامسازی انحراف از مبدأ به ثانیه بین جریانهای ویدیو و صدا"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:104
|
||||
msgid "Synchronisation offset in seconds between the subtitle and video streams"
|
||||
msgstr ""
|
||||
msgstr "همگامسازی انحراف از مبدأ به ثانیه بین جریانهای ویدیو و زیرنویس"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:118
|
||||
msgid "Default font"
|
||||
msgstr "قلم پیش فرض"
|
||||
msgstr "قلم پیشگزیده"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:119
|
||||
msgid "Text font used for subtitles when media does not explicitly specify one"
|
||||
msgstr ""
|
||||
msgstr "قلم متن استفاده شده برای زیرنویس هنگامی که رسانه قلمی خاص را مشخّص نکرده"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:137
|
||||
msgid "Tweaks"
|
||||
msgstr "دستكاري"
|
||||
msgstr "سیخونکها"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:144
|
||||
msgid "Plugin ranking"
|
||||
msgstr "پیکربندی پلاگین"
|
||||
msgstr "رتبه دهی افزایه"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:145
|
||||
msgid "Alter default ranks of GStreamer plugins"
|
||||
msgstr "تغییر پیکربندی پیش فرض پلاگین های GStreamer"
|
||||
msgstr "تغییر رتبه دهی پیشگزیده برای افزایههای جیاستریمر"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:164
|
||||
msgid "Plugin Ranking"
|
||||
msgstr ""
|
||||
msgstr "رتبه دهی افزایه"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:182
|
||||
msgid "Available plugins"
|
||||
msgstr ""
|
||||
msgstr "افزایههای موجود"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:183
|
||||
msgid "Select a plugin and its feature to override rank for. When multiple elements have similiar capabilities, the one with highest value is preferred."
|
||||
msgstr ""
|
||||
msgstr "گزینش افزایه و ویژگیش برای پایمالی رتبه دهیش. هنگامی که چندین عنصر قابلیتّای مشابهی دارند، آنی که بیشترین رتبه را دارد ترجیح داده میشود."
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:186
|
||||
msgid "Plugin"
|
||||
msgstr ""
|
||||
msgstr "افزایه"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:195
|
||||
msgid "Plugin feature"
|
||||
msgstr ""
|
||||
msgstr "ویژگی افزایه"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:213
|
||||
msgid "Add override"
|
||||
msgstr ""
|
||||
msgstr "افزودن پایمالی"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:229
|
||||
msgid "Rank overrides"
|
||||
msgstr ""
|
||||
msgstr "پایمالیهای رتبه دهی"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:60
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:23
|
||||
msgid "Add"
|
||||
msgstr ""
|
||||
msgstr "افزودن"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:87
|
||||
msgid "Queue progression"
|
||||
msgstr ""
|
||||
msgstr "پیشرفت صف"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:6
|
||||
msgid "Add URI"
|
||||
msgstr ""
|
||||
msgstr "افزودن نشانی"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:7
|
||||
msgid "Insert an URI to be added to playback queue"
|
||||
msgstr ""
|
||||
msgstr "درج نشانی برای افزودن به صف پخش"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:18
|
||||
msgid "Enter or drop URI here"
|
||||
msgstr "رها کردن یا واردکردن URI"
|
||||
msgstr "ورود یا انداختن ناشنی"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:22
|
||||
msgid "Cancel"
|
||||
@@ -408,32 +408,33 @@ msgstr "لغو"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:24
|
||||
msgid "Resolution"
|
||||
msgstr ""
|
||||
msgstr "تفکیکپذیری"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:39
|
||||
msgid "Framerate"
|
||||
msgstr ""
|
||||
msgstr "نرخ قاب"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:63
|
||||
msgid "Pixel Format"
|
||||
msgstr ""
|
||||
msgstr "قالب پیکسلی"
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/bin/clapper-app/clapper-app-about-window.c:43
|
||||
msgid "translator-credits"
|
||||
msgstr "سجاد موسوی نژاد <ssmns@outlook.com>"
|
||||
msgstr "سجاد موسوی نژاد <ssmns@outlook.com>\n"
|
||||
"دانیال بهزادی <dani.behzi@ubuntu.com>"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-info-window.c:86
|
||||
msgid "Hardware"
|
||||
msgstr ""
|
||||
msgstr "سختافزاری"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-info-window.c:86
|
||||
msgid "Software"
|
||||
msgstr ""
|
||||
msgstr "نرمافزاری"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-preferences-window.c:441
|
||||
msgid "Accurate"
|
||||
msgstr "دقت"
|
||||
msgstr "دقیق"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-preferences-window.c:443
|
||||
msgid "Normal"
|
||||
@@ -445,25 +446,25 @@ msgstr "تند"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:66
|
||||
msgid "No progression"
|
||||
msgstr ""
|
||||
msgstr "بدون پیشرفت"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:67
|
||||
msgid "Consecutive"
|
||||
msgstr ""
|
||||
msgstr "متوالی"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:68
|
||||
msgid "Repeat item"
|
||||
msgstr ""
|
||||
msgstr "تکرار مورد"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:69
|
||||
msgid "Carousel"
|
||||
msgstr ""
|
||||
msgstr "چرخ فلک"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:70
|
||||
msgid "Shuffle"
|
||||
msgstr ""
|
||||
msgstr "بر زدن"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-window.c:828
|
||||
msgid "Drop on title bar to play now or anywhere else to enqueue."
|
||||
msgstr ""
|
||||
msgstr "انداختن روی نوار عنوان برای پخش اکنون یا هر جای دیگری برای صف کردن."
|
||||
|
||||
|
469
src/bin/clapper-app/po/hi.po
Normal file
469
src/bin/clapper-app/po/hi.po
Normal file
@@ -0,0 +1,469 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-04-21 20:22+0200\n"
|
||||
"PO-Revision-Date: 2024-07-09 18:54\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Hindi\n"
|
||||
"Language: hi_IN\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: hi\n"
|
||||
"X-Crowdin-File: /master/src/bin/clapper-app/po/clapper-app.pot\n"
|
||||
"X-Crowdin-File-ID: 48\n"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:14
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:14
|
||||
msgid "Codec"
|
||||
msgstr "कोडेक"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:24
|
||||
msgid "Channels"
|
||||
msgstr "चैनल"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:36
|
||||
msgid "Sample Format"
|
||||
msgstr "सैंपल प्रारूप"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:46
|
||||
msgid "Sample Rate"
|
||||
msgstr "सैंपल दर"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:58
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:51
|
||||
msgid "Bitrate"
|
||||
msgstr "बिटरेट"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:70
|
||||
#: src/bin/clapper-app/ui/clapper-app-subtitle-stream-list-item.ui:24
|
||||
msgid "Language"
|
||||
msgstr "भाषा"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-headerbar.ui:183
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:80
|
||||
msgid "Preferences"
|
||||
msgstr "प्राथमिकताएं"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-headerbar.ui:187
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:84
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr "कीबोर्ड शॉर्टकट"
|
||||
|
||||
#. TRANSLATORS: Please do not translate application name
|
||||
#: src/bin/clapper-app/ui/clapper-app-headerbar.ui:194
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:91
|
||||
msgid "About Clapper"
|
||||
msgstr "क्लैपर के बारे में"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:10
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:11
|
||||
msgid "General"
|
||||
msgstr "सामान्य"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:13
|
||||
msgid "Show shortcuts"
|
||||
msgstr "शॉर्टकट दिखाएं"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:19
|
||||
msgid "Open preferences"
|
||||
msgstr "प्राथमिकताएं खोलें"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:25
|
||||
msgid "Toggle fullscreen"
|
||||
msgstr "पूर्णस्क्रीन टॉगल करें"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:26
|
||||
msgid "Double tap | Double click"
|
||||
msgstr "डबल टैप | डबल क्लिक"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:32
|
||||
msgid "Quit"
|
||||
msgstr "बंद करें"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:40
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:32
|
||||
msgid "Media"
|
||||
msgstr "मीडिया"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:43
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:55
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:178
|
||||
msgid "Add Files…"
|
||||
msgstr "फाइलें जोड़ें…"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:49
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:65
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:182
|
||||
msgid "Add URI…"
|
||||
msgstr "यूआरआई जोड़ें…"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:57
|
||||
msgid "Queue"
|
||||
msgstr "कतार"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:61
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:68
|
||||
msgid "Next item"
|
||||
msgstr "अगला मद"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:75
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:82
|
||||
msgid "Previous item"
|
||||
msgstr "पिछला मद"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:88
|
||||
msgid "Change progression mode"
|
||||
msgstr "प्रगति मोड बदलें"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:96
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:76
|
||||
msgid "Playback"
|
||||
msgstr "प्लेबैक"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:99
|
||||
msgid "Toggle play"
|
||||
msgstr "चजाना टॉगल करें"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:100
|
||||
msgid "Tap | Left click"
|
||||
msgstr "टैप | बायां क्लिक"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:107
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:115
|
||||
msgid "Seek forward"
|
||||
msgstr "आगे तलाशें"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:108
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:132
|
||||
msgid "Double tap (right side) | Scroll right"
|
||||
msgstr "डबल टैप (दायीं ओर) | दाएं स्क्रॉल करें"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:116
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:124
|
||||
msgid "Double tap (left side) | Scroll left"
|
||||
msgstr "डबल टैप (बायीं ओर) | बाएं स्क्रॉल करें"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:123
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:131
|
||||
msgid "Seek backward"
|
||||
msgstr "पीछे तलाशें"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:138
|
||||
msgid "Volume up"
|
||||
msgstr "आवाज बढ़ाएं"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:139
|
||||
msgid "Scroll up"
|
||||
msgstr "ऊपर स्क्रॉल"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:145
|
||||
msgid "Volume down"
|
||||
msgstr "आवाज घटाएं"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:146
|
||||
msgid "Scroll down"
|
||||
msgstr "नीचे स्क्रॉल"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:152
|
||||
msgid "Toggle mute"
|
||||
msgstr "मूक टॉगल करें"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:158
|
||||
msgid "Speed up"
|
||||
msgstr "गति बढ़ाएं"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:164
|
||||
msgid "Speed down"
|
||||
msgstr "गति घटाएं"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:171
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:178
|
||||
msgid "Next chapter"
|
||||
msgstr "अगला अध्याय"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:185
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:192
|
||||
msgid "Previous chapter"
|
||||
msgstr "पिछला अध्याय"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:13
|
||||
msgid "Info"
|
||||
msgstr "जानकारी"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:35
|
||||
#: src/bin/clapper-app/ui/clapper-app-subtitle-stream-list-item.ui:14
|
||||
msgid "Title"
|
||||
msgstr "शीर्षक"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:49
|
||||
msgid "Container Format"
|
||||
msgstr "कंटेनर प्रारूप"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:63
|
||||
msgid "Duration"
|
||||
msgstr "अवधि"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:81
|
||||
msgid "Streams"
|
||||
msgstr "स्ट्रीम"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:84
|
||||
#: src/bin/clapper-app/clapper-app-list-item-utils.c:36
|
||||
msgid "Video"
|
||||
msgstr "वीडियो"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:107
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:80
|
||||
#: src/bin/clapper-app/clapper-app-list-item-utils.c:39
|
||||
msgid "Audio"
|
||||
msgstr "ऑडियो"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:130
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:100
|
||||
#: src/bin/clapper-app/clapper-app-list-item-utils.c:42
|
||||
msgid "Subtitles"
|
||||
msgstr "उपशीर्षक"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:155
|
||||
msgid "Video Playback"
|
||||
msgstr "वीडियो प्लेबैक"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:158
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:199
|
||||
msgid "Decoder"
|
||||
msgstr "डिकोडर"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:170
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:211
|
||||
msgid "Filter"
|
||||
msgstr "फिल्टर"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:182
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:223
|
||||
msgid "Sink"
|
||||
msgstr "सिंक"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:196
|
||||
msgid "Audio Playback"
|
||||
msgstr "ऑडियो प्लेबैक"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:247
|
||||
msgid "Video Streams"
|
||||
msgstr "वीडियो स्ट्रीम"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:290
|
||||
msgid "Audio Streams"
|
||||
msgstr "ऑडियो स्ट्रीम"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:333
|
||||
msgid "Subtitle Streams"
|
||||
msgstr "उपशीर्षक स्ट्रीम"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:46
|
||||
msgid "Start by adding media to playback queue"
|
||||
msgstr "प्लेबैक कतार में मीडिया जोड़कर प्रारंभ करें"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:15
|
||||
msgid "Seeking"
|
||||
msgstr "तलाश"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:18
|
||||
msgid "Method"
|
||||
msgstr "विधि"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:19
|
||||
msgid "A preferred method used for seeking"
|
||||
msgstr "तलाशने की वरीय विधि"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:32
|
||||
msgid "Value"
|
||||
msgstr "मान"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:33
|
||||
msgid "Value used for seeking forward/backward"
|
||||
msgstr "आगे/पीछे तलाशने हेतु मान"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:46
|
||||
msgid "Unit"
|
||||
msgstr "इकाई"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:47
|
||||
msgid "An unit of a seek forward/backward value"
|
||||
msgstr "आगे/पीछे तलाशने हेतु मान की इकाई"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:51
|
||||
msgid "Second"
|
||||
msgstr "सेकंड"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:52
|
||||
msgid "Minute"
|
||||
msgstr "मिनट"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:53
|
||||
msgid "Percentage"
|
||||
msgstr "प्रतिशत"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:63
|
||||
msgid "Features"
|
||||
msgstr "विशेषताएं"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:66
|
||||
msgid "Server"
|
||||
msgstr "सर्वर"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:67
|
||||
msgid "Control player remotely"
|
||||
msgstr "प्लेयर को रिमोट से नियंत्रित करें"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:83
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:103
|
||||
msgid "Offset"
|
||||
msgstr "ऑफसेट"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:84
|
||||
msgid "Synchronisation offset in seconds between the audio and video streams"
|
||||
msgstr "ऑडियो और वीडियो स्ट्रीम के बीच सेकंड में समन्वयन ऑफसेट"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:104
|
||||
msgid "Synchronisation offset in seconds between the subtitle and video streams"
|
||||
msgstr "उपशीर्षक और वीडियो स्ट्रीम के बीच सेकंड में समन्वयन ऑफसेट"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:118
|
||||
msgid "Default font"
|
||||
msgstr "तयशुदा फॉन्ट"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:119
|
||||
msgid "Text font used for subtitles when media does not explicitly specify one"
|
||||
msgstr "उपशीर्षकों हेतु प्रयुक्त टेक्स्ट फॉन्ट जब मीडिया स्पष्ट रूप से निर्दिष्ट नहीं करता है"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:137
|
||||
msgid "Tweaks"
|
||||
msgstr "ट्विक्स"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:144
|
||||
msgid "Plugin ranking"
|
||||
msgstr "प्लगइन रैंकिंग"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:145
|
||||
msgid "Alter default ranks of GStreamer plugins"
|
||||
msgstr "GStreamer प्लगइन्स की तयशुदा रैंक बदलें"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:164
|
||||
msgid "Plugin Ranking"
|
||||
msgstr "प्लगइन रैंकिंग"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:182
|
||||
msgid "Available plugins"
|
||||
msgstr "उपलब्ध प्लगइन"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:183
|
||||
msgid "Select a plugin and its feature to override rank for. When multiple elements have similiar capabilities, the one with highest value is preferred."
|
||||
msgstr "रैंक को ओवरराइड करने के लिए प्लगइन और उसकी खासियत चुनें। जब कई तत्वों में समान क्षमताएं होती हैं, तो सबसे अधिक मान वाले को प्राथमिकता दी जाती है।"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:186
|
||||
msgid "Plugin"
|
||||
msgstr "प्लगइन"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:195
|
||||
msgid "Plugin feature"
|
||||
msgstr "प्लगइन सुविधा"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:213
|
||||
msgid "Add override"
|
||||
msgstr "ओवरराइड जोड़ें"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:229
|
||||
msgid "Rank overrides"
|
||||
msgstr "रैंक ओवरराइड"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:60
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:23
|
||||
msgid "Add"
|
||||
msgstr "जोड़ें"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:87
|
||||
msgid "Queue progression"
|
||||
msgstr "कतार प्रगति"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:6
|
||||
msgid "Add URI"
|
||||
msgstr "यूआरआई जोड़ें"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:7
|
||||
msgid "Insert an URI to be added to playback queue"
|
||||
msgstr "प्लेबैक कतार में जोड़ने के लिए यूआरआई डालें"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:18
|
||||
msgid "Enter or drop URI here"
|
||||
msgstr "यहां यूआरआई दर्ज करें या छोड़ें"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:22
|
||||
msgid "Cancel"
|
||||
msgstr "रद्द करें"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:24
|
||||
msgid "Resolution"
|
||||
msgstr "रिजोल्यूशन"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:39
|
||||
msgid "Framerate"
|
||||
msgstr "फ्रेमरेट"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:63
|
||||
msgid "Pixel Format"
|
||||
msgstr "पिक्सल प्रारूप"
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/bin/clapper-app/clapper-app-about-window.c:43
|
||||
msgid "translator-credits"
|
||||
msgstr "Scrambled777 <weblate.scrambled777@simplelogin.com>"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-info-window.c:86
|
||||
msgid "Hardware"
|
||||
msgstr "हार्डवेयर"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-info-window.c:86
|
||||
msgid "Software"
|
||||
msgstr "सॉफ्टवेयर"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-preferences-window.c:441
|
||||
msgid "Accurate"
|
||||
msgstr "सटीक"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-preferences-window.c:443
|
||||
msgid "Normal"
|
||||
msgstr "साधारण"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-preferences-window.c:445
|
||||
msgid "Fast"
|
||||
msgstr "तेज"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:66
|
||||
msgid "No progression"
|
||||
msgstr "प्रगति नहीं"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:67
|
||||
msgid "Consecutive"
|
||||
msgstr "लगातार"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:68
|
||||
msgid "Repeat item"
|
||||
msgstr "मद दोहराएं"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:69
|
||||
msgid "Carousel"
|
||||
msgstr "कैरोसेल"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:70
|
||||
msgid "Shuffle"
|
||||
msgstr "शफल"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-window.c:828
|
||||
msgid "Drop on title bar to play now or anywhere else to enqueue."
|
||||
msgstr "अभी चलाने के लिए शीर्षक पट्टी पर छोड़ें या कतार में लगाने के लिए कहीं और छोड़ें।"
|
||||
|
@@ -3,7 +3,7 @@ msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-04-21 20:22+0200\n"
|
||||
"PO-Revision-Date: 2024-04-21 20:51\n"
|
||||
"PO-Revision-Date: 2024-10-05 12:47\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Norwegian\n"
|
||||
"Language: no_NO\n"
|
||||
@@ -20,450 +20,450 @@ msgstr ""
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:14
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:14
|
||||
msgid "Codec"
|
||||
msgstr ""
|
||||
msgstr "Codec"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:24
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
msgstr "Kanaler"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:36
|
||||
msgid "Sample Format"
|
||||
msgstr ""
|
||||
msgstr "Samplingsformat"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:46
|
||||
msgid "Sample Rate"
|
||||
msgstr ""
|
||||
msgstr "Samplingsfrekvens"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:58
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:51
|
||||
msgid "Bitrate"
|
||||
msgstr ""
|
||||
msgstr "Bitrate"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:70
|
||||
#: src/bin/clapper-app/ui/clapper-app-subtitle-stream-list-item.ui:24
|
||||
msgid "Language"
|
||||
msgstr ""
|
||||
msgstr "Språk"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-headerbar.ui:183
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:80
|
||||
msgid "Preferences"
|
||||
msgstr ""
|
||||
msgstr "Brukervalg"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-headerbar.ui:187
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:84
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Tastatursnarveier"
|
||||
|
||||
#. TRANSLATORS: Please do not translate application name
|
||||
#: src/bin/clapper-app/ui/clapper-app-headerbar.ui:194
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:91
|
||||
msgid "About Clapper"
|
||||
msgstr ""
|
||||
msgstr "Om Clapper"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:10
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:11
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
msgstr "Generelt"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:13
|
||||
msgid "Show shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Vis tastatursnarveier"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:19
|
||||
msgid "Open preferences"
|
||||
msgstr ""
|
||||
msgstr "Åpne brukervalg"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:25
|
||||
msgid "Toggle fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Slå på/av fullskjermsmodus"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:26
|
||||
msgid "Double tap | Double click"
|
||||
msgstr ""
|
||||
msgstr "Dobbelttrykk | Dobbeltklikk"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:32
|
||||
msgid "Quit"
|
||||
msgstr ""
|
||||
msgstr "Avslutt"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:40
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:32
|
||||
msgid "Media"
|
||||
msgstr ""
|
||||
msgstr "Medium"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:43
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:55
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:178
|
||||
msgid "Add Files…"
|
||||
msgstr ""
|
||||
msgstr "Legg til filer…"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:49
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:65
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:182
|
||||
msgid "Add URI…"
|
||||
msgstr ""
|
||||
msgstr "Legg til URI…"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:57
|
||||
msgid "Queue"
|
||||
msgstr ""
|
||||
msgstr "Kø"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:61
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:68
|
||||
msgid "Next item"
|
||||
msgstr ""
|
||||
msgstr "Neste element"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:75
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:82
|
||||
msgid "Previous item"
|
||||
msgstr ""
|
||||
msgstr "Forrige element"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:88
|
||||
msgid "Change progression mode"
|
||||
msgstr ""
|
||||
msgstr "Endre progresjonsmodus"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:96
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:76
|
||||
msgid "Playback"
|
||||
msgstr ""
|
||||
msgstr "Avspilling"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:99
|
||||
msgid "Toggle play"
|
||||
msgstr ""
|
||||
msgstr "Spill av eller pause"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:100
|
||||
msgid "Tap | Left click"
|
||||
msgstr ""
|
||||
msgstr "Trykk | Venstreklikk"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:107
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:115
|
||||
msgid "Seek forward"
|
||||
msgstr ""
|
||||
msgstr "Søk fremover"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:108
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:132
|
||||
msgid "Double tap (right side) | Scroll right"
|
||||
msgstr ""
|
||||
msgstr "Dobbelttrykk (på høyre side) | Rull til høyre"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:116
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:124
|
||||
msgid "Double tap (left side) | Scroll left"
|
||||
msgstr ""
|
||||
msgstr "Dobbelttrykk (på venstre side) | Rull til venstre"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:123
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:131
|
||||
msgid "Seek backward"
|
||||
msgstr ""
|
||||
msgstr "Søk bakover"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:138
|
||||
msgid "Volume up"
|
||||
msgstr ""
|
||||
msgstr "Øk volym"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:139
|
||||
msgid "Scroll up"
|
||||
msgstr ""
|
||||
msgstr "Rull opp"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:145
|
||||
msgid "Volume down"
|
||||
msgstr ""
|
||||
msgstr "Senk volym"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:146
|
||||
msgid "Scroll down"
|
||||
msgstr ""
|
||||
msgstr "Rull ned"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:152
|
||||
msgid "Toggle mute"
|
||||
msgstr ""
|
||||
msgstr "Demp/avdemp"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:158
|
||||
msgid "Speed up"
|
||||
msgstr ""
|
||||
msgstr "Øk farten"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:164
|
||||
msgid "Speed down"
|
||||
msgstr ""
|
||||
msgstr "Senk farten"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:171
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:178
|
||||
msgid "Next chapter"
|
||||
msgstr ""
|
||||
msgstr "Neste kapittel"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:185
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:192
|
||||
msgid "Previous chapter"
|
||||
msgstr ""
|
||||
msgstr "Forrige kapittel"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:13
|
||||
msgid "Info"
|
||||
msgstr ""
|
||||
msgstr "Informasjon"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:35
|
||||
#: src/bin/clapper-app/ui/clapper-app-subtitle-stream-list-item.ui:14
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
msgstr "Tittel"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:49
|
||||
msgid "Container Format"
|
||||
msgstr ""
|
||||
msgstr "Konteinerformat"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:63
|
||||
msgid "Duration"
|
||||
msgstr ""
|
||||
msgstr "Lengde"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:81
|
||||
msgid "Streams"
|
||||
msgstr ""
|
||||
msgstr "Strømmer"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:84
|
||||
#: src/bin/clapper-app/clapper-app-list-item-utils.c:36
|
||||
msgid "Video"
|
||||
msgstr ""
|
||||
msgstr "Video"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:107
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:80
|
||||
#: src/bin/clapper-app/clapper-app-list-item-utils.c:39
|
||||
msgid "Audio"
|
||||
msgstr ""
|
||||
msgstr "Lyd"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:130
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:100
|
||||
#: src/bin/clapper-app/clapper-app-list-item-utils.c:42
|
||||
msgid "Subtitles"
|
||||
msgstr ""
|
||||
msgstr "Undertekstning"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:155
|
||||
msgid "Video Playback"
|
||||
msgstr ""
|
||||
msgstr "Videoavspilling"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:158
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:199
|
||||
msgid "Decoder"
|
||||
msgstr ""
|
||||
msgstr "Dekoder"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:170
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:211
|
||||
msgid "Filter"
|
||||
msgstr ""
|
||||
msgstr "Filter"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:182
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:223
|
||||
msgid "Sink"
|
||||
msgstr ""
|
||||
msgstr "Vask"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:196
|
||||
msgid "Audio Playback"
|
||||
msgstr ""
|
||||
msgstr "Lydavspilling"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:247
|
||||
msgid "Video Streams"
|
||||
msgstr ""
|
||||
msgstr "Videostrømmer"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:290
|
||||
msgid "Audio Streams"
|
||||
msgstr ""
|
||||
msgstr "Lydstrømmer"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:333
|
||||
msgid "Subtitle Streams"
|
||||
msgstr ""
|
||||
msgstr "Undertekstingsstrømmer"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:46
|
||||
msgid "Start by adding media to playback queue"
|
||||
msgstr ""
|
||||
msgstr "Start ved å legge til medier i avspillingskøen"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:15
|
||||
msgid "Seeking"
|
||||
msgstr ""
|
||||
msgstr "Søkning"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:18
|
||||
msgid "Method"
|
||||
msgstr ""
|
||||
msgstr "Metode"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:19
|
||||
msgid "A preferred method used for seeking"
|
||||
msgstr ""
|
||||
msgstr "En foretrukket metode brukt for å søke"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:32
|
||||
msgid "Value"
|
||||
msgstr ""
|
||||
msgstr "Verdi"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:33
|
||||
msgid "Value used for seeking forward/backward"
|
||||
msgstr ""
|
||||
msgstr "Verdi brukt for å søke fremover/bakover"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:46
|
||||
msgid "Unit"
|
||||
msgstr ""
|
||||
msgstr "Enhet"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:47
|
||||
msgid "An unit of a seek forward/backward value"
|
||||
msgstr ""
|
||||
msgstr "En enhet av en søkningsverdi"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:51
|
||||
msgid "Second"
|
||||
msgstr ""
|
||||
msgstr "Sekund"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:52
|
||||
msgid "Minute"
|
||||
msgstr ""
|
||||
msgstr "Minutt"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:53
|
||||
msgid "Percentage"
|
||||
msgstr ""
|
||||
msgstr "Prosentdel"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:63
|
||||
msgid "Features"
|
||||
msgstr ""
|
||||
msgstr "Funksjoner"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:66
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
msgstr "Server"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:67
|
||||
msgid "Control player remotely"
|
||||
msgstr ""
|
||||
msgstr "Fjernstyring av spilleren"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:83
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:103
|
||||
msgid "Offset"
|
||||
msgstr ""
|
||||
msgstr "Forskyvning"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:84
|
||||
msgid "Synchronisation offset in seconds between the audio and video streams"
|
||||
msgstr ""
|
||||
msgstr "Synkroniseringsforskyvning i sekunder mellom lyd- og videostrømmene"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:104
|
||||
msgid "Synchronisation offset in seconds between the subtitle and video streams"
|
||||
msgstr ""
|
||||
msgstr "Synkroniseringsforskyvning i sekunder mellom untertekst- og videostrømmene"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:118
|
||||
msgid "Default font"
|
||||
msgstr ""
|
||||
msgstr "Standard skrifttype"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:119
|
||||
msgid "Text font used for subtitles when media does not explicitly specify one"
|
||||
msgstr ""
|
||||
msgstr "Skrifttype som brukes for undertekster når mediet ikke angir en skrifttype"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:137
|
||||
msgid "Tweaks"
|
||||
msgstr ""
|
||||
msgstr "Justeringer"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:144
|
||||
msgid "Plugin ranking"
|
||||
msgstr ""
|
||||
msgstr "Tilleggsrangering"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:145
|
||||
msgid "Alter default ranks of GStreamer plugins"
|
||||
msgstr ""
|
||||
msgstr "Endre den standarde rangeringen av GStreamer-tillegg"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:164
|
||||
msgid "Plugin Ranking"
|
||||
msgstr ""
|
||||
msgstr "Tilleggsrangering"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:182
|
||||
msgid "Available plugins"
|
||||
msgstr ""
|
||||
msgstr "Tilgjengelige tillegg"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:183
|
||||
msgid "Select a plugin and its feature to override rank for. When multiple elements have similiar capabilities, the one with highest value is preferred."
|
||||
msgstr ""
|
||||
msgstr "Velg et tillegg og funskjonen dets for å overstyre rangen. Når flere elementer har lignende egenskaper, skal det med den høyeste verdien brukes."
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:186
|
||||
msgid "Plugin"
|
||||
msgstr ""
|
||||
msgstr "Tillegg"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:195
|
||||
msgid "Plugin feature"
|
||||
msgstr ""
|
||||
msgstr "Tilleggsfunksjon"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:213
|
||||
msgid "Add override"
|
||||
msgstr ""
|
||||
msgstr "Legg till overstyring"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:229
|
||||
msgid "Rank overrides"
|
||||
msgstr ""
|
||||
msgstr "Rangoverstyringer"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:60
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:23
|
||||
msgid "Add"
|
||||
msgstr ""
|
||||
msgstr "Legg til"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:87
|
||||
msgid "Queue progression"
|
||||
msgstr ""
|
||||
msgstr "Køprogresjon"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:6
|
||||
msgid "Add URI"
|
||||
msgstr ""
|
||||
msgstr "Legg til URI"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:7
|
||||
msgid "Insert an URI to be added to playback queue"
|
||||
msgstr ""
|
||||
msgstr "Tast inn en URI for å legge den til i avspillingskøen"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:18
|
||||
msgid "Enter or drop URI here"
|
||||
msgstr ""
|
||||
msgstr "Tast inn eller slipp URI her"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:22
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "Avbryt"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:24
|
||||
msgid "Resolution"
|
||||
msgstr ""
|
||||
msgstr "Oppløsning"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:39
|
||||
msgid "Framerate"
|
||||
msgstr ""
|
||||
msgstr "Bildefrekvens"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:63
|
||||
msgid "Pixel Format"
|
||||
msgstr ""
|
||||
msgstr "Pikselformat"
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/bin/clapper-app/clapper-app-about-window.c:43
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
msgstr "Sunniva Løvstad <clapper@turtle.garden>"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-info-window.c:86
|
||||
msgid "Hardware"
|
||||
msgstr ""
|
||||
msgstr "Maskinvare"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-info-window.c:86
|
||||
msgid "Software"
|
||||
msgstr ""
|
||||
msgstr "Programvare"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-preferences-window.c:441
|
||||
msgid "Accurate"
|
||||
msgstr ""
|
||||
msgstr "Nøyaktig"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-preferences-window.c:443
|
||||
msgid "Normal"
|
||||
msgstr ""
|
||||
msgstr "Normal"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-preferences-window.c:445
|
||||
msgid "Fast"
|
||||
msgstr ""
|
||||
msgstr "Rask"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:66
|
||||
msgid "No progression"
|
||||
msgstr ""
|
||||
msgstr "Ingen progresjon"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:67
|
||||
msgid "Consecutive"
|
||||
msgstr ""
|
||||
msgstr "Konsekutiv"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:68
|
||||
msgid "Repeat item"
|
||||
msgstr ""
|
||||
msgstr "Gjenta element"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:69
|
||||
msgid "Carousel"
|
||||
msgstr ""
|
||||
msgstr "Gjenta kø"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:70
|
||||
msgid "Shuffle"
|
||||
msgstr ""
|
||||
msgstr "Omstokking"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-window.c:828
|
||||
msgid "Drop on title bar to play now or anywhere else to enqueue."
|
||||
msgstr ""
|
||||
msgstr "Slipp på tittellinjen for å spille av nå, eller hvor som helst annet for å legg til i køen."
|
||||
|
||||
|
@@ -3,7 +3,7 @@ msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-04-21 20:22+0200\n"
|
||||
"PO-Revision-Date: 2024-04-21 20:51\n"
|
||||
"PO-Revision-Date: 2024-08-11 15:57\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Russian\n"
|
||||
"Language: ru_RU\n"
|
||||
@@ -20,7 +20,7 @@ msgstr ""
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:14
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:14
|
||||
msgid "Codec"
|
||||
msgstr ""
|
||||
msgstr "Кодек"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:24
|
||||
msgid "Channels"
|
||||
@@ -28,21 +28,21 @@ msgstr "Каналы"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:36
|
||||
msgid "Sample Format"
|
||||
msgstr ""
|
||||
msgstr "Формат семпла"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:46
|
||||
msgid "Sample Rate"
|
||||
msgstr ""
|
||||
msgstr "Частота дискретизации"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:58
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:51
|
||||
msgid "Bitrate"
|
||||
msgstr ""
|
||||
msgstr "Битрейт"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:70
|
||||
#: src/bin/clapper-app/ui/clapper-app-subtitle-stream-list-item.ui:24
|
||||
msgid "Language"
|
||||
msgstr ""
|
||||
msgstr "Язык"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-headerbar.ui:183
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:80
|
||||
@@ -52,7 +52,7 @@ msgstr "Параметры"
|
||||
#: src/bin/clapper-app/ui/clapper-app-headerbar.ui:187
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:84
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr ""
|
||||
msgstr "Сочетания клавиш"
|
||||
|
||||
#. TRANSLATORS: Please do not translate application name
|
||||
#: src/bin/clapper-app/ui/clapper-app-headerbar.ui:194
|
||||
@@ -71,7 +71,7 @@ msgstr "Комбинации клавиш"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:19
|
||||
msgid "Open preferences"
|
||||
msgstr ""
|
||||
msgstr "Открыть настройки"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:25
|
||||
msgid "Toggle fullscreen"
|
||||
@@ -94,17 +94,17 @@ msgstr "Медиа"
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:55
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:178
|
||||
msgid "Add Files…"
|
||||
msgstr ""
|
||||
msgstr "Добавить файлы…"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:49
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:65
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:182
|
||||
msgid "Add URI…"
|
||||
msgstr ""
|
||||
msgstr "Открыть по ссылке…"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:57
|
||||
msgid "Queue"
|
||||
msgstr ""
|
||||
msgstr "Дорожка"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:61
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:68
|
||||
@@ -118,7 +118,7 @@ msgstr "Предыдущий элемент"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:88
|
||||
msgid "Change progression mode"
|
||||
msgstr ""
|
||||
msgstr "Изменить режим повтора"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:96
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:76
|
||||
@@ -131,7 +131,7 @@ msgstr "Управление воспроизведением"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:100
|
||||
msgid "Tap | Left click"
|
||||
msgstr ""
|
||||
msgstr "Тап | Левая кнопка мыши"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:107
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:115
|
||||
@@ -141,12 +141,12 @@ msgstr "Перемотка вперед"
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:108
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:132
|
||||
msgid "Double tap (right side) | Scroll right"
|
||||
msgstr ""
|
||||
msgstr "Двойной тап (правая сторона) | Скролл вправо"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:116
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:124
|
||||
msgid "Double tap (left side) | Scroll left"
|
||||
msgstr ""
|
||||
msgstr "Двойной тап (левая сторона) | Скролл влево"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:123
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:131
|
||||
@@ -159,7 +159,7 @@ msgstr "Увеличить громкость"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:139
|
||||
msgid "Scroll up"
|
||||
msgstr ""
|
||||
msgstr "Скролл вверх"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:145
|
||||
msgid "Volume down"
|
||||
@@ -167,7 +167,7 @@ msgstr "Уменьшить громкость"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:146
|
||||
msgid "Scroll down"
|
||||
msgstr ""
|
||||
msgstr "Скролл вниз"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:152
|
||||
msgid "Toggle mute"
|
||||
@@ -175,11 +175,11 @@ msgstr "Отключить звук"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:158
|
||||
msgid "Speed up"
|
||||
msgstr ""
|
||||
msgstr "Ускорить"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:164
|
||||
msgid "Speed down"
|
||||
msgstr ""
|
||||
msgstr "Замедлить"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:171
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:178
|
||||
@@ -193,7 +193,7 @@ msgstr "Предыдущая глава"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:13
|
||||
msgid "Info"
|
||||
msgstr ""
|
||||
msgstr "Информация"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:35
|
||||
#: src/bin/clapper-app/ui/clapper-app-subtitle-stream-list-item.ui:14
|
||||
@@ -202,20 +202,20 @@ msgstr "Заголовок"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:49
|
||||
msgid "Container Format"
|
||||
msgstr ""
|
||||
msgstr "Формат контейнера"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:63
|
||||
msgid "Duration"
|
||||
msgstr ""
|
||||
msgstr "Длительность"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:81
|
||||
msgid "Streams"
|
||||
msgstr ""
|
||||
msgstr "Потоки"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:84
|
||||
#: src/bin/clapper-app/clapper-app-list-item-utils.c:36
|
||||
msgid "Video"
|
||||
msgstr ""
|
||||
msgstr "Видео"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:107
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:80
|
||||
@@ -231,42 +231,42 @@ msgstr "Субтитры"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:155
|
||||
msgid "Video Playback"
|
||||
msgstr ""
|
||||
msgstr "Воспроизведение видео"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:158
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:199
|
||||
msgid "Decoder"
|
||||
msgstr ""
|
||||
msgstr "Декодер"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:170
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:211
|
||||
msgid "Filter"
|
||||
msgstr ""
|
||||
msgstr "Фильтр"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:182
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:223
|
||||
msgid "Sink"
|
||||
msgstr ""
|
||||
msgstr "Приемник"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:196
|
||||
msgid "Audio Playback"
|
||||
msgstr ""
|
||||
msgstr "Воспроизведение звука"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:247
|
||||
msgid "Video Streams"
|
||||
msgstr ""
|
||||
msgstr "Видеопотоки"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:290
|
||||
msgid "Audio Streams"
|
||||
msgstr ""
|
||||
msgstr "Аудиопотоки"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:333
|
||||
msgid "Subtitle Streams"
|
||||
msgstr ""
|
||||
msgstr "Потоки субтитров"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:46
|
||||
msgid "Start by adding media to playback queue"
|
||||
msgstr ""
|
||||
msgstr "Начните с добавления медиа в очередь воспроизведения"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:15
|
||||
msgid "Seeking"
|
||||
@@ -274,11 +274,11 @@ msgstr "Перемотка"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:18
|
||||
msgid "Method"
|
||||
msgstr ""
|
||||
msgstr "Метод"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:19
|
||||
msgid "A preferred method used for seeking"
|
||||
msgstr ""
|
||||
msgstr "Предпочтительный метод, используемый для поиска"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:32
|
||||
msgid "Value"
|
||||
@@ -286,7 +286,7 @@ msgstr "Значение"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:33
|
||||
msgid "Value used for seeking forward/backward"
|
||||
msgstr ""
|
||||
msgstr "Значение, используемое для поиска вперед/назад"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:46
|
||||
msgid "Unit"
|
||||
@@ -294,7 +294,7 @@ msgstr "Ед. изм"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:47
|
||||
msgid "An unit of a seek forward/backward value"
|
||||
msgstr ""
|
||||
msgstr "Единица поиска вперёд/назад"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:51
|
||||
msgid "Second"
|
||||
@@ -310,7 +310,7 @@ msgstr "Проценты"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:63
|
||||
msgid "Features"
|
||||
msgstr ""
|
||||
msgstr "Дополнительные настройки"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:66
|
||||
msgid "Server"
|
||||
@@ -323,15 +323,15 @@ msgstr "Удаленное управление плеером"
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:83
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:103
|
||||
msgid "Offset"
|
||||
msgstr ""
|
||||
msgstr "Задержка"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:84
|
||||
msgid "Synchronisation offset in seconds between the audio and video streams"
|
||||
msgstr ""
|
||||
msgstr "Задержка синхронизации в секундах между аудио- и видеопотоками"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:104
|
||||
msgid "Synchronisation offset in seconds between the subtitle and video streams"
|
||||
msgstr ""
|
||||
msgstr "Задержка синхронизации в секундах между потоком субтитров и видеопотоком"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:118
|
||||
msgid "Default font"
|
||||
@@ -339,7 +339,7 @@ msgstr "Шрифт по умолчанию"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:119
|
||||
msgid "Text font used for subtitles when media does not explicitly specify one"
|
||||
msgstr ""
|
||||
msgstr "Шрифт, используемый для субтитров, если не указан какой именно"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:137
|
||||
msgid "Tweaks"
|
||||
@@ -355,48 +355,48 @@ msgstr "Изменить ранги плагинов GStreamer по умолча
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:164
|
||||
msgid "Plugin Ranking"
|
||||
msgstr ""
|
||||
msgstr "Ранжирование плагинов"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:182
|
||||
msgid "Available plugins"
|
||||
msgstr ""
|
||||
msgstr "Доступные плагины"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:183
|
||||
msgid "Select a plugin and its feature to override rank for. When multiple elements have similiar capabilities, the one with highest value is preferred."
|
||||
msgstr ""
|
||||
msgstr "Выберите плагин и его функцию, чтобы переопределить ранжирование. Когда несколько элементов имеют схожие возможности, предпочтение имеет один с наибольшим значением."
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:186
|
||||
msgid "Plugin"
|
||||
msgstr ""
|
||||
msgstr "Плагин"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:195
|
||||
msgid "Plugin feature"
|
||||
msgstr ""
|
||||
msgstr "Настройка плагина"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:213
|
||||
msgid "Add override"
|
||||
msgstr ""
|
||||
msgstr "Добавить переопределение"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:229
|
||||
msgid "Rank overrides"
|
||||
msgstr ""
|
||||
msgstr "Переопределение ранжирования"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:60
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:23
|
||||
msgid "Add"
|
||||
msgstr ""
|
||||
msgstr "Добавить"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:87
|
||||
msgid "Queue progression"
|
||||
msgstr ""
|
||||
msgstr "Прогресс очереди"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:6
|
||||
msgid "Add URI"
|
||||
msgstr ""
|
||||
msgstr "Открыть по ссылке"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:7
|
||||
msgid "Insert an URI to be added to playback queue"
|
||||
msgstr ""
|
||||
msgstr "Вставьте URI, который будет добавлен в очередь воспроизведения"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:18
|
||||
msgid "Enter or drop URI here"
|
||||
@@ -408,15 +408,15 @@ msgstr "Отмена"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:24
|
||||
msgid "Resolution"
|
||||
msgstr ""
|
||||
msgstr "Разрешение"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:39
|
||||
msgid "Framerate"
|
||||
msgstr ""
|
||||
msgstr "Частота кадров"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:63
|
||||
msgid "Pixel Format"
|
||||
msgstr ""
|
||||
msgstr "Формат пикселей"
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/bin/clapper-app/clapper-app-about-window.c:43
|
||||
@@ -425,11 +425,11 @@ msgstr "Игорь Дятлов"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-info-window.c:86
|
||||
msgid "Hardware"
|
||||
msgstr ""
|
||||
msgstr "Аппаратное"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-info-window.c:86
|
||||
msgid "Software"
|
||||
msgstr ""
|
||||
msgstr "Программное"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-preferences-window.c:441
|
||||
msgid "Accurate"
|
||||
@@ -445,25 +445,25 @@ msgstr "Быстрый"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:66
|
||||
msgid "No progression"
|
||||
msgstr ""
|
||||
msgstr "Нет прогрессии"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:67
|
||||
msgid "Consecutive"
|
||||
msgstr ""
|
||||
msgstr "Последовательно"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:68
|
||||
msgid "Repeat item"
|
||||
msgstr ""
|
||||
msgstr "Повторить элемент"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:69
|
||||
msgid "Carousel"
|
||||
msgstr ""
|
||||
msgstr "Повтор очереди"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-utils.c:70
|
||||
msgid "Shuffle"
|
||||
msgstr ""
|
||||
msgstr "Случайно"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-window.c:828
|
||||
msgid "Drop on title bar to play now or anywhere else to enqueue."
|
||||
msgstr ""
|
||||
msgstr "Перетащите на строку заголовка, чтобы воспроизвести сейчас или где-нибудь ещё, чтобы попасть в очередь."
|
||||
|
||||
|
@@ -178,6 +178,12 @@
|
||||
</child>
|
||||
</template>
|
||||
<menu id="app_menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">New Window</attribute>
|
||||
<attribute name="action">app.new-window</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Preferences</attribute>
|
||||
|
@@ -10,8 +10,8 @@
|
||||
<property name="title" translatable="yes">General</property>
|
||||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="title" translatable="yes">Show shortcuts</property>
|
||||
<property name="accelerator"><Ctrl>question</property>
|
||||
<property name="title" translatable="yes">New window</property>
|
||||
<property name="accelerator"><Ctrl>n</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -20,6 +20,12 @@
|
||||
<property name="accelerator"><Ctrl>comma</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="title" translatable="yes">Show shortcuts</property>
|
||||
<property name="accelerator"><Ctrl>question</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="title" translatable="yes">Toggle fullscreen</property>
|
||||
@@ -27,6 +33,19 @@
|
||||
<property name="accelerator">F11 f</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="title" translatable="yes">Unfullscreen</property>
|
||||
<property name="accelerator">Escape</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="title" translatable="yes">Auto window resize</property>
|
||||
<property name="subtitle" translatable="yes">Middle click</property>
|
||||
<property name="accelerator"><Super>r</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="title" translatable="yes">Quit</property>
|
||||
|
@@ -232,6 +232,16 @@
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="halign">center</property>
|
||||
<property name="label" translatable="yes">Show Pipeline</property>
|
||||
<property name="action-name">app.pipeline</property>
|
||||
<style>
|
||||
<class name="pill"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
28
src/bin/clapper-app/ui/clapper-app-pipeline-window.ui
Normal file
28
src/bin/clapper-app/ui/clapper-app-pipeline-window.ui
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface domain="clapper-app">
|
||||
<template class="ClapperAppPipelineWindow" parent="AdwWindow">
|
||||
<property name="title" translatable="yes">Pipeline</property>
|
||||
<property name="width-request">280</property>
|
||||
<property name="height-request">280</property>
|
||||
<property name="default-width">1400</property>
|
||||
<property name="default-height">720</property>
|
||||
<property name="modal">true</property>
|
||||
<property name="content">
|
||||
<object class="AdwToolbarView">
|
||||
<child type="top">
|
||||
<object class="AdwHeaderBar"/>
|
||||
</child>
|
||||
<property name="content">
|
||||
<object class="GtkScrolledWindow">
|
||||
<child>
|
||||
<object class="ClapperAppPipelineViewer" id="pipeline_viewer"/>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
<style>
|
||||
<class name="pipeline"/>
|
||||
</style>
|
||||
</template>
|
||||
</interface>
|
@@ -47,9 +47,9 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGestureClick">
|
||||
<property name="button">3</property>
|
||||
<signal name="pressed" handler="right_click_pressed_cb"/>
|
||||
<signal name="released" handler="right_click_released_cb"/>
|
||||
<property name="button">0</property>
|
||||
<signal name="pressed" handler="click_pressed_cb"/>
|
||||
<signal name="released" handler="click_released_cb"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -68,8 +68,5 @@
|
||||
<signal name="drop" handler="drop_cb"/>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="app"/>
|
||||
</style>
|
||||
</template>
|
||||
</interface>
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <clapper-gtk/clapper-gtk-visibility.h>
|
||||
#include <clapper-gtk/clapper-gtk-container.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -34,18 +35,25 @@ G_BEGIN_DECLS
|
||||
#define CLAPPER_GTK_TYPE_BILLBOARD (clapper_gtk_billboard_get_type())
|
||||
#define CLAPPER_GTK_BILLBOARD_CAST(obj) ((ClapperGtkBillboard *)(obj))
|
||||
|
||||
CLAPPER_GTK_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperGtkBillboard, clapper_gtk_billboard, CLAPPER_GTK, BILLBOARD, ClapperGtkContainer)
|
||||
|
||||
CLAPPER_GTK_API
|
||||
GtkWidget * clapper_gtk_billboard_new (void);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_billboard_post_message (ClapperGtkBillboard *billboard, const gchar *icon_name, const gchar *message);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_billboard_pin_message (ClapperGtkBillboard *billboard, const gchar *icon_name, const gchar *message);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_billboard_unpin_pinned_message (ClapperGtkBillboard *billboard);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_billboard_announce_volume (ClapperGtkBillboard *billboard);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_billboard_announce_speed (ClapperGtkBillboard *billboard);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -27,11 +27,14 @@
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <clapper-gtk/clapper-gtk-visibility.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLAPPER_GTK_TYPE_CONTAINER (clapper_gtk_container_get_type())
|
||||
#define CLAPPER_GTK_CONTAINER_CAST(obj) ((ClapperGtkContainer *)(obj))
|
||||
|
||||
CLAPPER_GTK_API
|
||||
G_DECLARE_DERIVABLE_TYPE (ClapperGtkContainer, clapper_gtk_container, CLAPPER_GTK, CONTAINER, GtkWidget)
|
||||
|
||||
struct _ClapperGtkContainerClass
|
||||
@@ -42,26 +45,37 @@ struct _ClapperGtkContainerClass
|
||||
gpointer padding[4];
|
||||
};
|
||||
|
||||
CLAPPER_GTK_API
|
||||
GtkWidget * clapper_gtk_container_new (void);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_container_set_child (ClapperGtkContainer *container, GtkWidget *child);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
GtkWidget * clapper_gtk_container_get_child (ClapperGtkContainer *container);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_container_set_width_target (ClapperGtkContainer *container, gint width);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
gint clapper_gtk_container_get_width_target (ClapperGtkContainer *container);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_container_set_height_target (ClapperGtkContainer *container, gint height);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
gint clapper_gtk_container_get_height_target (ClapperGtkContainer *container);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_container_set_adaptive_width (ClapperGtkContainer *container, gint width);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
gint clapper_gtk_container_get_adaptive_width (ClapperGtkContainer *container);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_container_set_adaptive_height (ClapperGtkContainer *container, gint height);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
gint clapper_gtk_container_get_adaptive_height (ClapperGtkContainer *container);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -27,25 +27,35 @@
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <clapper-gtk/clapper-gtk-visibility.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLAPPER_GTK_TYPE_EXTRA_MENU_BUTTON (clapper_gtk_extra_menu_button_get_type())
|
||||
#define CLAPPER_GTK_EXTRA_MENU_BUTTON_CAST(obj) ((ClapperGtkExtraMenuButton *)(obj))
|
||||
|
||||
CLAPPER_GTK_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperGtkExtraMenuButton, clapper_gtk_extra_menu_button, CLAPPER_GTK, EXTRA_MENU_BUTTON, GtkWidget)
|
||||
|
||||
CLAPPER_GTK_API
|
||||
GtkWidget * clapper_gtk_extra_menu_button_new (void);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_extra_menu_button_set_volume_visible (ClapperGtkExtraMenuButton *button, gboolean visible);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
gboolean clapper_gtk_extra_menu_button_get_volume_visible (ClapperGtkExtraMenuButton *button);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_extra_menu_button_set_speed_visible (ClapperGtkExtraMenuButton *button, gboolean visible);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
gboolean clapper_gtk_extra_menu_button_get_speed_visible (ClapperGtkExtraMenuButton *button);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_extra_menu_button_set_can_open_subtitles (ClapperGtkExtraMenuButton *button, gboolean allowed);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
gboolean clapper_gtk_extra_menu_button_get_can_open_subtitles (ClapperGtkExtraMenuButton *button);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <clapper-gtk/clapper-gtk-visibility.h>
|
||||
#include <clapper-gtk/clapper-gtk-enums.h>
|
||||
#include <clapper-gtk/clapper-gtk-container.h>
|
||||
|
||||
@@ -35,6 +36,7 @@ G_BEGIN_DECLS
|
||||
#define CLAPPER_GTK_TYPE_LEAD_CONTAINER (clapper_gtk_lead_container_get_type())
|
||||
#define CLAPPER_GTK_LEAD_CONTAINER_CAST(obj) ((ClapperGtkLeadContainer *)(obj))
|
||||
|
||||
CLAPPER_GTK_API
|
||||
G_DECLARE_DERIVABLE_TYPE (ClapperGtkLeadContainer, clapper_gtk_lead_container, CLAPPER_GTK, LEAD_CONTAINER, ClapperGtkContainer)
|
||||
|
||||
struct _ClapperGtkLeadContainerClass
|
||||
@@ -45,14 +47,19 @@ struct _ClapperGtkLeadContainerClass
|
||||
gpointer padding[4];
|
||||
};
|
||||
|
||||
CLAPPER_GTK_API
|
||||
GtkWidget * clapper_gtk_lead_container_new (void);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_lead_container_set_leading (ClapperGtkLeadContainer *lead_container, gboolean leading);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
gboolean clapper_gtk_lead_container_get_leading (ClapperGtkLeadContainer *lead_container);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_lead_container_set_blocked_actions (ClapperGtkLeadContainer *lead_container, ClapperGtkVideoActionMask actions);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
ClapperGtkVideoActionMask clapper_gtk_lead_container_get_blocked_actions (ClapperGtkLeadContainer *lead_container);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -27,13 +27,17 @@
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <clapper-gtk/clapper-gtk-visibility.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLAPPER_GTK_TYPE_NEXT_ITEM_BUTTON (clapper_gtk_next_item_button_get_type())
|
||||
#define CLAPPER_GTK_NEXT_ITEM_BUTTON_CAST(obj) ((ClapperGtkNextItemButton *)(obj))
|
||||
|
||||
CLAPPER_GTK_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperGtkNextItemButton, clapper_gtk_next_item_button, CLAPPER_GTK, NEXT_ITEM_BUTTON, GtkButton)
|
||||
|
||||
CLAPPER_GTK_API
|
||||
GtkWidget * clapper_gtk_next_item_button_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -27,13 +27,17 @@
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <clapper-gtk/clapper-gtk-visibility.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLAPPER_GTK_TYPE_PREVIOUS_ITEM_BUTTON (clapper_gtk_previous_item_button_get_type())
|
||||
#define CLAPPER_GTK_PREVIOUS_ITEM_BUTTON_CAST(obj) ((ClapperGtkPreviousItemButton *)(obj))
|
||||
|
||||
CLAPPER_GTK_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperGtkPreviousItemButton, clapper_gtk_previous_item_button, CLAPPER_GTK, PREVIOUS_ITEM_BUTTON, GtkButton)
|
||||
|
||||
CLAPPER_GTK_API
|
||||
GtkWidget * clapper_gtk_previous_item_button_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -28,21 +28,29 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <clapper/clapper.h>
|
||||
|
||||
#include <clapper-gtk/clapper-gtk-visibility.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLAPPER_GTK_TYPE_SEEK_BAR (clapper_gtk_seek_bar_get_type())
|
||||
#define CLAPPER_GTK_SEEK_BAR_CAST(obj) ((ClapperGtkSeekBar *)(obj))
|
||||
|
||||
CLAPPER_GTK_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperGtkSeekBar, clapper_gtk_seek_bar, CLAPPER_GTK, SEEK_BAR, GtkWidget)
|
||||
|
||||
CLAPPER_GTK_API
|
||||
GtkWidget * clapper_gtk_seek_bar_new (void);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_seek_bar_set_reveal_labels (ClapperGtkSeekBar *seek_bar, gboolean reveal);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
gboolean clapper_gtk_seek_bar_get_reveal_labels (ClapperGtkSeekBar *seek_bar);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_seek_bar_set_seek_method (ClapperGtkSeekBar *seek_bar, ClapperPlayerSeekMethod method);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
ClapperPlayerSeekMethod clapper_gtk_seek_bar_get_seek_method (ClapperGtkSeekBar *seek_bar);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -26,6 +26,8 @@
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <clapper-gtk/clapper-gtk-visibility.h>
|
||||
#include <clapper-gtk/clapper-gtk-container.h>
|
||||
#include <clapper-gtk/clapper-gtk-extra-menu-button.h>
|
||||
|
||||
@@ -34,18 +36,25 @@ G_BEGIN_DECLS
|
||||
#define CLAPPER_GTK_TYPE_SIMPLE_CONTROLS (clapper_gtk_simple_controls_get_type())
|
||||
#define CLAPPER_GTK_SIMPLE_CONTROLS_CAST(obj) ((ClapperGtkSimpleControls *)(obj))
|
||||
|
||||
CLAPPER_GTK_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperGtkSimpleControls, clapper_gtk_simple_controls, CLAPPER_GTK, SIMPLE_CONTROLS, ClapperGtkContainer)
|
||||
|
||||
CLAPPER_GTK_API
|
||||
GtkWidget * clapper_gtk_simple_controls_new (void);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_simple_controls_set_fullscreenable (ClapperGtkSimpleControls *controls, gboolean fullscreenable);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
gboolean clapper_gtk_simple_controls_get_fullscreenable (ClapperGtkSimpleControls *controls);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_simple_controls_set_seek_method (ClapperGtkSimpleControls *controls, ClapperPlayerSeekMethod method);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
ClapperPlayerSeekMethod clapper_gtk_simple_controls_get_seek_method (ClapperGtkSimpleControls *controls);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
ClapperGtkExtraMenuButton * clapper_gtk_simple_controls_get_extra_menu_button (ClapperGtkSimpleControls *controls);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -26,6 +26,8 @@
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <clapper-gtk/clapper-gtk-visibility.h>
|
||||
#include <clapper-gtk/clapper-gtk-lead-container.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -33,14 +35,19 @@ G_BEGIN_DECLS
|
||||
#define CLAPPER_GTK_TYPE_TITLE_HEADER (clapper_gtk_title_header_get_type())
|
||||
#define CLAPPER_GTK_TITLE_HEADER_CAST(obj) ((ClapperGtkTitleHeader *)(obj))
|
||||
|
||||
CLAPPER_GTK_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperGtkTitleHeader, clapper_gtk_title_header, CLAPPER_GTK, TITLE_HEADER, ClapperGtkLeadContainer)
|
||||
|
||||
CLAPPER_GTK_API
|
||||
GtkWidget * clapper_gtk_title_header_new (void);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
const gchar * clapper_gtk_title_header_get_current_title (ClapperGtkTitleHeader *header);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_title_header_set_fallback_to_uri (ClapperGtkTitleHeader *header, gboolean enabled);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
gboolean clapper_gtk_title_header_get_fallback_to_uri (ClapperGtkTitleHeader *header);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -28,23 +28,32 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <clapper/clapper.h>
|
||||
|
||||
#include <clapper-gtk/clapper-gtk-visibility.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLAPPER_GTK_TYPE_TITLE_LABEL (clapper_gtk_title_label_get_type())
|
||||
#define CLAPPER_GTK_TITLE_LABEL_CAST(obj) ((ClapperGtkTitleLabel *)(obj))
|
||||
|
||||
CLAPPER_GTK_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperGtkTitleLabel, clapper_gtk_title_label, CLAPPER_GTK, TITLE_LABEL, GtkWidget)
|
||||
|
||||
CLAPPER_GTK_API
|
||||
GtkWidget * clapper_gtk_title_label_new (void);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_title_label_set_media_item (ClapperGtkTitleLabel *label, ClapperMediaItem *item);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
ClapperMediaItem * clapper_gtk_title_label_get_media_item (ClapperGtkTitleLabel *label);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
const gchar * clapper_gtk_title_label_get_current_title (ClapperGtkTitleLabel *label);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_title_label_set_fallback_to_uri (ClapperGtkTitleLabel *label, gboolean enabled);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
gboolean clapper_gtk_title_label_get_fallback_to_uri (ClapperGtkTitleLabel *label);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -27,13 +27,17 @@
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <clapper-gtk/clapper-gtk-visibility.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLAPPER_GTK_TYPE_TOGGLE_FULLSCREEN_BUTTON (clapper_gtk_toggle_fullscreen_button_get_type())
|
||||
#define CLAPPER_GTK_TOGGLE_FULLSCREEN_BUTTON_CAST(obj) ((ClapperGtkToggleFullscreenButton *)(obj))
|
||||
|
||||
CLAPPER_GTK_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperGtkToggleFullscreenButton, clapper_gtk_toggle_fullscreen_button, CLAPPER_GTK, TOGGLE_FULLSCREEN_BUTTON, GtkButton)
|
||||
|
||||
CLAPPER_GTK_API
|
||||
GtkWidget * clapper_gtk_toggle_fullscreen_button_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -27,13 +27,17 @@
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <clapper-gtk/clapper-gtk-visibility.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLAPPER_GTK_TYPE_TOGGLE_PLAY_BUTTON (clapper_gtk_toggle_play_button_get_type())
|
||||
#define CLAPPER_GTK_TOGGLE_PLAY_BUTTON_CAST(obj) ((ClapperGtkTogglePlayButton *)(obj))
|
||||
|
||||
CLAPPER_GTK_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperGtkTogglePlayButton, clapper_gtk_toggle_play_button, CLAPPER_GTK, TOGGLE_PLAY_BUTTON, GtkButton)
|
||||
|
||||
CLAPPER_GTK_API
|
||||
GtkWidget * clapper_gtk_toggle_play_button_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -27,8 +27,11 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <clapper/clapper.h>
|
||||
|
||||
#include <clapper-gtk/clapper-gtk-visibility.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
CLAPPER_GTK_API
|
||||
ClapperPlayer * clapper_gtk_get_player_from_ancestor (GtkWidget *widget);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -1065,7 +1065,7 @@ _player_missing_plugin_cb (ClapperPlayer *player, const gchar *name,
|
||||
{
|
||||
/* Some media files have custom/proprietary metadata,
|
||||
* it should be safe to simply ignore these */
|
||||
if (g_str_has_prefix (name, "meta/"))
|
||||
if (strstr (name, "meta/") != NULL)
|
||||
return;
|
||||
|
||||
/* XXX: Playbin2 seems to not emit state change here,
|
||||
@@ -1583,7 +1583,7 @@ clapper_gtk_video_class_init (ClapperGtkVideoClass *klass)
|
||||
*/
|
||||
param_specs[PROP_FADE_DELAY] = g_param_spec_uint ("fade-delay",
|
||||
NULL, NULL, 1, G_MAXUINT, DEFAULT_FADE_DELAY,
|
||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClapperGtkVideo:touch-fade-delay:
|
||||
@@ -1593,7 +1593,7 @@ clapper_gtk_video_class_init (ClapperGtkVideoClass *klass)
|
||||
*/
|
||||
param_specs[PROP_TOUCH_FADE_DELAY] = g_param_spec_uint ("touch-fade-delay",
|
||||
NULL, NULL, 1, G_MAXUINT, DEFAULT_TOUCH_FADE_DELAY,
|
||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClapperGtkVideo:auto-inhibit:
|
||||
|
@@ -28,33 +28,47 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <clapper/clapper.h>
|
||||
|
||||
#include <clapper-gtk/clapper-gtk-visibility.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLAPPER_GTK_TYPE_VIDEO (clapper_gtk_video_get_type())
|
||||
#define CLAPPER_GTK_VIDEO_CAST(obj) ((ClapperGtkVideo *)(obj))
|
||||
|
||||
CLAPPER_GTK_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperGtkVideo, clapper_gtk_video, CLAPPER_GTK, VIDEO, GtkWidget)
|
||||
|
||||
CLAPPER_GTK_API
|
||||
GtkWidget * clapper_gtk_video_new (void);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_video_add_overlay (ClapperGtkVideo *video, GtkWidget *widget);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_video_add_fading_overlay (ClapperGtkVideo *video, GtkWidget *widget);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
ClapperPlayer * clapper_gtk_video_get_player (ClapperGtkVideo *video);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_video_set_fade_delay (ClapperGtkVideo *video, guint delay);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
guint clapper_gtk_video_get_fade_delay (ClapperGtkVideo *video);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_video_set_touch_fade_delay (ClapperGtkVideo *video, guint delay);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
guint clapper_gtk_video_get_touch_fade_delay (ClapperGtkVideo *video);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_video_set_auto_inhibit (ClapperGtkVideo *video, gboolean inhibit);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
gboolean clapper_gtk_video_get_auto_inhibit (ClapperGtkVideo *video);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
gboolean clapper_gtk_video_get_inhibited (ClapperGtkVideo *video);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -39,6 +39,19 @@ configure_file(
|
||||
configuration: config_h,
|
||||
)
|
||||
|
||||
visibility_conf = configuration_data()
|
||||
|
||||
visibility_conf.set(
|
||||
'CLAPPER_API',
|
||||
'CLAPPER_GTK',
|
||||
)
|
||||
|
||||
clappergtk_visibility_header = configure_file(
|
||||
input: '../shared/clapper-api-visibility.h.in',
|
||||
output: 'clapper-gtk-visibility.h',
|
||||
configuration: visibility_conf,
|
||||
)
|
||||
|
||||
version_conf = configuration_data()
|
||||
|
||||
version_conf.set(
|
||||
@@ -93,6 +106,7 @@ clappergtk_headers = [
|
||||
'clapper-gtk-utils.h',
|
||||
'clapper-gtk-video.h',
|
||||
clappergtk_version_header,
|
||||
clappergtk_visibility_header,
|
||||
]
|
||||
clappergtk_sources = [
|
||||
'clapper-gtk-billboard.c',
|
||||
@@ -122,11 +136,17 @@ clappergtk_c_args = [
|
||||
'-DGST_USE_UNSTABLE_API',
|
||||
]
|
||||
|
||||
if get_option('default_library') == 'static'
|
||||
clappergtk_c_args += ['-DCLAPPER_GTK_STATIC_COMPILATION']
|
||||
endif
|
||||
|
||||
clappergtk_headers_dir = join_paths(includedir, clapper_api_name, 'clapper-gtk')
|
||||
|
||||
clappergtk_enums = gnome.mkenums_simple(
|
||||
'clapper-gtk-enum-types',
|
||||
sources: clappergtk_headers,
|
||||
decorator: 'CLAPPER_GTK_API',
|
||||
header_prefix: '#include <clapper-gtk/clapper-gtk-visibility.h>',
|
||||
identifier_prefix: 'ClapperGtk',
|
||||
symbol_prefix: 'clapper_gtk',
|
||||
install_header: true,
|
||||
@@ -215,6 +235,7 @@ clappergtk_dep = declare_dependency(
|
||||
include_directories: clappergtk_conf_inc,
|
||||
dependencies: clappergtk_deps,
|
||||
sources: [
|
||||
clappergtk_visibility_header,
|
||||
clappergtk_version_header,
|
||||
clappergtk_enums[1],
|
||||
],
|
||||
|
@@ -3,7 +3,7 @@ msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-04-12 19:52+0200\n"
|
||||
"PO-Revision-Date: 2024-04-12 18:47\n"
|
||||
"PO-Revision-Date: 2024-08-12 08:36\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Czech\n"
|
||||
"Language: cs_CZ\n"
|
||||
@@ -20,7 +20,7 @@ msgstr ""
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:9
|
||||
#: src/lib/clapper-gtk/clapper-gtk-extra-menu-button.c:227
|
||||
msgid "Video"
|
||||
msgstr ""
|
||||
msgstr "Video"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:17
|
||||
#: src/lib/clapper-gtk/clapper-gtk-extra-menu-button.c:228
|
||||
@@ -34,33 +34,33 @@ msgstr "Titulky"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:28
|
||||
msgid "Show Subtitles"
|
||||
msgstr ""
|
||||
msgstr "Zobrazit Titulky"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:32
|
||||
msgid "Open…"
|
||||
msgstr ""
|
||||
msgstr "Otevřít…"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:75
|
||||
msgid "Mute"
|
||||
msgstr ""
|
||||
msgstr "Ztlumit"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:119
|
||||
msgid "Reset"
|
||||
msgstr ""
|
||||
msgstr "Resetovat"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-status.c:79
|
||||
msgid "Unplayable Content"
|
||||
msgstr ""
|
||||
msgstr "Nepřehratelný Obsah"
|
||||
|
||||
#. TRANSLATORS: Please do not try to translate "GStreamer" (it is a library name).
|
||||
#: src/lib/clapper-gtk/clapper-gtk-status.c:89
|
||||
#, c-format
|
||||
msgid "Your GStreamer installation is missing a plugin: %s"
|
||||
msgstr ""
|
||||
msgstr "Vaší instalaci GStreamer chybí plugin: %s"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-status.c:90
|
||||
msgid "Missing Plugin"
|
||||
msgstr ""
|
||||
msgstr "Chybějící Plugin"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-stream-check-button.c:82
|
||||
#: src/lib/clapper-gtk/clapper-gtk-stream-check-button.c:126
|
||||
@@ -73,9 +73,9 @@ msgstr "Kanály"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-title-label.c:91
|
||||
msgid "No media"
|
||||
msgstr ""
|
||||
msgstr "Žádná média"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-title-label.c:103
|
||||
msgid "Unknown title"
|
||||
msgstr ""
|
||||
msgstr "Neznámý název"
|
||||
|
||||
|
@@ -3,7 +3,7 @@ msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-04-12 19:52+0200\n"
|
||||
"PO-Revision-Date: 2024-04-12 18:48\n"
|
||||
"PO-Revision-Date: 2024-09-07 11:10\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Persian\n"
|
||||
"Language: fa_IR\n"
|
||||
@@ -20,12 +20,12 @@ msgstr ""
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:9
|
||||
#: src/lib/clapper-gtk/clapper-gtk-extra-menu-button.c:227
|
||||
msgid "Video"
|
||||
msgstr ""
|
||||
msgstr "ویدیو"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:17
|
||||
#: src/lib/clapper-gtk/clapper-gtk-extra-menu-button.c:228
|
||||
msgid "Audio"
|
||||
msgstr "صوتی"
|
||||
msgstr "صدا"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:25
|
||||
#: src/lib/clapper-gtk/clapper-gtk-extra-menu-button.c:229
|
||||
@@ -34,38 +34,38 @@ msgstr "زیرنویسها"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:28
|
||||
msgid "Show Subtitles"
|
||||
msgstr ""
|
||||
msgstr "نمایش زیرنویس"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:32
|
||||
msgid "Open…"
|
||||
msgstr ""
|
||||
msgstr "گشودن…"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:75
|
||||
msgid "Mute"
|
||||
msgstr ""
|
||||
msgstr "خموش"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:119
|
||||
msgid "Reset"
|
||||
msgstr ""
|
||||
msgstr "بازنشانی"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-status.c:79
|
||||
msgid "Unplayable Content"
|
||||
msgstr ""
|
||||
msgstr "محتوای غیر قابل پخش"
|
||||
|
||||
#. TRANSLATORS: Please do not try to translate "GStreamer" (it is a library name).
|
||||
#: src/lib/clapper-gtk/clapper-gtk-status.c:89
|
||||
#, c-format
|
||||
msgid "Your GStreamer installation is missing a plugin: %s"
|
||||
msgstr ""
|
||||
msgstr "نصب جیاستریمرتان افزایهای را ندارد: %s"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-status.c:90
|
||||
msgid "Missing Plugin"
|
||||
msgstr ""
|
||||
msgstr "افزایه ناموجود"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-stream-check-button.c:82
|
||||
#: src/lib/clapper-gtk/clapper-gtk-stream-check-button.c:126
|
||||
msgid "Undetermined"
|
||||
msgstr "نامشخص"
|
||||
msgstr "تشخیص داده نشده"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-stream-check-button.c:82
|
||||
msgid "Channels"
|
||||
@@ -73,9 +73,9 @@ msgstr "کانالها"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-title-label.c:91
|
||||
msgid "No media"
|
||||
msgstr ""
|
||||
msgstr "بدون رسانه"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-title-label.c:103
|
||||
msgid "Unknown title"
|
||||
msgstr ""
|
||||
msgstr "عنوان ناشناس"
|
||||
|
||||
|
81
src/lib/clapper-gtk/po/hi.po
Normal file
81
src/lib/clapper-gtk/po/hi.po
Normal file
@@ -0,0 +1,81 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-04-12 19:52+0200\n"
|
||||
"PO-Revision-Date: 2024-07-09 18:54\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Hindi\n"
|
||||
"Language: hi_IN\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: hi\n"
|
||||
"X-Crowdin-File: /master/src/lib/clapper-gtk/po/clapper-gtk.pot\n"
|
||||
"X-Crowdin-File-ID: 46\n"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:9
|
||||
#: src/lib/clapper-gtk/clapper-gtk-extra-menu-button.c:227
|
||||
msgid "Video"
|
||||
msgstr "वीडियो"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:17
|
||||
#: src/lib/clapper-gtk/clapper-gtk-extra-menu-button.c:228
|
||||
msgid "Audio"
|
||||
msgstr "ऑडियो"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:25
|
||||
#: src/lib/clapper-gtk/clapper-gtk-extra-menu-button.c:229
|
||||
msgid "Subtitles"
|
||||
msgstr "उपशीर्षक"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:28
|
||||
msgid "Show Subtitles"
|
||||
msgstr "उपशीर्षक दिखाएं"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:32
|
||||
msgid "Open…"
|
||||
msgstr "खोलें…"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:75
|
||||
msgid "Mute"
|
||||
msgstr "मूक"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:119
|
||||
msgid "Reset"
|
||||
msgstr "रीसेट"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-status.c:79
|
||||
msgid "Unplayable Content"
|
||||
msgstr "चलाने योग्य सामग्री नहीं"
|
||||
|
||||
#. TRANSLATORS: Please do not try to translate "GStreamer" (it is a library name).
|
||||
#: src/lib/clapper-gtk/clapper-gtk-status.c:89
|
||||
#, c-format
|
||||
msgid "Your GStreamer installation is missing a plugin: %s"
|
||||
msgstr "आपके GStreamer स्थापना में एक प्लगइन गायब है: %s"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-status.c:90
|
||||
msgid "Missing Plugin"
|
||||
msgstr "गायब प्लगइन"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-stream-check-button.c:82
|
||||
#: src/lib/clapper-gtk/clapper-gtk-stream-check-button.c:126
|
||||
msgid "Undetermined"
|
||||
msgstr "अनिर्धारित"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-stream-check-button.c:82
|
||||
msgid "Channels"
|
||||
msgstr "चैनल"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-title-label.c:91
|
||||
msgid "No media"
|
||||
msgstr "मीडिया नहीं"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-title-label.c:103
|
||||
msgid "Unknown title"
|
||||
msgstr "अज्ञात शीर्षक"
|
||||
|
@@ -3,7 +3,7 @@ msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-04-12 19:52+0200\n"
|
||||
"PO-Revision-Date: 2024-04-12 18:47\n"
|
||||
"PO-Revision-Date: 2024-10-05 12:47\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Norwegian\n"
|
||||
"Language: no_NO\n"
|
||||
@@ -20,62 +20,62 @@ msgstr ""
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:9
|
||||
#: src/lib/clapper-gtk/clapper-gtk-extra-menu-button.c:227
|
||||
msgid "Video"
|
||||
msgstr ""
|
||||
msgstr "Video"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:17
|
||||
#: src/lib/clapper-gtk/clapper-gtk-extra-menu-button.c:228
|
||||
msgid "Audio"
|
||||
msgstr ""
|
||||
msgstr "Lyd"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:25
|
||||
#: src/lib/clapper-gtk/clapper-gtk-extra-menu-button.c:229
|
||||
msgid "Subtitles"
|
||||
msgstr ""
|
||||
msgstr "Undertekstning"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:28
|
||||
msgid "Show Subtitles"
|
||||
msgstr ""
|
||||
msgstr "Vis undertekster"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:32
|
||||
msgid "Open…"
|
||||
msgstr ""
|
||||
msgstr "Åpne…"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:75
|
||||
msgid "Mute"
|
||||
msgstr ""
|
||||
msgstr "Demp"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:119
|
||||
msgid "Reset"
|
||||
msgstr ""
|
||||
msgstr "Tilbakestill"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-status.c:79
|
||||
msgid "Unplayable Content"
|
||||
msgstr ""
|
||||
msgstr "Uavspillelig innhold"
|
||||
|
||||
#. TRANSLATORS: Please do not try to translate "GStreamer" (it is a library name).
|
||||
#: src/lib/clapper-gtk/clapper-gtk-status.c:89
|
||||
#, c-format
|
||||
msgid "Your GStreamer installation is missing a plugin: %s"
|
||||
msgstr ""
|
||||
msgstr "GStreamer-innstallasjon din mangler et tillegg: %s"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-status.c:90
|
||||
msgid "Missing Plugin"
|
||||
msgstr ""
|
||||
msgstr "Manglende tillegg"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-stream-check-button.c:82
|
||||
#: src/lib/clapper-gtk/clapper-gtk-stream-check-button.c:126
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
msgstr "Ubestemt"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-stream-check-button.c:82
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
msgstr "Kanaler"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-title-label.c:91
|
||||
msgid "No media"
|
||||
msgstr ""
|
||||
msgstr "Ingen medier"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-title-label.c:103
|
||||
msgid "Unknown title"
|
||||
msgstr ""
|
||||
msgstr "Ukjent tittel"
|
||||
|
||||
|
@@ -3,7 +3,7 @@ msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-04-12 19:52+0200\n"
|
||||
"PO-Revision-Date: 2024-04-12 18:47\n"
|
||||
"PO-Revision-Date: 2024-08-03 08:27\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Russian\n"
|
||||
"Language: ru_RU\n"
|
||||
@@ -20,7 +20,7 @@ msgstr ""
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:9
|
||||
#: src/lib/clapper-gtk/clapper-gtk-extra-menu-button.c:227
|
||||
msgid "Video"
|
||||
msgstr ""
|
||||
msgstr "Видео"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:17
|
||||
#: src/lib/clapper-gtk/clapper-gtk-extra-menu-button.c:228
|
||||
@@ -34,33 +34,33 @@ msgstr "Субтитры"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:28
|
||||
msgid "Show Subtitles"
|
||||
msgstr ""
|
||||
msgstr "Показать субтитры"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:32
|
||||
msgid "Open…"
|
||||
msgstr ""
|
||||
msgstr "Открыть…"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:75
|
||||
msgid "Mute"
|
||||
msgstr ""
|
||||
msgstr "Без звука"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:119
|
||||
msgid "Reset"
|
||||
msgstr ""
|
||||
msgstr "Сброс"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-status.c:79
|
||||
msgid "Unplayable Content"
|
||||
msgstr ""
|
||||
msgstr "Невоспроизводимый контент"
|
||||
|
||||
#. TRANSLATORS: Please do not try to translate "GStreamer" (it is a library name).
|
||||
#: src/lib/clapper-gtk/clapper-gtk-status.c:89
|
||||
#, c-format
|
||||
msgid "Your GStreamer installation is missing a plugin: %s"
|
||||
msgstr ""
|
||||
msgstr "В вашей установке GStreamer отсутствует модуль: %s"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-status.c:90
|
||||
msgid "Missing Plugin"
|
||||
msgstr ""
|
||||
msgstr "Отсутствующий плагин"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-stream-check-button.c:82
|
||||
#: src/lib/clapper-gtk/clapper-gtk-stream-check-button.c:126
|
||||
@@ -73,9 +73,9 @@ msgstr "Каналы"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-title-label.c:91
|
||||
msgid "No media"
|
||||
msgstr ""
|
||||
msgstr "Нет медиафайлов"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-title-label.c:103
|
||||
msgid "Unknown title"
|
||||
msgstr ""
|
||||
msgstr "Неизвестное название"
|
||||
|
||||
|
@@ -47,6 +47,8 @@ void clapper_app_bus_post_refresh_timeline (ClapperAppBus *app_bus, GstObject *s
|
||||
|
||||
void clapper_app_bus_post_simple_signal (ClapperAppBus *app_bus, GstObject *src, guint signal_id);
|
||||
|
||||
void clapper_app_bus_post_object_desc_signal (ClapperAppBus *app_bus, GstObject *src, guint signal_id, GstObject *object, const gchar *desc);
|
||||
|
||||
void clapper_app_bus_post_desc_with_details_signal (ClapperAppBus *app_bus, GstObject *src, guint signal_id, const gchar *desc, const gchar *details);
|
||||
|
||||
void clapper_app_bus_post_error_signal (ClapperAppBus *app_bus, GstObject *src, guint signal_id, GError *error, const gchar *debug_info);
|
||||
|
@@ -43,6 +43,7 @@ enum
|
||||
CLAPPER_APP_BUS_STRUCTURE_REFRESH_STREAMS,
|
||||
CLAPPER_APP_BUS_STRUCTURE_REFRESH_TIMELINE,
|
||||
CLAPPER_APP_BUS_STRUCTURE_SIMPLE_SIGNAL,
|
||||
CLAPPER_APP_BUS_STRUCTURE_OBJECT_DESC_SIGNAL,
|
||||
CLAPPER_APP_BUS_STRUCTURE_DESC_WITH_DETAILS_SIGNAL,
|
||||
CLAPPER_APP_BUS_STRUCTURE_ERROR_SIGNAL
|
||||
};
|
||||
@@ -53,6 +54,7 @@ static ClapperBusQuark _structure_quarks[] = {
|
||||
{"refresh-streams", 0},
|
||||
{"refresh-timeline", 0},
|
||||
{"simple-signal", 0},
|
||||
{"object-desc-signal", 0},
|
||||
{"desc-with-details-signal", 0},
|
||||
{"error-signal", 0},
|
||||
{NULL, 0}
|
||||
@@ -63,6 +65,7 @@ enum
|
||||
CLAPPER_APP_BUS_FIELD_UNKNOWN = 0,
|
||||
CLAPPER_APP_BUS_FIELD_PSPEC,
|
||||
CLAPPER_APP_BUS_FIELD_SIGNAL_ID,
|
||||
CLAPPER_APP_BUS_FIELD_OBJECT,
|
||||
CLAPPER_APP_BUS_FIELD_DESC,
|
||||
CLAPPER_APP_BUS_FIELD_DETAILS,
|
||||
CLAPPER_APP_BUS_FIELD_ERROR,
|
||||
@@ -73,6 +76,7 @@ static ClapperBusQuark _field_quarks[] = {
|
||||
{"unknown", 0},
|
||||
{"pspec", 0},
|
||||
{"signal-id", 0},
|
||||
{"object", 0},
|
||||
{"desc", 0},
|
||||
{"details", 0},
|
||||
{"error", 0},
|
||||
@@ -177,6 +181,37 @@ _handle_simple_signal_msg (GstMessage *msg, const GstStructure *structure)
|
||||
g_signal_emit (_MESSAGE_SRC_GOBJECT (msg), signal_id, 0);
|
||||
}
|
||||
|
||||
void
|
||||
clapper_app_bus_post_object_desc_signal (ClapperAppBus *self,
|
||||
GstObject *src, guint signal_id,
|
||||
GstObject *object, const gchar *desc)
|
||||
{
|
||||
GstStructure *structure = gst_structure_new_id (_STRUCTURE_QUARK (OBJECT_DESC_SIGNAL),
|
||||
_FIELD_QUARK (SIGNAL_ID), G_TYPE_UINT, signal_id,
|
||||
_FIELD_QUARK (OBJECT), GST_TYPE_OBJECT, object,
|
||||
_FIELD_QUARK (DESC), G_TYPE_STRING, desc,
|
||||
NULL);
|
||||
gst_bus_post (GST_BUS_CAST (self), gst_message_new_application (src, structure));
|
||||
}
|
||||
|
||||
static inline void
|
||||
_handle_object_desc_signal_msg (GstMessage *msg, const GstStructure *structure)
|
||||
{
|
||||
guint signal_id = 0;
|
||||
GstObject *object = NULL;
|
||||
gchar *desc = NULL;
|
||||
|
||||
gst_structure_id_get (structure,
|
||||
_FIELD_QUARK (SIGNAL_ID), G_TYPE_UINT, &signal_id,
|
||||
_FIELD_QUARK (OBJECT), GST_TYPE_OBJECT, &object,
|
||||
_FIELD_QUARK (DESC), G_TYPE_STRING, &desc,
|
||||
NULL);
|
||||
g_signal_emit (_MESSAGE_SRC_GOBJECT (msg), signal_id, 0, object, desc);
|
||||
|
||||
gst_object_unref (object);
|
||||
g_free (desc);
|
||||
}
|
||||
|
||||
void
|
||||
clapper_app_bus_post_desc_with_details_signal (ClapperAppBus *self,
|
||||
GstObject *src, guint signal_id,
|
||||
@@ -253,6 +288,8 @@ clapper_app_bus_message_func (GstBus *bus, GstMessage *msg, gpointer user_data G
|
||||
_handle_refresh_timeline_msg (msg, structure);
|
||||
else if (quark == _STRUCTURE_QUARK (SIMPLE_SIGNAL))
|
||||
_handle_simple_signal_msg (msg, structure);
|
||||
else if (quark == _STRUCTURE_QUARK (OBJECT_DESC_SIGNAL))
|
||||
_handle_object_desc_signal_msg (msg, structure);
|
||||
else if (quark == _STRUCTURE_QUARK (ERROR_SIGNAL))
|
||||
_handle_error_signal_msg (msg, structure);
|
||||
else if (quark == _STRUCTURE_QUARK (DESC_WITH_DETAILS_SIGNAL))
|
||||
|
@@ -25,6 +25,8 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <clapper/clapper-visibility.h>
|
||||
#include <clapper/clapper-stream.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -32,20 +34,28 @@ G_BEGIN_DECLS
|
||||
#define CLAPPER_TYPE_AUDIO_STREAM (clapper_audio_stream_get_type())
|
||||
#define CLAPPER_AUDIO_STREAM_CAST(obj) ((ClapperAudioStream *)(obj))
|
||||
|
||||
CLAPPER_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperAudioStream, clapper_audio_stream, CLAPPER, AUDIO_STREAM, ClapperStream)
|
||||
|
||||
CLAPPER_API
|
||||
gchar * clapper_audio_stream_get_codec (ClapperAudioStream *stream);
|
||||
|
||||
CLAPPER_API
|
||||
guint clapper_audio_stream_get_bitrate (ClapperAudioStream *stream);
|
||||
|
||||
CLAPPER_API
|
||||
gchar * clapper_audio_stream_get_sample_format (ClapperAudioStream *stream);
|
||||
|
||||
CLAPPER_API
|
||||
gint clapper_audio_stream_get_sample_rate (ClapperAudioStream *stream);
|
||||
|
||||
CLAPPER_API
|
||||
gint clapper_audio_stream_get_channels (ClapperAudioStream *stream);
|
||||
|
||||
CLAPPER_API
|
||||
gchar * clapper_audio_stream_get_lang_code (ClapperAudioStream *stream);
|
||||
|
||||
CLAPPER_API
|
||||
gchar * clapper_audio_stream_get_lang_name (ClapperAudioStream *stream);
|
||||
|
||||
G_END_DECLS
|
||||
|
42
src/lib/clapper/clapper-enhancers-loader-private.h
Normal file
42
src/lib/clapper/clapper-enhancers-loader-private.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/* Clapper Playback Library
|
||||
* Copyright (C) 2024 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 Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser 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 <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_enhancers_loader_initialize (void);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean clapper_enhancers_loader_has_enhancers (GType iface_type);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gchar ** clapper_enhancers_loader_get_schemes (GType iface_type);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean clapper_enhancers_loader_check (GType iface_type, const gchar *scheme, const gchar *host, const gchar **name);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GObject * clapper_enhancers_loader_create_enhancer_for_uri (GType iface_type, GUri *uri);
|
||||
|
||||
G_END_DECLS
|
388
src/lib/clapper/clapper-enhancers-loader.c
Normal file
388
src/lib/clapper/clapper-enhancers-loader.c
Normal file
@@ -0,0 +1,388 @@
|
||||
/* Clapper Playback Library
|
||||
* Copyright (C) 2024 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 Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser 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 "config.h"
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <libpeas.h>
|
||||
|
||||
#include "clapper-enhancers-loader-private.h"
|
||||
|
||||
#define ENHANCER_INTERFACES "X-Interfaces"
|
||||
#define ENHANCER_SCHEMES "X-Schemes"
|
||||
#define ENHANCER_HOSTS "X-Hosts"
|
||||
#define ENHANCER_IFACE_NAME_FROM_TYPE(type) (g_type_name (type) + 7) // strip "Clapper" prefix
|
||||
|
||||
#define GST_CAT_DEFAULT clapper_enhancers_loader_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
static PeasEngine *_engine = NULL;
|
||||
static GMutex load_lock;
|
||||
|
||||
/*
|
||||
* clapper_enhancers_loader_initialize:
|
||||
*
|
||||
* Initializes #PeasEngine with directories that store enhancers.
|
||||
*/
|
||||
void
|
||||
clapper_enhancers_loader_initialize (void)
|
||||
{
|
||||
const gchar *enhancers_path;
|
||||
gchar **dir_paths;
|
||||
guint i;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperenhancersloader", 0,
|
||||
"Clapper Enhancer Loader");
|
||||
|
||||
enhancers_path = g_getenv ("CLAPPER_ENHANCERS_PATH");
|
||||
if (!enhancers_path || *enhancers_path == '\0')
|
||||
enhancers_path = CLAPPER_ENHANCERS_PATH;
|
||||
|
||||
GST_INFO ("Initializing Clapper enhancers with path: \"%s\"", enhancers_path);
|
||||
|
||||
_engine = peas_engine_new ();
|
||||
|
||||
/* Peas loaders are loaded lazily, so it should be fine
|
||||
* to just enable them all here (even if not installed) */
|
||||
peas_engine_enable_loader (_engine, "python");
|
||||
peas_engine_enable_loader (_engine, "gjs");
|
||||
|
||||
dir_paths = g_strsplit (enhancers_path, G_SEARCHPATH_SEPARATOR_S, 0);
|
||||
|
||||
for (i = 0; dir_paths[i]; ++i)
|
||||
peas_engine_add_search_path (_engine, dir_paths[i], NULL);
|
||||
|
||||
g_strfreev (dir_paths);
|
||||
|
||||
if (gst_debug_category_get_threshold (GST_CAT_DEFAULT) >= GST_LEVEL_INFO) {
|
||||
GListModel *list = (GListModel *) _engine;
|
||||
guint n_items = g_list_model_get_n_items (list);
|
||||
|
||||
for (i = 0; i < n_items; ++i) {
|
||||
PeasPluginInfo *info = (PeasPluginInfo *) g_list_model_get_item (list, i);
|
||||
GST_INFO ("Found enhancer: %s (%s)", peas_plugin_info_get_name (info),
|
||||
peas_plugin_info_get_external_data (info, ENHANCER_INTERFACES));
|
||||
g_object_unref (info);
|
||||
}
|
||||
|
||||
GST_INFO ("Clapper enhancers initialized, found: %u", n_items);
|
||||
}
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
_is_name_listed (const gchar *name, const gchar *list_str)
|
||||
{
|
||||
gsize name_len = strlen (name);
|
||||
guint i = 0;
|
||||
|
||||
while (list_str[i] != '\0') {
|
||||
guint end = i;
|
||||
|
||||
while (list_str[end] != ';' && list_str[end] != '\0')
|
||||
++end;
|
||||
|
||||
/* Compare letters count until separator and prefix of whole string */
|
||||
if (end - i == name_len && g_str_has_prefix (list_str + i, name))
|
||||
return TRUE;
|
||||
|
||||
i = end;
|
||||
|
||||
/* Move to the next letter after ';' */
|
||||
if (list_str[i] != '\0')
|
||||
++i;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* clapper_enhancers_loader_get_info:
|
||||
* @iface_type: an interface #GType
|
||||
* @scheme: an URI scheme
|
||||
* @host: (nullable): an URI host
|
||||
*
|
||||
* Returns: (transfer full) (nullable): available #PeasPluginInfo or %NULL.
|
||||
*/
|
||||
static PeasPluginInfo *
|
||||
clapper_enhancers_loader_get_info (GType iface_type, const gchar *scheme, const gchar *host)
|
||||
{
|
||||
GListModel *list = (GListModel *) _engine;
|
||||
PeasPluginInfo *found_info = NULL;
|
||||
guint i, n_plugins = g_list_model_get_n_items (list);
|
||||
const gchar *iface_name;
|
||||
gboolean is_https;
|
||||
|
||||
if (n_plugins == 0) {
|
||||
GST_INFO ("No Clapper enhancers found");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
iface_name = ENHANCER_IFACE_NAME_FROM_TYPE (iface_type);
|
||||
|
||||
/* Strip common subdomains, so plugins do not
|
||||
* have to list all combinations */
|
||||
if (host) {
|
||||
if (g_str_has_prefix (host, "www."))
|
||||
host += 4;
|
||||
else if (g_str_has_prefix (host, "m."))
|
||||
host += 2;
|
||||
}
|
||||
|
||||
GST_INFO ("Enhancer check, iface: %s, scheme: %s, host: %s",
|
||||
iface_name, scheme, GST_STR_NULL (host));
|
||||
|
||||
is_https = (g_str_has_prefix (scheme, "http")
|
||||
&& (scheme[4] == '\0' || (scheme[4] == 's' && scheme[5] == '\0')));
|
||||
|
||||
if (!host && is_https)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < n_plugins; ++i) {
|
||||
PeasPluginInfo *info = (PeasPluginInfo *) g_list_model_get_item (list, i);
|
||||
const gchar *iface_names, *schemes, *hosts;
|
||||
|
||||
if (!(iface_names = peas_plugin_info_get_external_data (info, ENHANCER_INTERFACES))) {
|
||||
GST_DEBUG ("Skipping enhancer without interfaces: %s", peas_plugin_info_get_name (info));
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
if (!_is_name_listed (iface_name, iface_names)) {
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
if (!(schemes = peas_plugin_info_get_external_data (info, ENHANCER_SCHEMES))) {
|
||||
GST_DEBUG ("Skipping enhancer without schemes: %s", peas_plugin_info_get_name (info));
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
if (!_is_name_listed (scheme, schemes)) {
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
if (is_https) {
|
||||
if (!(hosts = peas_plugin_info_get_external_data (info, ENHANCER_HOSTS))) {
|
||||
GST_DEBUG ("Skipping enhancer without hosts: %s", peas_plugin_info_get_name (info));
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
if (!_is_name_listed (host, hosts)) {
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
found_info = info;
|
||||
break;
|
||||
}
|
||||
|
||||
return found_info;
|
||||
}
|
||||
|
||||
/*
|
||||
* clapper_enhancers_loader_has_enhancers:
|
||||
* @iface_type: an interface #GType
|
||||
*
|
||||
* Check if any enhancer implementing given interface type is available.
|
||||
*
|
||||
* Returns: whether any valid enhancer was found.
|
||||
*/
|
||||
gboolean
|
||||
clapper_enhancers_loader_has_enhancers (GType iface_type)
|
||||
{
|
||||
GListModel *list = (GListModel *) _engine;
|
||||
const gchar *iface_name = ENHANCER_IFACE_NAME_FROM_TYPE (iface_type);
|
||||
guint i, n_plugins;
|
||||
|
||||
GST_DEBUG ("Checking for any enhancers of type: \"%s\"", iface_name);
|
||||
|
||||
n_plugins = g_list_model_get_n_items (list);
|
||||
|
||||
for (i = 0; i < n_plugins; ++i) {
|
||||
PeasPluginInfo *info = (PeasPluginInfo *) g_list_model_get_item (list, i);
|
||||
const gchar *iface_names;
|
||||
|
||||
if (!(iface_names = peas_plugin_info_get_external_data (info, ENHANCER_INTERFACES))) {
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
if (!_is_name_listed (iface_name, iface_names)) {
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Additional validation */
|
||||
if (!peas_plugin_info_get_external_data (info, ENHANCER_SCHEMES)
|
||||
|| !peas_plugin_info_get_external_data (info, ENHANCER_HOSTS)) {
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
|
||||
GST_DEBUG ("Found valid enhancers of type: \"%s\"", iface_name);
|
||||
g_object_unref (info);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GST_DEBUG ("No available enhancers of type: \"%s\"", iface_name);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* clapper_enhancers_loader_get_schemes:
|
||||
* @iface_type: an interface #GType
|
||||
*
|
||||
* Get all supported schemes for a given interface type.
|
||||
* The returned array consists of unique strings (no duplicates).
|
||||
*
|
||||
* Returns: (transfer full): all supported schemes by enhancers of type.
|
||||
*/
|
||||
gchar **
|
||||
clapper_enhancers_loader_get_schemes (GType iface_type)
|
||||
{
|
||||
GListModel *list = (GListModel *) _engine;
|
||||
GSList *found_schemes = NULL, *fs;
|
||||
const gchar *iface_name = ENHANCER_IFACE_NAME_FROM_TYPE (iface_type);
|
||||
gchar **schemes_strv;
|
||||
guint i, n_plugins, n_schemes;
|
||||
|
||||
GST_DEBUG ("Checking supported URI schemes for \"%s\"", iface_name);
|
||||
|
||||
n_plugins = g_list_model_get_n_items (list);
|
||||
|
||||
for (i = 0; i < n_plugins; ++i) {
|
||||
PeasPluginInfo *info = (PeasPluginInfo *) g_list_model_get_item (list, i);
|
||||
const gchar *iface_names, *schemes;
|
||||
gchar **tmp_strv;
|
||||
gint j;
|
||||
|
||||
if (!(iface_names = peas_plugin_info_get_external_data (info, ENHANCER_INTERFACES))) {
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
if (!_is_name_listed (iface_name, iface_names)) {
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
if (!(schemes = peas_plugin_info_get_external_data (info, ENHANCER_SCHEMES))) {
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp_strv = g_strsplit (schemes, ";", 0);
|
||||
|
||||
for (j = 0; tmp_strv[j]; ++j) {
|
||||
const gchar *scheme = tmp_strv[j];
|
||||
|
||||
if (!found_schemes || !g_slist_find_custom (found_schemes,
|
||||
scheme, (GCompareFunc) strcmp)) {
|
||||
found_schemes = g_slist_append (found_schemes, g_strdup (scheme));
|
||||
GST_INFO ("Found supported URI scheme: %s", scheme);
|
||||
}
|
||||
}
|
||||
|
||||
g_strfreev (tmp_strv);
|
||||
g_object_unref (info);
|
||||
}
|
||||
|
||||
n_schemes = g_slist_length (found_schemes);
|
||||
schemes_strv = g_new0 (gchar *, n_schemes + 1);
|
||||
|
||||
fs = found_schemes;
|
||||
for (i = 0; i < n_schemes; ++i) {
|
||||
schemes_strv[i] = fs->data;
|
||||
fs = fs->next;
|
||||
}
|
||||
|
||||
GST_DEBUG ("Total found URI schemes: %u", n_schemes);
|
||||
|
||||
/* Since string pointers were taken,
|
||||
* free list without content */
|
||||
g_slist_free (found_schemes);
|
||||
|
||||
return schemes_strv;
|
||||
}
|
||||
|
||||
/*
|
||||
* clapper_enhancers_loader_check:
|
||||
* @iface_type: a requested #GType
|
||||
* @scheme: an URI scheme
|
||||
* @host: (nullable): an URI host
|
||||
* @name: (out) (optional) (transfer none): return location for found enhancer name
|
||||
*
|
||||
* Checks if any enhancer can handle @uri without initializing loader
|
||||
* or creating enhancer instance, thus this can be used freely from any thread.
|
||||
*
|
||||
* Returns: whether enhancer for given scheme and host is available.
|
||||
*/
|
||||
gboolean
|
||||
clapper_enhancers_loader_check (GType iface_type,
|
||||
const gchar *scheme, const gchar *host, const gchar **name)
|
||||
{
|
||||
PeasPluginInfo *info;
|
||||
|
||||
if ((info = clapper_enhancers_loader_get_info (iface_type, scheme, host))) {
|
||||
if (name)
|
||||
*name = peas_plugin_info_get_name (info);
|
||||
|
||||
g_object_unref (info);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* clapper_enhancers_loader_create_enhancer_for_uri:
|
||||
* @iface_type: a requested #GType
|
||||
* @uri: a #GUri
|
||||
*
|
||||
* Creates a new enhancer object for given URI.
|
||||
*
|
||||
* Enhancer should only be created and used within single thread.
|
||||
*
|
||||
* Returns: (transfer full) (nullable): a new enhancer instance.
|
||||
*/
|
||||
GObject *
|
||||
clapper_enhancers_loader_create_enhancer_for_uri (GType iface_type, GUri *uri)
|
||||
{
|
||||
GObject *enhancer = NULL;
|
||||
PeasPluginInfo *info;
|
||||
const gchar *scheme = g_uri_get_scheme (uri);
|
||||
const gchar *host = g_uri_get_host (uri);
|
||||
|
||||
if ((info = clapper_enhancers_loader_get_info (iface_type, scheme, host))) {
|
||||
g_mutex_lock (&load_lock);
|
||||
|
||||
if (!peas_plugin_info_is_loaded (info) && !peas_engine_load_plugin (_engine, info)) {
|
||||
GST_ERROR ("Could not load enhancer: %s", peas_plugin_info_get_name (info));
|
||||
} else if (!peas_engine_provides_extension (_engine, info, iface_type)) {
|
||||
GST_ERROR ("No \"%s\" enhancer in plugin: %s", ENHANCER_IFACE_NAME_FROM_TYPE (iface_type),
|
||||
peas_plugin_info_get_name (info));
|
||||
} else {
|
||||
enhancer = peas_engine_create_extension (_engine, info, iface_type, NULL);
|
||||
}
|
||||
|
||||
g_mutex_unlock (&load_lock);
|
||||
g_object_unref (info);
|
||||
}
|
||||
|
||||
return enhancer;
|
||||
}
|
33
src/lib/clapper/clapper-extractable-private.h
Normal file
33
src/lib/clapper/clapper-extractable-private.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/* Clapper Playback Library
|
||||
* Copyright (C) 2024 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 Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser 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 <gio/gio.h>
|
||||
|
||||
#include "clapper-extractable.h"
|
||||
#include "clapper-harvest.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean clapper_extractable_extract (ClapperExtractable *extractable, GUri *uri, ClapperHarvest *harvest, GCancellable *cancellable, GError **error);
|
||||
|
||||
G_END_DECLS
|
61
src/lib/clapper/clapper-extractable.c
Normal file
61
src/lib/clapper/clapper-extractable.c
Normal file
@@ -0,0 +1,61 @@
|
||||
/* Clapper Playback Library
|
||||
* Copyright (C) 2024 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 Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClapperExtractable:
|
||||
*
|
||||
* An interface for creating enhancers that resolve given URI into something playable.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "clapper-extractable-private.h"
|
||||
#include "clapper-harvest-private.h"
|
||||
|
||||
G_DEFINE_INTERFACE (ClapperExtractable, clapper_extractable, G_TYPE_OBJECT);
|
||||
|
||||
static gboolean
|
||||
clapper_extractable_default_extract (ClapperExtractable *self, GUri *uri,
|
||||
ClapperHarvest *harvest, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
if (*error == NULL) {
|
||||
g_set_error (error, GST_CORE_ERROR,
|
||||
GST_CORE_ERROR_NOT_IMPLEMENTED,
|
||||
"Extractable object did not implement extract function");
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_extractable_default_init (ClapperExtractableInterface *iface)
|
||||
{
|
||||
iface->extract = clapper_extractable_default_extract;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clapper_extractable_extract (ClapperExtractable *self, GUri *uri,
|
||||
ClapperHarvest *harvest, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
ClapperExtractableInterface *iface = CLAPPER_EXTRACTABLE_GET_IFACE (self);
|
||||
|
||||
return iface->extract (self, uri, harvest, cancellable, error);
|
||||
}
|
69
src/lib/clapper/clapper-extractable.h
Normal file
69
src/lib/clapper/clapper-extractable.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* Clapper Playback Library
|
||||
* Copyright (C) 2024 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 Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser 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
|
||||
|
||||
#if !defined(__CLAPPER_INSIDE__) && !defined(CLAPPER_COMPILATION)
|
||||
#error "Only <clapper/clapper.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include <clapper/clapper-visibility.h>
|
||||
#include <clapper/clapper-harvest.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLAPPER_TYPE_EXTRACTABLE (clapper_extractable_get_type())
|
||||
#define CLAPPER_EXTRACTABLE_CAST(obj) ((ClapperExtractable *)(obj))
|
||||
|
||||
CLAPPER_API
|
||||
G_DECLARE_INTERFACE (ClapperExtractable, clapper_extractable, CLAPPER, EXTRACTABLE, GObject)
|
||||
|
||||
/**
|
||||
* ClapperExtractableInterface:
|
||||
* @parent_iface: The parent interface structure.
|
||||
* @extract: Extract data and fill harvest.
|
||||
*/
|
||||
struct _ClapperExtractableInterface
|
||||
{
|
||||
GTypeInterface parent_iface;
|
||||
|
||||
/**
|
||||
* ClapperExtractableInterface::extract:
|
||||
* @extractable: a #ClapperExtractable
|
||||
* @uri: a #GUri
|
||||
* @cancellable: a #GCancellable object
|
||||
* @error: a #GError
|
||||
*
|
||||
* Extract data and fill harvest.
|
||||
*
|
||||
* Returns: whether extraction was successful.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
gboolean (* extract) (ClapperExtractable *extractable, GUri *uri, ClapperHarvest *harvest, GCancellable *cancellable, GError **error);
|
||||
|
||||
/*< private >*/
|
||||
gpointer padding[8];
|
||||
};
|
||||
|
||||
G_END_DECLS
|
@@ -27,6 +27,8 @@
|
||||
#include <glib-object.h>
|
||||
#include <gio/gio.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <clapper/clapper-visibility.h>
|
||||
#include <clapper/clapper-media-item.h>
|
||||
#include <clapper/clapper-enums.h>
|
||||
|
||||
@@ -35,6 +37,7 @@ G_BEGIN_DECLS
|
||||
#define CLAPPER_TYPE_FEATURE (clapper_feature_get_type())
|
||||
#define CLAPPER_FEATURE_CAST(obj) ((ClapperFeature *)(obj))
|
||||
|
||||
CLAPPER_API
|
||||
G_DECLARE_DERIVABLE_TYPE (ClapperFeature, clapper_feature, CLAPPER, FEATURE, GstObject)
|
||||
|
||||
/**
|
||||
|
36
src/lib/clapper/clapper-functionalities-availability.h.in
Normal file
36
src/lib/clapper/clapper-functionalities-availability.h.in
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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 Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser 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
|
||||
|
||||
#if !defined(__CLAPPER_INSIDE__) && !defined(CLAPPER_COMPILATION)
|
||||
#error "Only <clapper/clapper.h> can be included directly."
|
||||
#endif
|
||||
|
||||
/**
|
||||
* CLAPPER_WITH_ENHANCERS_LOADER:
|
||||
*
|
||||
* Check if Clapper was compiled with Enhancers Loader functionality.
|
||||
*
|
||||
* Alternatively, apps before compiling can also check whether `pkgconfig`
|
||||
* variable named `functionalities` contains `enhancers-loader` string.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
#define CLAPPER_WITH_ENHANCERS_LOADER (@CLAPPER_WITH_ENHANCERS_LOADER@)
|
35
src/lib/clapper/clapper-harvest-private.h
Normal file
35
src/lib/clapper/clapper-harvest-private.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/* Clapper Playback Library
|
||||
* Copyright (C) 2024 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 Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser 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 <gst/tag/tag.h>
|
||||
|
||||
#include "clapper-harvest.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
ClapperHarvest * clapper_harvest_new (void);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean clapper_harvest_unpack (ClapperHarvest *harvest, GstBuffer **buffer, gsize *buf_size, GstCaps **caps, GstTagList **tags, GstToc **toc, GstStructure **headers);
|
||||
|
||||
G_END_DECLS
|
450
src/lib/clapper/clapper-harvest.c
Normal file
450
src/lib/clapper/clapper-harvest.c
Normal file
@@ -0,0 +1,450 @@
|
||||
/* Clapper Playback Library
|
||||
* Copyright (C) 2024 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 Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClapperHarvest:
|
||||
*
|
||||
* An object storing data from enhancers that implement [iface@Clapper.Extractable] interface.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE: We cannot simply expose GstMiniObjects for
|
||||
* implementations to assemble TagList/Toc themselves, see:
|
||||
* https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/2867
|
||||
*/
|
||||
|
||||
#include "clapper-harvest-private.h"
|
||||
|
||||
#define GST_CAT_DEFAULT clapper_harvest_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
struct _ClapperHarvest
|
||||
{
|
||||
GstObject parent;
|
||||
|
||||
GstCaps *caps;
|
||||
GstBuffer *buffer;
|
||||
gsize buf_size;
|
||||
|
||||
GstTagList *tags;
|
||||
GstToc *toc;
|
||||
GstStructure *headers;
|
||||
|
||||
guint16 n_chapters;
|
||||
guint16 n_tracks;
|
||||
};
|
||||
|
||||
#define parent_class clapper_harvest_parent_class
|
||||
G_DEFINE_TYPE (ClapperHarvest, clapper_harvest, GST_TYPE_OBJECT);
|
||||
|
||||
static inline void
|
||||
_ensure_tags (ClapperHarvest *self)
|
||||
{
|
||||
if (!self->tags) {
|
||||
self->tags = gst_tag_list_new_empty ();
|
||||
gst_tag_list_set_scope (self->tags, GST_TAG_SCOPE_GLOBAL);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_ensure_toc (ClapperHarvest *self)
|
||||
{
|
||||
if (!self->toc)
|
||||
self->toc = gst_toc_new (GST_TOC_SCOPE_GLOBAL);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_ensure_headers (ClapperHarvest *self)
|
||||
{
|
||||
if (!self->headers)
|
||||
self->headers = gst_structure_new_empty ("request-headers");
|
||||
}
|
||||
|
||||
ClapperHarvest *
|
||||
clapper_harvest_new (void)
|
||||
{
|
||||
ClapperHarvest *harvest;
|
||||
|
||||
harvest = g_object_new (CLAPPER_TYPE_HARVEST, NULL);
|
||||
gst_object_ref_sink (harvest);
|
||||
|
||||
return harvest;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clapper_harvest_unpack (ClapperHarvest *self,
|
||||
GstBuffer **buffer, gsize *buf_size, GstCaps **caps,
|
||||
GstTagList **tags, GstToc **toc, GstStructure **headers)
|
||||
{
|
||||
/* Not filled or already unpacked */
|
||||
if (!self->buffer)
|
||||
return FALSE;
|
||||
|
||||
*buffer = self->buffer;
|
||||
self->buffer = NULL;
|
||||
|
||||
*buf_size = self->buf_size;
|
||||
self->buf_size = 0;
|
||||
|
||||
*caps = self->caps;
|
||||
self->caps = NULL;
|
||||
|
||||
*tags = self->tags;
|
||||
self->tags = NULL;
|
||||
|
||||
*toc = self->toc;
|
||||
self->toc = NULL;
|
||||
|
||||
*headers = self->headers;
|
||||
self->headers = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_harvest_fill:
|
||||
* @harvest: a #ClapperHarvest
|
||||
* @media_type: media mime type
|
||||
* @data: (array length=size) (element-type guint8) (transfer full): data to fill @harvest
|
||||
* @size: allocated size of @data
|
||||
*
|
||||
* Fill harvest with extracted data. It can be anything that GStreamer
|
||||
* can parse and play such as single URI or a streaming manifest.
|
||||
*
|
||||
* Calling again this function will replace previously filled content.
|
||||
*
|
||||
* Commonly used media types are:
|
||||
*
|
||||
* * `application/dash+xml`
|
||||
*
|
||||
* * `application/x-hls`
|
||||
*
|
||||
* * `text/uri-list`
|
||||
*
|
||||
* Returns: %TRUE when filled successfully, %FALSE if taken data was empty.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
gboolean
|
||||
clapper_harvest_fill (ClapperHarvest *self, const gchar *media_type, gpointer data, gsize size)
|
||||
{
|
||||
g_return_val_if_fail (CLAPPER_IS_HARVEST (self), FALSE);
|
||||
g_return_val_if_fail (media_type != NULL, FALSE);
|
||||
g_return_val_if_fail (data != NULL, FALSE);
|
||||
|
||||
if (!data || size == 0) {
|
||||
g_free (data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (gst_debug_category_get_threshold (GST_CAT_DEFAULT) >= GST_LEVEL_DEBUG) {
|
||||
gboolean is_printable = (strcmp (media_type, "application/dash+xml") == 0)
|
||||
|| (strcmp (media_type, "application/x-hls") == 0)
|
||||
|| (strcmp (media_type, "text/uri-list") == 0);
|
||||
|
||||
if (is_printable) {
|
||||
gchar *data_str;
|
||||
|
||||
data_str = g_new0 (gchar, size + 1);
|
||||
memcpy (data_str, data, size);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Filled with data:\n%s", data_str);
|
||||
|
||||
g_free (data_str);
|
||||
}
|
||||
}
|
||||
|
||||
gst_clear_buffer (&self->buffer);
|
||||
gst_clear_caps (&self->caps);
|
||||
|
||||
self->buffer = gst_buffer_new_wrapped (data, size);
|
||||
self->buf_size = size;
|
||||
self->caps = gst_caps_new_simple (media_type,
|
||||
"source", G_TYPE_STRING, "clapper-harvest", NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_harvest_fill_with_text:
|
||||
* @harvest: a #ClapperHarvest
|
||||
* @media_type: media mime type
|
||||
* @text: (transfer full): data to fill @harvest as %NULL terminated string
|
||||
*
|
||||
* A convenience method to fill @harvest using a %NULL terminated string.
|
||||
*
|
||||
* For more info, see [method@Clapper.Harvest.fill] documentation.
|
||||
*
|
||||
* Returns: %TRUE when filled successfully, %FALSE if taken data was empty.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
gboolean
|
||||
clapper_harvest_fill_with_text (ClapperHarvest *self, const gchar *media_type, gchar *text)
|
||||
{
|
||||
g_return_val_if_fail (text != NULL, FALSE);
|
||||
|
||||
return clapper_harvest_fill (self, media_type, text, strlen (text));
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_harvest_fill_with_bytes:
|
||||
* @harvest: a #ClapperHarvest
|
||||
* @media_type: media mime type
|
||||
* @bytes: (transfer full): a #GBytes to fill @harvest
|
||||
*
|
||||
* A convenience method to fill @harvest with data from #GBytes.
|
||||
*
|
||||
* For more info, see [method@Clapper.Harvest.fill] documentation.
|
||||
*
|
||||
* Returns: %TRUE when filled successfully, %FALSE if taken data was empty.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
gboolean
|
||||
clapper_harvest_fill_with_bytes (ClapperHarvest *self, const gchar *media_type, GBytes *bytes)
|
||||
{
|
||||
gpointer data;
|
||||
gsize size = 0;
|
||||
|
||||
g_return_val_if_fail (bytes != NULL, FALSE);
|
||||
|
||||
data = g_bytes_unref_to_data (bytes, &size);
|
||||
|
||||
return clapper_harvest_fill (self, media_type, data, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_harvest_tags_add:
|
||||
* @harvest: a #ClapperHarvest
|
||||
* @tag: a name of tag to set
|
||||
* @...: %NULL-terminated list of arguments
|
||||
*
|
||||
* Append one or more tags into the tag list.
|
||||
*
|
||||
* Variable arguments should be in the form of tag and value pairs.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
clapper_harvest_tags_add (ClapperHarvest *self, const gchar *tag, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
g_return_if_fail (CLAPPER_IS_HARVEST (self));
|
||||
g_return_if_fail (tag != NULL);
|
||||
|
||||
_ensure_tags (self);
|
||||
|
||||
va_start (args, tag);
|
||||
gst_tag_list_add_valist (self->tags, GST_TAG_MERGE_APPEND, tag, args);
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_harvest_tags_add_value: (rename-to clapper_harvest_tags_add)
|
||||
* @harvest: a #ClapperHarvest
|
||||
* @tag: a name of tag to set
|
||||
* @value: a #GValue of tag
|
||||
*
|
||||
* Append another tag into the tag list using #GValue.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
clapper_harvest_tags_add_value (ClapperHarvest *self, const gchar *tag, const GValue *value)
|
||||
{
|
||||
g_return_if_fail (CLAPPER_IS_HARVEST (self));
|
||||
g_return_if_fail (tag != NULL);
|
||||
g_return_if_fail (G_IS_VALUE (value));
|
||||
|
||||
_ensure_tags (self);
|
||||
gst_tag_list_add_value (self->tags, GST_TAG_MERGE_APPEND, tag, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_harvest_toc_add:
|
||||
* @harvest: a #ClapperHarvest
|
||||
* @type: a #GstTocEntryType
|
||||
* @title: an entry title
|
||||
* @start: entry start time in seconds
|
||||
* @end: entry end time in seconds or -1 if none
|
||||
*
|
||||
* Append a chapter or track name into table of contents.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
clapper_harvest_toc_add (ClapperHarvest *self, GstTocEntryType type,
|
||||
const gchar *title, gdouble start, gdouble end)
|
||||
{
|
||||
GstTocEntry *entry, *subentry;
|
||||
GstClockTime start_time, end_time;
|
||||
gchar edition[3]; // 2 + 1
|
||||
gchar id[14]; // 7 + 1 + 5 + 1
|
||||
const gchar *id_prefix;
|
||||
guint16 nth_entry;
|
||||
|
||||
g_return_if_fail (CLAPPER_IS_HARVEST (self));
|
||||
g_return_if_fail (type == GST_TOC_ENTRY_TYPE_CHAPTER || type == GST_TOC_ENTRY_TYPE_TRACK);
|
||||
g_return_if_fail (title != NULL);
|
||||
g_return_if_fail (start >= 0 && end >= start);
|
||||
|
||||
switch (type) {
|
||||
case GST_TOC_ENTRY_TYPE_CHAPTER:
|
||||
id_prefix = "chapter";
|
||||
nth_entry = ++(self->n_chapters);
|
||||
break;
|
||||
case GST_TOC_ENTRY_TYPE_TRACK:
|
||||
id_prefix = "track";
|
||||
nth_entry = ++(self->n_tracks);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return;
|
||||
}
|
||||
|
||||
start_time = start * GST_SECOND;
|
||||
end_time = (end >= 0) ? end * GST_SECOND : GST_CLOCK_TIME_NONE;
|
||||
|
||||
g_snprintf (edition, sizeof (edition), "0%i", type);
|
||||
g_snprintf (id, sizeof (id), "%s.%" G_GUINT16_FORMAT, id_prefix, nth_entry);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Inserting TOC %s: \"%s\""
|
||||
" (%" G_GUINT64_FORMAT "-%" G_GUINT64_FORMAT ")",
|
||||
id, title, start_time, end_time);
|
||||
|
||||
subentry = gst_toc_entry_new (type, id);
|
||||
gst_toc_entry_set_tags (subentry, gst_tag_list_new (GST_TAG_TITLE, title, NULL));
|
||||
gst_toc_entry_set_start_stop_times (subentry, start_time, end_time);
|
||||
|
||||
_ensure_toc (self);
|
||||
|
||||
find_entry:
|
||||
if (!(entry = gst_toc_find_entry (self->toc, edition))) {
|
||||
GstTocEntry *toc_entry;
|
||||
|
||||
toc_entry = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, edition);
|
||||
gst_toc_entry_set_start_stop_times (toc_entry, 0, GST_CLOCK_TIME_NONE);
|
||||
gst_toc_append_entry (self->toc, toc_entry); // transfer full and must be writable
|
||||
|
||||
goto find_entry;
|
||||
}
|
||||
|
||||
gst_toc_entry_append_sub_entry (entry, subentry);
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_harvest_headers_set:
|
||||
* @harvest: a #ClapperHarvest
|
||||
* @key: a header name
|
||||
* @...: %NULL-terminated list of arguments
|
||||
*
|
||||
* Set one or more request headers named with @key to specified `value`.
|
||||
*
|
||||
* Arguments should be %NULL terminated list of `key+value` string pairs.
|
||||
*
|
||||
* Setting again the same key will update its value to the new one.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
clapper_harvest_headers_set (ClapperHarvest *self, const gchar *key, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
g_return_if_fail (CLAPPER_IS_HARVEST (self));
|
||||
g_return_if_fail (key != NULL);
|
||||
|
||||
_ensure_headers (self);
|
||||
|
||||
va_start (args, key);
|
||||
|
||||
while (key != NULL) {
|
||||
const gchar *val = va_arg (args, const gchar *);
|
||||
GST_DEBUG_OBJECT (self, "Set header, \"%s\": \"%s\"", key, val);
|
||||
gst_structure_set (self->headers, key, G_TYPE_STRING, val, NULL);
|
||||
key = va_arg (args, const gchar *);
|
||||
}
|
||||
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_harvest_headers_set_value: (rename-to clapper_harvest_headers_set)
|
||||
* @harvest: a #ClapperHarvest
|
||||
* @key: a header name
|
||||
* @value: a string #GValue of header
|
||||
*
|
||||
* Set another header in the request headers list using #GValue.
|
||||
*
|
||||
* Setting again the same key will update its value to the new one.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
clapper_harvest_headers_set_value (ClapperHarvest *self, const gchar *key, const GValue *value)
|
||||
{
|
||||
g_return_if_fail (CLAPPER_IS_HARVEST (self));
|
||||
g_return_if_fail (key != NULL);
|
||||
g_return_if_fail (G_IS_VALUE (value) && G_VALUE_HOLDS_STRING (value));
|
||||
|
||||
_ensure_headers (self);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Set header, \"%s\": \"%s\"", key, g_value_get_string (value));
|
||||
gst_structure_set_value (self->headers, key, value);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_harvest_init (ClapperHarvest *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_harvest_finalize (GObject *object)
|
||||
{
|
||||
ClapperHarvest *self = CLAPPER_HARVEST_CAST (object);
|
||||
|
||||
GST_TRACE_OBJECT (self, "Finalize");
|
||||
|
||||
gst_clear_caps (&self->caps);
|
||||
gst_clear_buffer (&self->buffer);
|
||||
|
||||
if (self->tags)
|
||||
gst_tag_list_unref (self->tags);
|
||||
if (self->toc)
|
||||
gst_toc_unref (self->toc);
|
||||
if (self->headers)
|
||||
gst_structure_free (self->headers);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_harvest_class_init (ClapperHarvestClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperharvest", 0,
|
||||
"Clapper Harvest");
|
||||
|
||||
gobject_class->finalize = clapper_harvest_finalize;
|
||||
}
|
64
src/lib/clapper/clapper-harvest.h
Normal file
64
src/lib/clapper/clapper-harvest.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/* Clapper Playback Library
|
||||
* Copyright (C) 2024 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 Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser 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
|
||||
|
||||
#if !defined(__CLAPPER_INSIDE__) && !defined(CLAPPER_COMPILATION)
|
||||
#error "Only <clapper/clapper.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gst/gst.h>
|
||||
#include <gst/tag/tag.h>
|
||||
|
||||
#include <clapper/clapper-visibility.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLAPPER_TYPE_HARVEST (clapper_harvest_get_type())
|
||||
#define CLAPPER_HARVEST_CAST(obj) ((ClapperHarvest *)(obj))
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ClapperHarvest, clapper_harvest, CLAPPER, HARVEST, GstObject)
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_harvest_fill (ClapperHarvest *harvest, const gchar *media_type, gpointer data, gsize size);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_harvest_fill_with_text (ClapperHarvest *harvest, const gchar *media_type, gchar *text);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_harvest_fill_with_bytes (ClapperHarvest *harvest, const gchar *media_type, GBytes *bytes);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_harvest_tags_add (ClapperHarvest *harvest, const gchar *tag, ...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_harvest_tags_add_value (ClapperHarvest *harvest, const gchar *tag, const GValue *value);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_harvest_toc_add (ClapperHarvest *harvest, GstTocEntryType type, const gchar *title, gdouble start, gdouble end);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_harvest_headers_set (ClapperHarvest *harvest, const gchar *key, ...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_harvest_headers_set_value (ClapperHarvest *harvest, const gchar *key, const GValue *value);
|
||||
|
||||
G_END_DECLS
|
@@ -26,6 +26,8 @@
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <clapper/clapper-visibility.h>
|
||||
#include <clapper/clapper-enums.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -36,6 +38,7 @@ G_BEGIN_DECLS
|
||||
/* NOTE: #ClapperMarker are immutable objects that cannot be derived,
|
||||
* otherwise #ClapperFeaturesManager would not be able to announce media
|
||||
* item changed caused by changes within them */
|
||||
CLAPPER_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperMarker, clapper_marker, CLAPPER, MARKER, GstObject)
|
||||
|
||||
/**
|
||||
@@ -45,14 +48,19 @@ G_DECLARE_FINAL_TYPE (ClapperMarker, clapper_marker, CLAPPER, MARKER, GstObject)
|
||||
*/
|
||||
#define CLAPPER_MARKER_NO_END ((gdouble) -1) // Needs a cast from int, otherwise GIR is generated incorrectly
|
||||
|
||||
CLAPPER_API
|
||||
ClapperMarker * clapper_marker_new (ClapperMarkerType marker_type, const gchar *title, gdouble start, gdouble end);
|
||||
|
||||
CLAPPER_API
|
||||
ClapperMarkerType clapper_marker_get_marker_type (ClapperMarker *marker);
|
||||
|
||||
CLAPPER_API
|
||||
const gchar * clapper_marker_get_title (ClapperMarker *marker);
|
||||
|
||||
CLAPPER_API
|
||||
gdouble clapper_marker_get_start (ClapperMarker *marker);
|
||||
|
||||
CLAPPER_API
|
||||
gdouble clapper_marker_get_end (ClapperMarker *marker);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -37,6 +37,12 @@ void clapper_media_item_update_from_discoverer_info (ClapperMediaItem *self, Gst
|
||||
G_GNUC_INTERNAL
|
||||
gboolean clapper_media_item_set_duration (ClapperMediaItem *item, gdouble duration, ClapperAppBus *app_bus);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_media_item_set_cache_location (ClapperMediaItem *item, const gchar *location);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
const gchar * clapper_media_item_get_playback_uri (ClapperMediaItem *item);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_media_item_set_used (ClapperMediaItem *item, gboolean used);
|
||||
|
||||
|
@@ -50,6 +50,8 @@ struct _ClapperMediaItem
|
||||
gchar *container_format;
|
||||
gdouble duration;
|
||||
|
||||
gchar *cache_uri;
|
||||
|
||||
/* For shuffle */
|
||||
gboolean used;
|
||||
};
|
||||
@@ -60,6 +62,7 @@ enum
|
||||
PROP_ID,
|
||||
PROP_URI,
|
||||
PROP_SUBURI,
|
||||
PROP_CACHE_LOCATION,
|
||||
PROP_TITLE,
|
||||
PROP_CONTAINER_FORMAT,
|
||||
PROP_DURATION,
|
||||
@@ -141,6 +144,35 @@ clapper_media_item_new_from_file (GFile *file)
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_media_item_new_cached:
|
||||
* @uri: a media URI
|
||||
* @location: (type filename) (nullable): a path to downloaded file
|
||||
*
|
||||
* Same as [ctor@Clapper.MediaItem.new], but allows to provide
|
||||
* a location of a cache file where particular media at @uri
|
||||
* is supposed to be found.
|
||||
*
|
||||
* File at @location existence will be checked upon starting playback
|
||||
* of created item. If cache file is not found, media item @uri will be
|
||||
* used as fallback. In this case when [property@Clapper.Player:download-enabled]
|
||||
* is set to %TRUE, item will be downloaded and cached again if possible.
|
||||
*
|
||||
* Returns: (transfer full): a new #ClapperMediaItem.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
ClapperMediaItem *
|
||||
clapper_media_item_new_cached (const gchar *uri, const gchar *location)
|
||||
{
|
||||
ClapperMediaItem *item = clapper_media_item_new (uri);
|
||||
|
||||
if (location && G_LIKELY (item != NULL))
|
||||
clapper_media_item_set_cache_location (item, location);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_media_item_get_id:
|
||||
* @item: a #ClapperMediaItem
|
||||
@@ -450,6 +482,43 @@ clapper_media_item_update_from_discoverer_info (ClapperMediaItem *self, GstDisco
|
||||
gst_object_unref (player);
|
||||
}
|
||||
|
||||
/* XXX: Must be set from player thread or upon construction */
|
||||
void
|
||||
clapper_media_item_set_cache_location (ClapperMediaItem *self, const gchar *location)
|
||||
{
|
||||
g_clear_pointer (&self->cache_uri, g_free);
|
||||
|
||||
if (location)
|
||||
self->cache_uri = g_filename_to_uri (location, NULL, NULL);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Set cache URI: \"%s\"",
|
||||
GST_STR_NULL (self->cache_uri));
|
||||
}
|
||||
|
||||
/* XXX: Can only be read from player thread.
|
||||
* Returns cache URI if available, item URI otherwise. */
|
||||
inline const gchar *
|
||||
clapper_media_item_get_playback_uri (ClapperMediaItem *self)
|
||||
{
|
||||
if (self->cache_uri) {
|
||||
GFile *file = g_file_new_for_uri (self->cache_uri);
|
||||
gboolean exists;
|
||||
|
||||
/* It is an app error if it removes files in non-stopped state,
|
||||
* and this function is only called when starting playback */
|
||||
exists = g_file_query_exists (file, NULL);
|
||||
g_object_unref (file);
|
||||
|
||||
if (exists)
|
||||
return self->cache_uri;
|
||||
|
||||
/* Do not test file existence next time */
|
||||
clapper_media_item_set_cache_location (self, NULL);
|
||||
}
|
||||
|
||||
return self->uri;
|
||||
}
|
||||
|
||||
void
|
||||
clapper_media_item_set_used (ClapperMediaItem *self, gboolean used)
|
||||
{
|
||||
@@ -505,6 +574,8 @@ clapper_media_item_finalize (GObject *object)
|
||||
gst_object_unparent (GST_OBJECT_CAST (self->timeline));
|
||||
gst_object_unref (self->timeline);
|
||||
|
||||
g_free (self->cache_uri);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@@ -521,6 +592,9 @@ clapper_media_item_set_property (GObject *object, guint prop_id,
|
||||
case PROP_SUBURI:
|
||||
clapper_media_item_set_suburi (self, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_CACHE_LOCATION:
|
||||
clapper_media_item_set_cache_location (self, g_value_get_string (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -601,6 +675,17 @@ clapper_media_item_class_init (ClapperMediaItemClass *klass)
|
||||
NULL, NULL, NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClapperMediaItem:cache-location:
|
||||
*
|
||||
* Media downloaded cache file location.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
param_specs[PROP_CACHE_LOCATION] = g_param_spec_string ("cache-location",
|
||||
NULL, NULL, NULL,
|
||||
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClapperMediaItem:title:
|
||||
*
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include <gio/gio.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <clapper/clapper-visibility.h>
|
||||
#include <clapper/clapper-timeline.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -35,26 +36,40 @@ G_BEGIN_DECLS
|
||||
#define CLAPPER_TYPE_MEDIA_ITEM (clapper_media_item_get_type())
|
||||
#define CLAPPER_MEDIA_ITEM_CAST(obj) ((ClapperMediaItem *)(obj))
|
||||
|
||||
CLAPPER_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperMediaItem, clapper_media_item, CLAPPER, MEDIA_ITEM, GstObject)
|
||||
|
||||
CLAPPER_API
|
||||
ClapperMediaItem * clapper_media_item_new (const gchar *uri);
|
||||
|
||||
CLAPPER_API
|
||||
ClapperMediaItem * clapper_media_item_new_from_file (GFile *file);
|
||||
|
||||
CLAPPER_API
|
||||
ClapperMediaItem * clapper_media_item_new_cached (const gchar *uri, const gchar *location);
|
||||
|
||||
CLAPPER_API
|
||||
guint clapper_media_item_get_id (ClapperMediaItem *item);
|
||||
|
||||
CLAPPER_API
|
||||
const gchar * clapper_media_item_get_uri (ClapperMediaItem *item);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_media_item_set_suburi (ClapperMediaItem *item, const gchar *suburi);
|
||||
|
||||
CLAPPER_API
|
||||
gchar * clapper_media_item_get_suburi (ClapperMediaItem *item);
|
||||
|
||||
CLAPPER_API
|
||||
gchar * clapper_media_item_get_title (ClapperMediaItem *item);
|
||||
|
||||
CLAPPER_API
|
||||
gchar * clapper_media_item_get_container_format (ClapperMediaItem *item);
|
||||
|
||||
CLAPPER_API
|
||||
gdouble clapper_media_item_get_duration (ClapperMediaItem *item);
|
||||
|
||||
CLAPPER_API
|
||||
ClapperTimeline * clapper_media_item_get_timeline (ClapperMediaItem *item);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -30,6 +30,12 @@
|
||||
#include "clapper-stream-private.h"
|
||||
#include "clapper-stream-list-private.h"
|
||||
|
||||
#include "clapper-functionalities-availability.h"
|
||||
|
||||
#if CLAPPER_WITH_ENHANCERS_LOADER
|
||||
#include "gst/clapper-enhancer-src-private.h"
|
||||
#endif
|
||||
|
||||
#define GST_CAT_DEFAULT clapper_playbin_bus_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
@@ -827,6 +833,40 @@ _handle_element_msg (GstMessage *msg, ClapperPlayer *player)
|
||||
|
||||
g_free (name);
|
||||
g_free (details);
|
||||
} else if (gst_message_has_name (msg, "GstCacheDownloadComplete")) {
|
||||
ClapperMediaItem *downloaded_item = NULL;
|
||||
const GstStructure *structure;
|
||||
const gchar *location;
|
||||
guint signal_id;
|
||||
|
||||
GST_OBJECT_LOCK (player);
|
||||
|
||||
/* Short video might be fully downloaded before playback starts */
|
||||
if (player->pending_item)
|
||||
downloaded_item = gst_object_ref (player->pending_item);
|
||||
else if (player->played_item)
|
||||
downloaded_item = gst_object_ref (player->played_item);
|
||||
|
||||
GST_OBJECT_UNLOCK (player);
|
||||
|
||||
if (G_UNLIKELY (downloaded_item == NULL)) {
|
||||
GST_WARNING_OBJECT (player, "Download completed without media item set");
|
||||
return;
|
||||
}
|
||||
|
||||
structure = gst_message_get_structure (msg);
|
||||
location = gst_structure_get_string (structure, "location");
|
||||
signal_id = g_signal_lookup ("download-complete", CLAPPER_TYPE_PLAYER);
|
||||
|
||||
GST_INFO_OBJECT (player, "Download of %" GST_PTR_FORMAT
|
||||
" complete: %s", downloaded_item, location);
|
||||
clapper_media_item_set_cache_location (downloaded_item, location);
|
||||
|
||||
clapper_app_bus_post_object_desc_signal (player->app_bus,
|
||||
GST_OBJECT_CAST (player), signal_id,
|
||||
GST_OBJECT_CAST (downloaded_item), location);
|
||||
|
||||
gst_object_unref (downloaded_item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -835,6 +875,7 @@ _handle_tag_msg (GstMessage *msg, ClapperPlayer *player)
|
||||
{
|
||||
GstObject *src = GST_MESSAGE_SRC (msg);
|
||||
GstTagList *tags = NULL;
|
||||
gboolean from_enhancer_src;
|
||||
|
||||
/* Tag messages should only be posted by sink elements */
|
||||
if (G_UNLIKELY (!src))
|
||||
@@ -845,8 +886,21 @@ _handle_tag_msg (GstMessage *msg, ClapperPlayer *player)
|
||||
GST_LOG_OBJECT (player, "Got tags from element: %s: %" GST_PTR_FORMAT,
|
||||
GST_OBJECT_NAME (src), tags);
|
||||
|
||||
if (G_LIKELY (player->played_item != NULL))
|
||||
#if CLAPPER_WITH_ENHANCERS_LOADER
|
||||
from_enhancer_src = CLAPPER_IS_ENHANCER_SRC (src);
|
||||
#else
|
||||
from_enhancer_src = FALSE;
|
||||
#endif
|
||||
|
||||
/* ClapperEnhancerSrc determines tags before stream start */
|
||||
if (from_enhancer_src) {
|
||||
if (player->pending_tags) {
|
||||
gst_tag_list_unref (player->pending_tags);
|
||||
}
|
||||
player->pending_tags = gst_tag_list_ref (tags);
|
||||
} else if (G_LIKELY (player->played_item != NULL)) {
|
||||
clapper_media_item_update_from_tag_list (player->played_item, tags, player);
|
||||
}
|
||||
|
||||
gst_tag_list_unref (tags);
|
||||
}
|
||||
@@ -856,11 +910,10 @@ _handle_toc_msg (GstMessage *msg, ClapperPlayer *player)
|
||||
{
|
||||
GstObject *src = GST_MESSAGE_SRC (msg);
|
||||
GstToc *toc = NULL;
|
||||
ClapperTimeline *timeline;
|
||||
gboolean updated = FALSE;
|
||||
gboolean from_enhancer_src, updated = FALSE;
|
||||
|
||||
/* TOC messages should only be posted by sink elements after start */
|
||||
if (G_UNLIKELY (!src || !player->played_item))
|
||||
/* TOC messages should only be posted by sink elements */
|
||||
if (G_UNLIKELY (!src))
|
||||
return;
|
||||
|
||||
/* Either new TOC was found or previous one was updated */
|
||||
@@ -870,11 +923,27 @@ _handle_toc_msg (GstMessage *msg, ClapperPlayer *player)
|
||||
" from element: %s, updated: %s",
|
||||
toc, GST_OBJECT_NAME (src), (updated) ? "yes" : "no");
|
||||
|
||||
timeline = clapper_media_item_get_timeline (player->played_item);
|
||||
#if CLAPPER_WITH_ENHANCERS_LOADER
|
||||
from_enhancer_src = CLAPPER_IS_ENHANCER_SRC (src);
|
||||
#else
|
||||
from_enhancer_src = FALSE;
|
||||
#endif
|
||||
|
||||
if (clapper_timeline_set_toc (timeline, toc, updated)) {
|
||||
clapper_app_bus_post_refresh_timeline (player->app_bus,
|
||||
GST_OBJECT_CAST (player->played_item));
|
||||
/* ClapperEnhancerSrc determines TOC before stream start */
|
||||
if (from_enhancer_src) {
|
||||
if (player->pending_toc) {
|
||||
gst_toc_unref (player->pending_toc);
|
||||
}
|
||||
player->pending_toc = gst_toc_ref (toc);
|
||||
} else if (G_LIKELY (player->played_item != NULL)) {
|
||||
ClapperTimeline *timeline;
|
||||
|
||||
timeline = clapper_media_item_get_timeline (player->played_item);
|
||||
|
||||
if (clapper_timeline_set_toc (timeline, toc, updated)) {
|
||||
clapper_app_bus_post_refresh_timeline (player->app_bus,
|
||||
GST_OBJECT_CAST (player->played_item));
|
||||
}
|
||||
}
|
||||
|
||||
gst_toc_unref (toc);
|
||||
@@ -1001,6 +1070,26 @@ _handle_stream_start_msg (GstMessage *msg, ClapperPlayer *player)
|
||||
/* With playbin2 we update all decoders at once after stream start */
|
||||
if (!player->use_playbin3)
|
||||
clapper_player_playbin_update_current_decoders (player);
|
||||
|
||||
if (player->pending_tags) {
|
||||
if (G_LIKELY (player->played_item != NULL))
|
||||
clapper_media_item_update_from_tag_list (player->played_item, player->pending_tags, player);
|
||||
|
||||
gst_clear_tag_list (&player->pending_tags);
|
||||
}
|
||||
if (player->pending_toc) {
|
||||
if (G_LIKELY (player->played_item != NULL)) {
|
||||
ClapperTimeline *timeline = clapper_media_item_get_timeline (player->played_item);
|
||||
|
||||
if (clapper_timeline_set_toc (timeline, player->pending_toc, FALSE)) {
|
||||
clapper_app_bus_post_refresh_timeline (player->app_bus,
|
||||
GST_OBJECT_CAST (player->played_item));
|
||||
}
|
||||
}
|
||||
|
||||
gst_toc_unref (player->pending_toc);
|
||||
player->pending_toc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@@ -19,6 +19,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gst/tag/tag.h>
|
||||
|
||||
#include "clapper-player.h"
|
||||
#include "clapper-queue.h"
|
||||
#include "clapper-enums.h"
|
||||
@@ -53,6 +55,11 @@ struct _ClapperPlayer
|
||||
* different thread, thus needs a lock */
|
||||
ClapperMediaItem *pending_item;
|
||||
|
||||
/* Pending tags/toc that arrive before stream start.
|
||||
* To be applied to "played_item", thus no lock needed. */
|
||||
GstTagList *pending_tags;
|
||||
GstToc *pending_toc;
|
||||
|
||||
GstElement *playbin;
|
||||
|
||||
GstBus *bus;
|
||||
@@ -80,6 +87,9 @@ struct _ClapperPlayer
|
||||
gboolean pending_eos; // when pausing due to EOS
|
||||
gint eos; // atomic integer
|
||||
|
||||
/* Set adaptive props immediately */
|
||||
GstElement *adaptive_demuxer;
|
||||
|
||||
/* Playbin2 compat */
|
||||
gint n_video, n_audio, n_text;
|
||||
|
||||
@@ -95,6 +105,12 @@ struct _ClapperPlayer
|
||||
gboolean video_enabled;
|
||||
gboolean audio_enabled;
|
||||
gboolean subtitles_enabled;
|
||||
gchar *download_dir;
|
||||
gboolean download_enabled;
|
||||
guint start_bitrate;
|
||||
guint min_bitrate;
|
||||
guint max_bitrate;
|
||||
guint bandwidth;
|
||||
gdouble audio_offset;
|
||||
gdouble subtitle_offset;
|
||||
};
|
||||
|
@@ -43,7 +43,7 @@
|
||||
#include "clapper-playbin-bus-private.h"
|
||||
#include "clapper-app-bus-private.h"
|
||||
#include "clapper-queue-private.h"
|
||||
#include "clapper-media-item.h"
|
||||
#include "clapper-media-item-private.h"
|
||||
#include "clapper-stream-list-private.h"
|
||||
#include "clapper-stream-private.h"
|
||||
#include "clapper-video-stream-private.h"
|
||||
@@ -61,6 +61,8 @@
|
||||
#define DEFAULT_VIDEO_ENABLED TRUE
|
||||
#define DEFAULT_AUDIO_ENABLED TRUE
|
||||
#define DEFAULT_SUBTITLES_ENABLED TRUE
|
||||
#define DEFAULT_DOWNLOAD_ENABLED FALSE
|
||||
#define DEFAULT_ADAPTIVE_START_BITRATE 1600000
|
||||
|
||||
#define GST_CAT_DEFAULT clapper_player_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
@@ -90,6 +92,12 @@ enum
|
||||
PROP_VIDEO_ENABLED,
|
||||
PROP_AUDIO_ENABLED,
|
||||
PROP_SUBTITLES_ENABLED,
|
||||
PROP_DOWNLOAD_DIR,
|
||||
PROP_DOWNLOAD_ENABLED,
|
||||
PROP_ADAPTIVE_START_BITRATE,
|
||||
PROP_ADAPTIVE_MIN_BITRATE,
|
||||
PROP_ADAPTIVE_MAX_BITRATE,
|
||||
PROP_ADAPTIVE_BANDWIDTH,
|
||||
PROP_AUDIO_OFFSET,
|
||||
PROP_SUBTITLE_OFFSET,
|
||||
PROP_SUBTITLE_FONT_DESC,
|
||||
@@ -99,6 +107,7 @@ enum
|
||||
enum
|
||||
{
|
||||
SIGNAL_SEEK_DONE,
|
||||
SIGNAL_DOWNLOAD_COMPLETE,
|
||||
SIGNAL_MISSING_PLUGIN,
|
||||
SIGNAL_WARNING,
|
||||
SIGNAL_ERROR,
|
||||
@@ -278,14 +287,15 @@ void
|
||||
clapper_player_handle_playbin_flags_changed (ClapperPlayer *self, const GValue *value)
|
||||
{
|
||||
gint flags;
|
||||
gboolean video_enabled, audio_enabled, subtitles_enabled;
|
||||
gboolean video_changed, audio_changed, subtitles_changed;
|
||||
gboolean video_enabled, audio_enabled, subtitles_enabled, download_enabled;
|
||||
gboolean video_changed, audio_changed, subtitles_changed, download_changed;
|
||||
|
||||
flags = g_value_get_flags (value);
|
||||
|
||||
video_enabled = ((flags & CLAPPER_PLAYER_PLAY_FLAG_VIDEO) == CLAPPER_PLAYER_PLAY_FLAG_VIDEO);
|
||||
audio_enabled = ((flags & CLAPPER_PLAYER_PLAY_FLAG_AUDIO) == CLAPPER_PLAYER_PLAY_FLAG_AUDIO);
|
||||
subtitles_enabled = ((flags & CLAPPER_PLAYER_PLAY_FLAG_TEXT) == CLAPPER_PLAYER_PLAY_FLAG_TEXT);
|
||||
download_enabled = ((flags & CLAPPER_PLAYER_PLAY_FLAG_DOWNLOAD) == CLAPPER_PLAYER_PLAY_FLAG_DOWNLOAD);
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
|
||||
@@ -295,6 +305,8 @@ clapper_player_handle_playbin_flags_changed (ClapperPlayer *self, const GValue *
|
||||
self->audio_enabled = audio_enabled;
|
||||
if ((subtitles_changed = self->subtitles_enabled != subtitles_enabled))
|
||||
self->subtitles_enabled = subtitles_enabled;
|
||||
if ((download_changed = self->download_enabled != download_enabled))
|
||||
self->download_enabled = download_enabled;
|
||||
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
@@ -313,6 +325,11 @@ clapper_player_handle_playbin_flags_changed (ClapperPlayer *self, const GValue *
|
||||
clapper_app_bus_post_prop_notify (self->app_bus,
|
||||
GST_OBJECT_CAST (self), param_specs[PROP_SUBTITLES_ENABLED]);
|
||||
}
|
||||
if (download_changed) {
|
||||
GST_INFO_OBJECT (self, "Download enabled: %s", (download_enabled) ? "yes" : "no");
|
||||
clapper_app_bus_post_prop_notify (self->app_bus,
|
||||
GST_OBJECT_CAST (self), param_specs[PROP_DOWNLOAD_ENABLED]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -438,7 +455,7 @@ clapper_player_set_pending_item (ClapperPlayer *self, ClapperMediaItem *pending_
|
||||
|
||||
/* Might be NULL (e.g. after queue is cleared) */
|
||||
if (pending_item) {
|
||||
uri = clapper_media_item_get_uri (pending_item);
|
||||
uri = clapper_media_item_get_playback_uri (pending_item);
|
||||
suburi = clapper_media_item_get_suburi (pending_item);
|
||||
}
|
||||
|
||||
@@ -700,6 +717,32 @@ clapper_player_playbin_update_current_decoders (ClapperPlayer *self)
|
||||
GST_DEBUG_OBJECT (self, "Active audio decoder not found");
|
||||
}
|
||||
|
||||
static void
|
||||
_adaptive_demuxer_bandwidth_changed_cb (GstElement *adaptive_demuxer,
|
||||
GParamSpec *pspec G_GNUC_UNUSED, ClapperPlayer *self)
|
||||
{
|
||||
guint bandwidth = 0;
|
||||
gboolean changed;
|
||||
|
||||
g_object_get (adaptive_demuxer, "current-bandwidth", &bandwidth, NULL);
|
||||
|
||||
/* Skip uncalculated bandwidth from
|
||||
* new adaptive demuxer instance */
|
||||
if (bandwidth == 0)
|
||||
return;
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
if ((changed = bandwidth != self->bandwidth))
|
||||
self->bandwidth = bandwidth;
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
if (changed) {
|
||||
GST_LOG_OBJECT (self, "Adaptive bandwidth: %u", bandwidth);
|
||||
clapper_app_bus_post_prop_notify (self->app_bus,
|
||||
GST_OBJECT_CAST (self), param_specs[PROP_ADAPTIVE_BANDWIDTH]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
clapper_player_reset (ClapperPlayer *self, gboolean pending_dispose)
|
||||
{
|
||||
@@ -715,8 +758,21 @@ clapper_player_reset (ClapperPlayer *self, gboolean pending_dispose)
|
||||
gst_clear_object (&self->audio_decoder);
|
||||
}
|
||||
|
||||
if (self->adaptive_demuxer) {
|
||||
g_signal_handlers_disconnect_by_func (self->adaptive_demuxer,
|
||||
_adaptive_demuxer_bandwidth_changed_cb, self);
|
||||
gst_clear_object (&self->adaptive_demuxer);
|
||||
}
|
||||
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
gst_clear_tag_list (&self->pending_tags);
|
||||
|
||||
if (self->pending_toc) {
|
||||
gst_toc_unref (self->pending_toc);
|
||||
self->pending_toc = NULL;
|
||||
}
|
||||
|
||||
/* Emit notify when we are not going to be disposed */
|
||||
if (!pending_dispose) {
|
||||
/* Clear current decoders (next item might not have video/audio track) */
|
||||
@@ -725,6 +781,83 @@ clapper_player_reset (ClapperPlayer *self, gboolean pending_dispose)
|
||||
}
|
||||
}
|
||||
|
||||
static inline gchar *
|
||||
_make_download_template (ClapperPlayer *self)
|
||||
{
|
||||
gchar *download_template = NULL;
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
|
||||
if (self->download_enabled && self->download_dir) {
|
||||
if (g_mkdir_with_parents (self->download_dir, 0755) == 0) {
|
||||
download_template = g_build_filename (self->download_dir, "XXXXXX", NULL);
|
||||
} else {
|
||||
GST_ERROR_OBJECT (self, "Could not create download dir: \"%s\"", self->download_dir);
|
||||
}
|
||||
}
|
||||
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return download_template;
|
||||
}
|
||||
|
||||
static void
|
||||
_element_setup_cb (GstElement *playbin, GstElement *element, ClapperPlayer *self)
|
||||
{
|
||||
GstElementFactory *factory = gst_element_get_factory (element);
|
||||
const gchar *factory_name;
|
||||
|
||||
if (G_UNLIKELY (factory == NULL))
|
||||
return;
|
||||
|
||||
factory_name = g_intern_static_string (GST_OBJECT_NAME (factory));
|
||||
GST_INFO_OBJECT (self, "Element setup: %s", factory_name);
|
||||
|
||||
if (factory_name == g_intern_static_string ("downloadbuffer")) {
|
||||
gchar *download_template;
|
||||
|
||||
/* Only set props if we have download template */
|
||||
if ((download_template = _make_download_template (self))) {
|
||||
g_object_set (element,
|
||||
"temp-template", download_template,
|
||||
"temp-remove", FALSE,
|
||||
NULL);
|
||||
g_free (download_template);
|
||||
}
|
||||
} else if (factory_name == g_intern_static_string ("dashdemux2")
|
||||
|| factory_name == g_intern_static_string ("hlsdemux2")) {
|
||||
guint start_bitrate, min_bitrate, max_bitrate;
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
|
||||
start_bitrate = self->start_bitrate;
|
||||
min_bitrate = self->min_bitrate;
|
||||
max_bitrate = self->max_bitrate;
|
||||
|
||||
if (self->adaptive_demuxer) {
|
||||
g_signal_handlers_disconnect_by_func (self->adaptive_demuxer,
|
||||
_adaptive_demuxer_bandwidth_changed_cb, self);
|
||||
}
|
||||
|
||||
gst_object_replace ((GstObject **) &self->adaptive_demuxer, GST_OBJECT_CAST (element));
|
||||
|
||||
if (self->adaptive_demuxer) {
|
||||
g_signal_connect (self->adaptive_demuxer, "notify::current-bandwidth",
|
||||
G_CALLBACK (_adaptive_demuxer_bandwidth_changed_cb), self);
|
||||
}
|
||||
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
g_object_set (element,
|
||||
"low-watermark-time", 3 * GST_SECOND,
|
||||
"high-watermark-time", 10 * GST_SECOND,
|
||||
"start-bitrate", start_bitrate,
|
||||
"min-bitrate", min_bitrate,
|
||||
"max-bitrate", max_bitrate,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_about_to_finish_cb (GstElement *playbin, ClapperPlayer *self)
|
||||
{
|
||||
@@ -1505,6 +1638,293 @@ clapper_player_get_subtitles_enabled (ClapperPlayer *self)
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_player_set_download_dir:
|
||||
* @player: a #ClapperPlayer
|
||||
* @path: (type filename): the path of a directory to use for media downloads
|
||||
*
|
||||
* Set a directory that @player will use to store downloads.
|
||||
*
|
||||
* See [property@Clapper.Player:download-enabled] description for more
|
||||
* info how this works.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
clapper_player_set_download_dir (ClapperPlayer *self, const gchar *path)
|
||||
{
|
||||
gboolean changed;
|
||||
|
||||
g_return_if_fail (CLAPPER_IS_PLAYER (self));
|
||||
g_return_if_fail (path != NULL);
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
changed = g_set_str (&self->download_dir, path);
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
if (changed) {
|
||||
GST_INFO_OBJECT (self, "Current download dir: %s", path);
|
||||
clapper_app_bus_post_prop_notify (self->app_bus,
|
||||
GST_OBJECT_CAST (self), param_specs[PROP_DOWNLOAD_DIR]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_player_get_download_dir:
|
||||
* @player: a #ClapperPlayer
|
||||
*
|
||||
* Get path to a directory set for media downloads.
|
||||
*
|
||||
* Returns: (type filename) (transfer full) (nullable): the path of a directory
|
||||
* set for media downloads or %NULL if no directory was set yet.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
gchar *
|
||||
clapper_player_get_download_dir (ClapperPlayer *self)
|
||||
{
|
||||
gchar *download_dir;
|
||||
|
||||
g_return_val_if_fail (CLAPPER_IS_PLAYER (self), NULL);
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
download_dir = g_strdup (self->download_dir);
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return download_dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_player_set_download_enabled:
|
||||
* @player: a #ClapperPlayer
|
||||
* @enabled: whether enabled
|
||||
*
|
||||
* Set whether player should attempt progressive download buffering.
|
||||
*
|
||||
* For this to actually work a [property@Clapper.Player:download-dir]
|
||||
* must also be set.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
clapper_player_set_download_enabled (ClapperPlayer *self, gboolean enabled)
|
||||
{
|
||||
g_return_if_fail (CLAPPER_IS_PLAYER (self));
|
||||
|
||||
clapper_playbin_bus_post_set_play_flag (self->bus, CLAPPER_PLAYER_PLAY_FLAG_DOWNLOAD, enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_player_get_download_enabled:
|
||||
* @player: a #ClapperPlayer
|
||||
*
|
||||
* Get whether progressive download buffering is enabled.
|
||||
*
|
||||
* Returns: %TRUE if enabled, %FALSE otherwise.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
gboolean
|
||||
clapper_player_get_download_enabled (ClapperPlayer *self)
|
||||
{
|
||||
gboolean enabled;
|
||||
|
||||
g_return_val_if_fail (CLAPPER_IS_PLAYER (self), FALSE);
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
enabled = self->download_enabled;
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
static void
|
||||
_set_adaptive_bitrate (ClapperPlayer *self, guint *internal_ptr,
|
||||
const gchar *prop_name, guint bitrate, GParamSpec *pspec)
|
||||
{
|
||||
GstElement *element = NULL;
|
||||
gboolean changed;
|
||||
|
||||
if (!self->use_playbin3) {
|
||||
GST_WARNING_OBJECT (self, "Setting adaptive-%s when using playbin2"
|
||||
" has no effect", prop_name);
|
||||
}
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
if ((changed = (*internal_ptr != bitrate))) {
|
||||
*internal_ptr = bitrate;
|
||||
|
||||
if (self->adaptive_demuxer)
|
||||
element = gst_object_ref (self->adaptive_demuxer);
|
||||
}
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
if (changed) {
|
||||
GST_INFO_OBJECT (self, "Set adaptive-%s: %u", prop_name, bitrate);
|
||||
|
||||
if (element)
|
||||
g_object_set (element, prop_name, bitrate, NULL);
|
||||
|
||||
clapper_app_bus_post_prop_notify (self->app_bus, GST_OBJECT_CAST (self), pspec);
|
||||
}
|
||||
|
||||
gst_clear_object (&element);
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_player_set_adaptive_start_bitrate:
|
||||
* @player: a #ClapperPlayer
|
||||
* @bitrate: a bitrate to set (bits/s)
|
||||
*
|
||||
* Set initial bitrate to select when starting adaptive
|
||||
* streaming such as DASH or HLS.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
clapper_player_set_adaptive_start_bitrate (ClapperPlayer *self, guint bitrate)
|
||||
{
|
||||
g_return_if_fail (CLAPPER_IS_PLAYER (self));
|
||||
|
||||
_set_adaptive_bitrate (self, &self->start_bitrate,
|
||||
"start-bitrate", bitrate, param_specs[PROP_ADAPTIVE_START_BITRATE]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_player_get_adaptive_start_bitrate:
|
||||
* @player: a #ClapperPlayer
|
||||
*
|
||||
* Get currently set initial bitrate (bits/s) for adaptive streaming.
|
||||
*
|
||||
* Returns: the start bitrate value.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
guint
|
||||
clapper_player_get_adaptive_start_bitrate (ClapperPlayer *self)
|
||||
{
|
||||
guint bitrate;
|
||||
|
||||
g_return_val_if_fail (CLAPPER_IS_PLAYER (self), 0);
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
bitrate = self->start_bitrate;
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return bitrate;
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_player_set_adaptive_min_bitrate:
|
||||
* @player: a #ClapperPlayer
|
||||
* @bitrate: a bitrate to set (bits/s)
|
||||
*
|
||||
* Set minimal bitrate to select for adaptive streaming
|
||||
* such as DASH or HLS.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
clapper_player_set_adaptive_min_bitrate (ClapperPlayer *self, guint bitrate)
|
||||
{
|
||||
g_return_if_fail (CLAPPER_IS_PLAYER (self));
|
||||
|
||||
_set_adaptive_bitrate (self, &self->min_bitrate,
|
||||
"min-bitrate", bitrate, param_specs[PROP_ADAPTIVE_MIN_BITRATE]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_player_get_adaptive_min_bitrate:
|
||||
* @player: a #ClapperPlayer
|
||||
*
|
||||
* Get currently set minimal bitrate (bits/s) for adaptive streaming.
|
||||
*
|
||||
* Returns: the minimal bitrate value.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
guint
|
||||
clapper_player_get_adaptive_min_bitrate (ClapperPlayer *self)
|
||||
{
|
||||
guint bitrate;
|
||||
|
||||
g_return_val_if_fail (CLAPPER_IS_PLAYER (self), 0);
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
bitrate = self->min_bitrate;
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return bitrate;
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_player_set_adaptive_max_bitrate:
|
||||
* @player: a #ClapperPlayer
|
||||
* @bitrate: a bitrate to set (bits/s)
|
||||
*
|
||||
* Set maximal bitrate to select for adaptive streaming
|
||||
* such as DASH or HLS.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
clapper_player_set_adaptive_max_bitrate (ClapperPlayer *self, guint bitrate)
|
||||
{
|
||||
g_return_if_fail (CLAPPER_IS_PLAYER (self));
|
||||
|
||||
_set_adaptive_bitrate (self, &self->max_bitrate,
|
||||
"max-bitrate", bitrate, param_specs[PROP_ADAPTIVE_MAX_BITRATE]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_player_get_adaptive_max_bitrate:
|
||||
* @player: a #ClapperPlayer
|
||||
*
|
||||
* Get currently set maximal bitrate (bits/s) for adaptive streaming.
|
||||
*
|
||||
* Returns: the maximal bitrate value.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
guint
|
||||
clapper_player_get_adaptive_max_bitrate (ClapperPlayer *self)
|
||||
{
|
||||
guint bitrate;
|
||||
|
||||
g_return_val_if_fail (CLAPPER_IS_PLAYER (self), 0);
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
bitrate = self->max_bitrate;
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return bitrate;
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_player_get_adaptive_bandwidth:
|
||||
* @player: a #ClapperPlayer
|
||||
*
|
||||
* Get last fragment download bandwidth (bits/s) during
|
||||
* adaptive streaming.
|
||||
*
|
||||
* Returns: the adaptive bandwidth.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
guint
|
||||
clapper_player_get_adaptive_bandwidth (ClapperPlayer *self)
|
||||
{
|
||||
guint bandwidth;
|
||||
|
||||
g_return_val_if_fail (CLAPPER_IS_PLAYER (self), 0);
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
bandwidth = self->bandwidth;
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return bandwidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_player_set_audio_offset:
|
||||
* @player: a #ClapperPlayer
|
||||
@@ -1766,6 +2186,28 @@ clapper_player_add_feature (ClapperPlayer *self, ClapperFeature *feature)
|
||||
clapper_features_manager_add_feature (self->features_manager, feature, GST_OBJECT (self));
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_player_make_pipeline_graph:
|
||||
* @player: a #ClapperPlayer
|
||||
* @details: a #GstDebugGraphDetails level
|
||||
*
|
||||
* Make current #GStreamer pipeline graph in `graphviz` dot format.
|
||||
*
|
||||
* Applications can use tools like `graphviz` to display returned
|
||||
* data or just save it to a file as-is for the user to do it manually.
|
||||
*
|
||||
* Returns: (transfer full): current pipeline description in dot format.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
gchar *
|
||||
clapper_player_make_pipeline_graph (ClapperPlayer *self, GstDebugGraphDetails details)
|
||||
{
|
||||
g_return_val_if_fail (CLAPPER_IS_PLAYER (self), NULL);
|
||||
|
||||
return gst_debug_bin_to_dot_data (GST_BIN (self->playbin), details);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_player_thread_start (ClapperThreadedObject *threaded_object)
|
||||
{
|
||||
@@ -1779,7 +2221,7 @@ clapper_player_thread_start (ClapperThreadedObject *threaded_object)
|
||||
if (!(env = g_getenv ("CLAPPER_USE_PLAYBIN3"))) // Clapper override
|
||||
env = g_getenv ("GST_CLAPPER_USE_PLAYBIN3"); // compat
|
||||
|
||||
self->use_playbin3 = (env && g_str_has_prefix (env, "1"));
|
||||
self->use_playbin3 = (!env || g_str_has_prefix (env, "1"));
|
||||
playbin_str = (self->use_playbin3) ? "playbin3" : "playbin";
|
||||
|
||||
if (!(self->playbin = gst_element_factory_make (playbin_str, NULL))) {
|
||||
@@ -1793,6 +2235,7 @@ clapper_player_thread_start (ClapperThreadedObject *threaded_object)
|
||||
for (i = 0; playbin_watchlist[i]; ++i)
|
||||
gst_element_add_property_notify_watch (self->playbin, playbin_watchlist[i], TRUE);
|
||||
|
||||
g_signal_connect (self->playbin, "element-setup", G_CALLBACK (_element_setup_cb), self);
|
||||
g_signal_connect (self->playbin, "about-to-finish", G_CALLBACK (_about_to_finish_cb), self);
|
||||
|
||||
if (!self->use_playbin3) {
|
||||
@@ -1866,6 +2309,8 @@ clapper_player_init (ClapperPlayer *self)
|
||||
self->video_enabled = DEFAULT_VIDEO_ENABLED;
|
||||
self->audio_enabled = DEFAULT_AUDIO_ENABLED;
|
||||
self->subtitles_enabled = DEFAULT_SUBTITLES_ENABLED;
|
||||
self->download_enabled = DEFAULT_DOWNLOAD_ENABLED;
|
||||
self->start_bitrate = DEFAULT_ADAPTIVE_START_BITRATE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1924,6 +2369,8 @@ clapper_player_finalize (GObject *object)
|
||||
gst_clear_object (&self->pending_item);
|
||||
gst_clear_object (&self->played_item);
|
||||
|
||||
g_free (self->download_dir);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@@ -1991,6 +2438,24 @@ clapper_player_get_property (GObject *object, guint prop_id,
|
||||
case PROP_SUBTITLES_ENABLED:
|
||||
g_value_set_boolean (value, clapper_player_get_subtitles_enabled (self));
|
||||
break;
|
||||
case PROP_DOWNLOAD_DIR:
|
||||
g_value_take_string (value, clapper_player_get_download_dir (self));
|
||||
break;
|
||||
case PROP_DOWNLOAD_ENABLED:
|
||||
g_value_set_boolean (value, clapper_player_get_download_enabled (self));
|
||||
break;
|
||||
case PROP_ADAPTIVE_START_BITRATE:
|
||||
g_value_set_uint (value, clapper_player_get_adaptive_start_bitrate (self));
|
||||
break;
|
||||
case PROP_ADAPTIVE_MIN_BITRATE:
|
||||
g_value_set_uint (value, clapper_player_get_adaptive_min_bitrate (self));
|
||||
break;
|
||||
case PROP_ADAPTIVE_MAX_BITRATE:
|
||||
g_value_set_uint (value, clapper_player_get_adaptive_max_bitrate (self));
|
||||
break;
|
||||
case PROP_ADAPTIVE_BANDWIDTH:
|
||||
g_value_set_uint (value, clapper_player_get_adaptive_bandwidth (self));
|
||||
break;
|
||||
case PROP_AUDIO_OFFSET:
|
||||
g_value_set_double (value, clapper_player_get_audio_offset (self));
|
||||
break;
|
||||
@@ -2046,6 +2511,21 @@ clapper_player_set_property (GObject *object, guint prop_id,
|
||||
case PROP_SUBTITLES_ENABLED:
|
||||
clapper_player_set_subtitles_enabled (self, g_value_get_boolean (value));
|
||||
break;
|
||||
case PROP_DOWNLOAD_DIR:
|
||||
clapper_player_set_download_dir (self, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_DOWNLOAD_ENABLED:
|
||||
clapper_player_set_download_enabled (self, g_value_get_boolean (value));
|
||||
break;
|
||||
case PROP_ADAPTIVE_START_BITRATE:
|
||||
clapper_player_set_adaptive_start_bitrate (self, g_value_get_uint (value));
|
||||
break;
|
||||
case PROP_ADAPTIVE_MIN_BITRATE:
|
||||
clapper_player_set_adaptive_min_bitrate (self, g_value_get_uint (value));
|
||||
break;
|
||||
case PROP_ADAPTIVE_MAX_BITRATE:
|
||||
clapper_player_set_adaptive_max_bitrate (self, g_value_get_uint (value));
|
||||
break;
|
||||
case PROP_AUDIO_OFFSET:
|
||||
clapper_player_set_audio_offset (self, g_value_get_double (value));
|
||||
break;
|
||||
@@ -2251,6 +2731,118 @@ clapper_player_class_init (ClapperPlayerClass *klass)
|
||||
NULL, NULL, DEFAULT_SUBTITLES_ENABLED,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClapperPlayer:download-dir:
|
||||
*
|
||||
* A directory that @player will use to download network content
|
||||
* when [property@Clapper.Player:download-enabled] is set to %TRUE.
|
||||
*
|
||||
* If directory at @path does not exist, it will be automatically created.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
param_specs[PROP_DOWNLOAD_DIR] = g_param_spec_string ("download-dir",
|
||||
NULL, NULL, NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClapperPlayer:download-enabled:
|
||||
*
|
||||
* Whether progressive download buffering is enabled.
|
||||
*
|
||||
* If progressive download is enabled and [property@Clapper.Player:download-dir]
|
||||
* is set, streamed network content will be cached to the disk space instead
|
||||
* of memory whenever possible. This allows for faster seeking through
|
||||
* currently played media.
|
||||
*
|
||||
* Not every type of content is download applicable. Mainly applies to
|
||||
* web content that does not use adaptive streaming.
|
||||
*
|
||||
* Once data that media item URI points to is fully downloaded, player
|
||||
* will emit [signal@Clapper.Player::download-complete] signal with a
|
||||
* location of downloaded file.
|
||||
*
|
||||
* Playing again the exact same [class@Clapper.MediaItem] object that was
|
||||
* previously fully downloaded will cause player to automatically use that
|
||||
* cached file if it still exists, avoiding any further network requests.
|
||||
*
|
||||
* Please note that player will not delete nor manage downloaded content.
|
||||
* It is up to application to cleanup data in created cache directory
|
||||
* (e.g. before app exits), in order to remove any downloads that app
|
||||
* is not going to use next time it is run and incomplete ones.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
param_specs[PROP_DOWNLOAD_ENABLED] = g_param_spec_boolean ("download-enabled",
|
||||
NULL, NULL, DEFAULT_DOWNLOAD_ENABLED,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClapperPlayer:adaptive-start-bitrate:
|
||||
*
|
||||
* An initial bitrate (bits/s) to select during
|
||||
* starting adaptive streaming such as DASH or HLS.
|
||||
*
|
||||
* If value is higher than lowest available bitrate in streaming
|
||||
* manifest, then lowest possible bitrate will be selected.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
param_specs[PROP_ADAPTIVE_START_BITRATE] = g_param_spec_uint ("adaptive-start-bitrate",
|
||||
NULL, NULL, 0, G_MAXUINT, DEFAULT_ADAPTIVE_START_BITRATE,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClapperPlayer:adaptive-min-bitrate:
|
||||
*
|
||||
* A minimal allowed bitrate (bits/s) during adaptive streaming
|
||||
* such as DASH or HLS.
|
||||
*
|
||||
* Setting this will prevent streaming from entering lower qualities
|
||||
* (even when connection speed cannot keep up). When set together with
|
||||
* [property@Clapper.Player:adaptive-max-bitrate] it can be used to
|
||||
* enforce some specific quality.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
param_specs[PROP_ADAPTIVE_MIN_BITRATE] = g_param_spec_uint ("adaptive-min-bitrate",
|
||||
NULL, NULL, 0, G_MAXUINT, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClapperPlayer:adaptive-max-bitrate:
|
||||
*
|
||||
* A maximal allowed bitrate (bits/s) during adaptive streaming
|
||||
* such as DASH or HLS (`0` for unlimited).
|
||||
*
|
||||
* Setting this will prevent streaming from entering qualities with
|
||||
* higher bandwidth than the one set. When set together with
|
||||
* [property@Clapper.Player:adaptive-min-bitrate] it can be used to
|
||||
* enforce some specific quality.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
param_specs[PROP_ADAPTIVE_MAX_BITRATE] = g_param_spec_uint ("adaptive-max-bitrate",
|
||||
NULL, NULL, 0, G_MAXUINT, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClapperPlayer:adaptive-bandwidth:
|
||||
*
|
||||
* Last fragment download bandwidth (bits/s) during adaptive streaming.
|
||||
*
|
||||
* This property only changes when adaptive streaming and later stays
|
||||
* at the last value until streaming some adaptive content again.
|
||||
*
|
||||
* Apps can use this to determine and set an optimal value for
|
||||
* [property@Clapper.Player:adaptive-start-bitrate].
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
param_specs[PROP_ADAPTIVE_BANDWIDTH] = g_param_spec_uint ("adaptive-bandwidth",
|
||||
NULL, NULL, 0, G_MAXUINT, 0,
|
||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClapperPlayer:audio-offset:
|
||||
*
|
||||
@@ -2288,6 +2880,22 @@ clapper_player_class_init (ClapperPlayerClass *klass)
|
||||
G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
|
||||
0, NULL, NULL, NULL, G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* ClapperPlayer::download-complete:
|
||||
* @player: a #ClapperPlayer
|
||||
* @item: a #ClapperMediaItem
|
||||
* @location: (type filename): a path to downloaded file
|
||||
*
|
||||
* Media was fully downloaded to local cache directory. This signal will
|
||||
* be only emitted when progressive download buffering is enabled by
|
||||
* setting [property@Clapper.Player:download-enabled] property to %TRUE.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
signals[SIGNAL_DOWNLOAD_COMPLETE] = g_signal_new ("download-complete",
|
||||
G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
|
||||
0, NULL, NULL, NULL, G_TYPE_NONE, 2, CLAPPER_TYPE_MEDIA_ITEM, G_TYPE_STRING);
|
||||
|
||||
/**
|
||||
* ClapperPlayer::missing-plugin:
|
||||
* @player: a #ClapperPlayer
|
||||
|
@@ -26,6 +26,8 @@
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <clapper/clapper-visibility.h>
|
||||
#include <clapper/clapper-threaded-object.h>
|
||||
#include <clapper/clapper-queue.h>
|
||||
#include <clapper/clapper-stream-list.h>
|
||||
@@ -37,92 +39,172 @@ G_BEGIN_DECLS
|
||||
#define CLAPPER_TYPE_PLAYER (clapper_player_get_type())
|
||||
#define CLAPPER_PLAYER_CAST(obj) ((ClapperPlayer *)(obj))
|
||||
|
||||
CLAPPER_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperPlayer, clapper_player, CLAPPER, PLAYER, ClapperThreadedObject)
|
||||
|
||||
CLAPPER_API
|
||||
ClapperPlayer * clapper_player_new (void);
|
||||
|
||||
CLAPPER_API
|
||||
ClapperQueue * clapper_player_get_queue (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
ClapperStreamList * clapper_player_get_video_streams (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
ClapperStreamList * clapper_player_get_audio_streams (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
ClapperStreamList * clapper_player_get_subtitle_streams (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_set_autoplay (ClapperPlayer *player, gboolean enabled);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_player_get_autoplay (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
gdouble clapper_player_get_position (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
ClapperPlayerState clapper_player_get_state (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_set_mute (ClapperPlayer *player, gboolean mute);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_player_get_mute (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_set_volume (ClapperPlayer *player, gdouble volume);
|
||||
|
||||
CLAPPER_API
|
||||
gdouble clapper_player_get_volume (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_set_speed (ClapperPlayer *player, gdouble speed);
|
||||
|
||||
CLAPPER_API
|
||||
gdouble clapper_player_get_speed (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_set_video_sink (ClapperPlayer *player, GstElement *element);
|
||||
|
||||
CLAPPER_API
|
||||
GstElement * clapper_player_get_video_sink (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_set_audio_sink (ClapperPlayer *player, GstElement *element);
|
||||
|
||||
CLAPPER_API
|
||||
GstElement * clapper_player_get_audio_sink (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_set_video_filter (ClapperPlayer *player, GstElement *element);
|
||||
|
||||
CLAPPER_API
|
||||
GstElement * clapper_player_get_video_filter (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_set_audio_filter (ClapperPlayer *player, GstElement *element);
|
||||
|
||||
CLAPPER_API
|
||||
GstElement * clapper_player_get_audio_filter (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
GstElement * clapper_player_get_current_video_decoder (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
GstElement * clapper_player_get_current_audio_decoder (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_set_video_enabled (ClapperPlayer *player, gboolean enabled);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_player_get_video_enabled (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_set_audio_enabled (ClapperPlayer *player, gboolean enabled);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_player_get_audio_enabled (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_set_subtitles_enabled (ClapperPlayer *player, gboolean enabled);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_player_get_subtitles_enabled (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_set_download_dir (ClapperPlayer *player, const gchar *path);
|
||||
|
||||
CLAPPER_API
|
||||
gchar * clapper_player_get_download_dir (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_set_download_enabled (ClapperPlayer *player, gboolean enabled);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_player_get_download_enabled (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_set_adaptive_start_bitrate (ClapperPlayer *player, guint bitrate);
|
||||
|
||||
CLAPPER_API
|
||||
guint clapper_player_get_adaptive_start_bitrate (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_set_adaptive_min_bitrate (ClapperPlayer *player, guint bitrate);
|
||||
|
||||
CLAPPER_API
|
||||
guint clapper_player_get_adaptive_min_bitrate (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_set_adaptive_max_bitrate (ClapperPlayer *player, guint bitrate);
|
||||
|
||||
CLAPPER_API
|
||||
guint clapper_player_get_adaptive_max_bitrate (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
guint clapper_player_get_adaptive_bandwidth (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_set_audio_offset (ClapperPlayer *player, gdouble offset);
|
||||
|
||||
CLAPPER_API
|
||||
gdouble clapper_player_get_audio_offset (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_set_subtitle_offset (ClapperPlayer *player, gdouble offset);
|
||||
|
||||
CLAPPER_API
|
||||
gdouble clapper_player_get_subtitle_offset (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_set_subtitle_font_desc (ClapperPlayer *player, const gchar *font_desc);
|
||||
|
||||
CLAPPER_API
|
||||
gchar * clapper_player_get_subtitle_font_desc (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_play (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_pause (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_stop (ClapperPlayer *player);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_seek (ClapperPlayer *player, gdouble position);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_seek_custom (ClapperPlayer *player, gdouble position, ClapperPlayerSeekMethod method);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_player_add_feature (ClapperPlayer *player, ClapperFeature *feature);
|
||||
|
||||
CLAPPER_API
|
||||
gchar * clapper_player_make_pipeline_graph (ClapperPlayer *player, GstDebugGraphDetails details);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include <glib-object.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <clapper/clapper-visibility.h>
|
||||
#include <clapper/clapper-enums.h>
|
||||
#include <clapper/clapper-media-item.h>
|
||||
|
||||
@@ -35,6 +36,7 @@ G_BEGIN_DECLS
|
||||
#define CLAPPER_TYPE_QUEUE (clapper_queue_get_type())
|
||||
#define CLAPPER_QUEUE_CAST(obj) ((ClapperQueue *)(obj))
|
||||
|
||||
CLAPPER_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperQueue, clapper_queue, CLAPPER, QUEUE, GstObject)
|
||||
|
||||
/**
|
||||
@@ -44,50 +46,73 @@ G_DECLARE_FINAL_TYPE (ClapperQueue, clapper_queue, CLAPPER, QUEUE, GstObject)
|
||||
*/
|
||||
#define CLAPPER_QUEUE_INVALID_POSITION ((guint) 0xffffffff)
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_queue_add_item (ClapperQueue *queue, ClapperMediaItem *item);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_queue_insert_item (ClapperQueue *queue, ClapperMediaItem *item, gint index);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_queue_reposition_item (ClapperQueue *queue, ClapperMediaItem *item, gint index);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_queue_remove_item (ClapperQueue *queue, ClapperMediaItem *item);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_queue_remove_index (ClapperQueue *queue, guint index);
|
||||
|
||||
CLAPPER_API
|
||||
ClapperMediaItem * clapper_queue_steal_index (ClapperQueue *queue, guint index);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_queue_clear (ClapperQueue *queue);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_queue_select_item (ClapperQueue *queue, ClapperMediaItem *item);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_queue_select_index (ClapperQueue *queue, guint index);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_queue_select_next_item (ClapperQueue *queue);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_queue_select_previous_item (ClapperQueue *queue);
|
||||
|
||||
CLAPPER_API
|
||||
ClapperMediaItem * clapper_queue_get_item (ClapperQueue *queue, guint index);
|
||||
|
||||
CLAPPER_API
|
||||
ClapperMediaItem * clapper_queue_get_current_item (ClapperQueue *queue);
|
||||
|
||||
CLAPPER_API
|
||||
guint clapper_queue_get_current_index (ClapperQueue *queue);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_queue_item_is_current (ClapperQueue *queue, ClapperMediaItem *item);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_queue_find_item (ClapperQueue *queue, ClapperMediaItem *item, guint *index);
|
||||
|
||||
CLAPPER_API
|
||||
guint clapper_queue_get_n_items (ClapperQueue *queue);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_queue_set_progression_mode (ClapperQueue *queue, ClapperQueueProgressionMode mode);
|
||||
|
||||
CLAPPER_API
|
||||
ClapperQueueProgressionMode clapper_queue_get_progression_mode (ClapperQueue *queue);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_queue_set_gapless (ClapperQueue *queue, gboolean gapless);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_queue_get_gapless (ClapperQueue *queue);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_queue_set_instant (ClapperQueue *queue, gboolean instant);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_queue_get_instant (ClapperQueue *queue);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include <glib-object.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <clapper/clapper-visibility.h>
|
||||
#include <clapper/clapper-stream.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -34,6 +35,7 @@ G_BEGIN_DECLS
|
||||
#define CLAPPER_TYPE_STREAM_LIST (clapper_stream_list_get_type())
|
||||
#define CLAPPER_STREAM_LIST_CAST(obj) ((ClapperStreamList *)(obj))
|
||||
|
||||
CLAPPER_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperStreamList, clapper_stream_list, CLAPPER, STREAM_LIST, GstObject)
|
||||
|
||||
/**
|
||||
@@ -43,16 +45,22 @@ G_DECLARE_FINAL_TYPE (ClapperStreamList, clapper_stream_list, CLAPPER, STREAM_LI
|
||||
*/
|
||||
#define CLAPPER_STREAM_LIST_INVALID_POSITION ((guint) 0xffffffff)
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_stream_list_select_stream (ClapperStreamList *list, ClapperStream *stream);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_stream_list_select_index (ClapperStreamList *list, guint index);
|
||||
|
||||
CLAPPER_API
|
||||
ClapperStream * clapper_stream_list_get_stream (ClapperStreamList *list, guint index);
|
||||
|
||||
CLAPPER_API
|
||||
ClapperStream * clapper_stream_list_get_current_stream (ClapperStreamList *list);
|
||||
|
||||
CLAPPER_API
|
||||
guint clapper_stream_list_get_current_index (ClapperStreamList *list);
|
||||
|
||||
CLAPPER_API
|
||||
guint clapper_stream_list_get_n_streams (ClapperStreamList *list);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include <glib-object.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <clapper/clapper-visibility.h>
|
||||
#include <clapper/clapper-enums.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -34,6 +35,7 @@ G_BEGIN_DECLS
|
||||
#define CLAPPER_TYPE_STREAM (clapper_stream_get_type())
|
||||
#define CLAPPER_STREAM_CAST(obj) ((ClapperStream *)(obj))
|
||||
|
||||
CLAPPER_API
|
||||
G_DECLARE_DERIVABLE_TYPE (ClapperStream, clapper_stream, CLAPPER, STREAM, GstObject)
|
||||
|
||||
struct _ClapperStreamClass
|
||||
@@ -58,8 +60,10 @@ struct _ClapperStreamClass
|
||||
gpointer padding[4];
|
||||
};
|
||||
|
||||
CLAPPER_API
|
||||
ClapperStreamType clapper_stream_get_stream_type (ClapperStream *stream);
|
||||
|
||||
CLAPPER_API
|
||||
gchar * clapper_stream_get_title (ClapperStream *stream);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -25,6 +25,8 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <clapper/clapper-visibility.h>
|
||||
#include <clapper/clapper-stream.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -32,10 +34,13 @@ G_BEGIN_DECLS
|
||||
#define CLAPPER_TYPE_SUBTITLE_STREAM (clapper_subtitle_stream_get_type())
|
||||
#define CLAPPER_SUBTITLE_STREAM_CAST(obj) ((ClapperSubtitleStream *)(obj))
|
||||
|
||||
CLAPPER_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperSubtitleStream, clapper_subtitle_stream, CLAPPER, SUBTITLE_STREAM, ClapperStream)
|
||||
|
||||
CLAPPER_API
|
||||
gchar * clapper_subtitle_stream_get_lang_code (ClapperSubtitleStream *stream);
|
||||
|
||||
CLAPPER_API
|
||||
gchar * clapper_subtitle_stream_get_lang_name (ClapperSubtitleStream *stream);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -27,11 +27,14 @@
|
||||
#include <glib-object.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <clapper/clapper-visibility.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLAPPER_TYPE_THREADED_OBJECT (clapper_threaded_object_get_type())
|
||||
#define CLAPPER_THREADED_OBJECT_CAST(obj) ((ClapperThreadedObject *)(obj))
|
||||
|
||||
CLAPPER_API
|
||||
G_DECLARE_DERIVABLE_TYPE (ClapperThreadedObject, clapper_threaded_object, CLAPPER, THREADED_OBJECT, GstObject)
|
||||
|
||||
/**
|
||||
@@ -68,6 +71,7 @@ struct _ClapperThreadedObjectClass
|
||||
gpointer padding[4];
|
||||
};
|
||||
|
||||
CLAPPER_API
|
||||
GMainContext * clapper_threaded_object_get_context (ClapperThreadedObject *threaded_object);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include <glib-object.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <clapper/clapper-visibility.h>
|
||||
#include <clapper/clapper-marker.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -34,14 +35,19 @@ G_BEGIN_DECLS
|
||||
#define CLAPPER_TYPE_TIMELINE (clapper_timeline_get_type())
|
||||
#define CLAPPER_TIMELINE_CAST(obj) ((ClapperTimeline *)(obj))
|
||||
|
||||
CLAPPER_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperTimeline, clapper_timeline, CLAPPER, TIMELINE, GstObject)
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_timeline_insert_marker (ClapperTimeline *timeline, ClapperMarker *marker);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_timeline_remove_marker (ClapperTimeline *timeline, ClapperMarker *marker);
|
||||
|
||||
CLAPPER_API
|
||||
ClapperMarker * clapper_timeline_get_marker (ClapperTimeline *timeline, guint index);
|
||||
|
||||
CLAPPER_API
|
||||
guint clapper_timeline_get_n_markers (ClapperTimeline *timeline);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -25,6 +25,8 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <clapper/clapper-visibility.h>
|
||||
#include <clapper/clapper-stream.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -32,18 +34,25 @@ G_BEGIN_DECLS
|
||||
#define CLAPPER_TYPE_VIDEO_STREAM (clapper_video_stream_get_type())
|
||||
#define CLAPPER_VIDEO_STREAM_CAST(obj) ((ClapperVideoStream *)(obj))
|
||||
|
||||
CLAPPER_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperVideoStream, clapper_video_stream, CLAPPER, VIDEO_STREAM, ClapperStream)
|
||||
|
||||
CLAPPER_API
|
||||
gchar * clapper_video_stream_get_codec (ClapperVideoStream *stream);
|
||||
|
||||
CLAPPER_API
|
||||
gint clapper_video_stream_get_width (ClapperVideoStream *stream);
|
||||
|
||||
CLAPPER_API
|
||||
gint clapper_video_stream_get_height (ClapperVideoStream *stream);
|
||||
|
||||
CLAPPER_API
|
||||
gdouble clapper_video_stream_get_fps (ClapperVideoStream *stream);
|
||||
|
||||
CLAPPER_API
|
||||
guint clapper_video_stream_get_bitrate (ClapperVideoStream *stream);
|
||||
|
||||
CLAPPER_API
|
||||
gchar * clapper_video_stream_get_pixel_format (ClapperVideoStream *stream);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -17,6 +17,8 @@
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/pbutils/pbutils.h>
|
||||
|
||||
@@ -25,6 +27,11 @@
|
||||
#include "clapper-playbin-bus-private.h"
|
||||
#include "clapper-app-bus-private.h"
|
||||
#include "clapper-features-bus-private.h"
|
||||
#include "gst/clapper-plugin-private.h"
|
||||
|
||||
#if CLAPPER_WITH_ENHANCERS_LOADER
|
||||
#include "clapper-enhancers-loader-private.h"
|
||||
#endif
|
||||
|
||||
static gboolean is_initialized = FALSE;
|
||||
static GMutex init_lock;
|
||||
@@ -44,6 +51,22 @@ clapper_init_check_internal (int *argc, char **argv[])
|
||||
clapper_app_bus_initialize ();
|
||||
clapper_features_bus_initialize ();
|
||||
|
||||
#if CLAPPER_WITH_ENHANCERS_LOADER
|
||||
clapper_enhancers_loader_initialize ();
|
||||
#endif
|
||||
|
||||
gst_plugin_register_static (
|
||||
GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
PACKAGE "internal",
|
||||
PLUGIN_DESC,
|
||||
(GstPluginInitFunc) clapper_gst_plugin_init,
|
||||
PACKAGE_VERSION,
|
||||
PLUGIN_LICENSE,
|
||||
PACKAGE,
|
||||
PACKAGE,
|
||||
PACKAGE_ORIGIN);
|
||||
|
||||
is_initialized = TRUE;
|
||||
|
||||
finish:
|
||||
@@ -92,3 +115,52 @@ clapper_init_check (int *argc, char **argv[])
|
||||
{
|
||||
return clapper_init_check_internal (argc, argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_enhancer_check:
|
||||
* @iface_type: an interface #GType
|
||||
* @scheme: an URI scheme
|
||||
* @host: (nullable): an URI host
|
||||
* @name: (out) (optional) (transfer none): return location for found enhancer name
|
||||
*
|
||||
* Check if an enhancer of @type is available for given @scheme and @host.
|
||||
*
|
||||
* A check that compares requested capabilites of all available Clapper enhancers,
|
||||
* thus it is fast but does not guarantee that the found one will succeed. Please note
|
||||
* that this function will always return %FALSE if Clapper was built without enhancers
|
||||
* loader functionality. To check that, use [const@Clapper.WITH_ENHANCERS_LOADER].
|
||||
*
|
||||
* This function can be used to quickly determine early if Clapper will at least try to
|
||||
* handle URI and with one of its enhancers and which one.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```c
|
||||
* gboolean supported = clapper_enhancer_check (CLAPPER_TYPE_EXTRACTABLE, "https", "example.com", NULL);
|
||||
* ```
|
||||
*
|
||||
* For self hosted services a custom URI @scheme without @host can be used. Enhancers should announce
|
||||
* support for such schemes by defining them in their plugin info files.
|
||||
*
|
||||
* ```c
|
||||
* gboolean supported = clapper_enhancer_check (CLAPPER_TYPE_EXTRACTABLE, "example", NULL, NULL);
|
||||
* ```
|
||||
*
|
||||
* Returns: whether a plausible enhancer was found.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
gboolean
|
||||
clapper_enhancer_check (GType iface_type, const gchar *scheme, const gchar *host, const gchar **name)
|
||||
{
|
||||
gboolean success = FALSE;
|
||||
|
||||
g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface_type), FALSE);
|
||||
g_return_val_if_fail (scheme != NULL, FALSE);
|
||||
|
||||
#if CLAPPER_WITH_ENHANCERS_LOADER
|
||||
success = clapper_enhancers_loader_check (iface_type, scheme, host, name);
|
||||
#endif
|
||||
|
||||
return success;
|
||||
}
|
||||
|
@@ -19,13 +19,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#define __CLAPPER_INSIDE__
|
||||
|
||||
#include <clapper/clapper-visibility.h>
|
||||
|
||||
#include <clapper/clapper-enums.h>
|
||||
#include <clapper/clapper-version.h>
|
||||
|
||||
#include <clapper/clapper-audio-stream.h>
|
||||
#include <clapper/clapper-feature.h>
|
||||
#include <clapper/clapper-harvest.h>
|
||||
#include <clapper/clapper-marker.h>
|
||||
#include <clapper/clapper-media-item.h>
|
||||
#include <clapper/clapper-player.h>
|
||||
@@ -38,6 +44,9 @@
|
||||
#include <clapper/clapper-utils.h>
|
||||
#include <clapper/clapper-video-stream.h>
|
||||
|
||||
#include <clapper/clapper-extractable.h>
|
||||
|
||||
#include <clapper/clapper-functionalities-availability.h>
|
||||
#include <clapper/features/clapper-features-availability.h>
|
||||
|
||||
#if CLAPPER_HAVE_DISCOVERER
|
||||
@@ -52,10 +61,15 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_init (int *argc, char **argv[]);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_init_check (int *argc, char **argv[]);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_enhancer_check (GType iface_type, const gchar *scheme, const gchar *host, const gchar **name);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#undef __CLAPPER_INSIDE__
|
||||
|
@@ -25,6 +25,8 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <clapper/clapper-visibility.h>
|
||||
#include <clapper/clapper-feature.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -32,12 +34,16 @@ G_BEGIN_DECLS
|
||||
#define CLAPPER_TYPE_DISCOVERER (clapper_discoverer_get_type())
|
||||
#define CLAPPER_DISCOVERER_CAST(obj) ((ClapperDiscoverer *)(obj))
|
||||
|
||||
CLAPPER_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperDiscoverer, clapper_discoverer, CLAPPER, DISCOVERER, ClapperFeature)
|
||||
|
||||
CLAPPER_API
|
||||
ClapperDiscoverer * clapper_discoverer_new (void);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_discoverer_set_discovery_mode (ClapperDiscoverer *discoverer, ClapperDiscovererDiscoveryMode mode);
|
||||
|
||||
CLAPPER_API
|
||||
ClapperDiscovererDiscoveryMode clapper_discoverer_get_discovery_mode (ClapperDiscoverer *discoverer);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -14,7 +14,7 @@ clapper_possible_features = [
|
||||
foreach feature_name : clapper_possible_features
|
||||
subdir(feature_name)
|
||||
features_availability_conf.set(
|
||||
'CLAPPER_HAVE_@0@'.format(feature_name.to_upper()),
|
||||
'CLAPPER_HAVE_@0@'.format(feature_name.replace('-', '_').to_upper()),
|
||||
clapper_available_features.contains(feature_name) ? 'TRUE' : 'FALSE'
|
||||
)
|
||||
endforeach
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user