Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videolan/vlc
  • chouquette/vlc
  • bakiewicz.marek122/vlc
  • devnexen/vlc
  • rohanrajpal/vlc
  • blurrrb/vlc
  • gsoc/gsoc2019/darkapex/vlc
  • b1ue/vlc
  • fkuehne/vlc
  • magsoft/vlc
  • chub/vlc
  • cramiro9/vlc
  • robUx4/vlc
  • rom1v/vlc
  • akshayaky/vlc
  • tmk907/vlc
  • akymaster/vlc
  • govind.sharma/vlc
  • psilokos/vlc
  • xjbeta/vlc
  • jahan/vlc
  • 1480c1/vlc
  • amanchande/vlc
  • aaqib/vlc
  • rist/vlc
  • apol/vlc
  • mindfreeze/vlc
  • alexandre-janniaux/vlc
  • sandsmark/vlc
  • jagannatharjun/vlc
  • gsoc/gsoc2020/matiaslgonzalez/vlc
  • gsoc/gsoc2020/jagannatharjun/vlc
  • mstorsjo/vlc
  • gsoc/gsoc2020/vedenta/vlc
  • gsoc/gsoc2020/arnav-ishaan/vlc
  • gsoc/gsoc2020/andreduong/vlc
  • fuzun/vlc
  • gsoc/gsoc2020/vatsin/vlc
  • gsoc/gsoc2020/sagid/vlc
  • yaron/vlc
  • Phoenix/vlc
  • Garf/vlc
  • ePiratWorkarounds/vlc
  • tguillem/vlc
  • jnqnfe/vlc
  • mdc/vlc
  • Vedaa/vlc
  • rasa/vlc
  • quink/vlc
  • yealo/vlc
  • aleksey_ak/vlc
  • ePirat/vlc
  • ilya.yanok/vlc
  • asenat/vlc
  • m/vlc
  • bunjee/vlc
  • BLumia/vlc
  • sagudev/vlc
  • hamedmonji30/vlc
  • nullgemm/vlc
  • DivyamAhuja/vlc
  • thesamesam/vlc
  • dag7/vlc
  • snehil101/vlc
  • haasn/vlc
  • jbk/vlc
  • ValZapod/vlc
  • mfkl/vlc
  • WangChuan/vlc
  • core1024/vlc
  • GhostVaibhav/vlc
  • dfuhrmann/vlc
  • davide.prade/vlc
  • tmatth/vlc
  • Courmisch/vlc
  • zouya/vlc
  • hpi/vlc
  • EwoutH/vlc
  • aleung27/vlc
  • hengwu0/vlc
  • saladin/vlc
  • ashuio/vlc
  • richselwood/vlc
  • verma16Ayush/vlc
  • chemicalflash/vlc
  • PoignardAzur/vlc
  • huangjieNT/vlc
  • Blake-Haydon/vlc
  • AnuthaDev/vlc
  • gsoc/gsoc2021/mpd/vlc
  • nicolas_lequec/vlc
  • sambassaly/vlc
  • thresh/vlc
  • bonniegong/vlc
  • myaashish/vlc
  • stavros.vagionitis/vlc
  • ileoo/vlc
  • louis-santucci/vlc
  • cchristiansen/vlc
  • sabyasachi07/vlc
  • AbduAmeen/vlc
  • ashishb0410/vlc
  • urbanhusky/vlc
  • davidepietrasanta/vlc
  • riksleutelstad/vlc
  • jeremyVignelles/vlc
  • komh/vlc
  • iamjithinjohn/vlc
  • JohannesKauffmann/vlc2
  • kunglao/vlc
  • natzberg/vlc
  • jill/vlc
  • cwendling/vlc
  • adufou/vlc
  • ErwanAirone/vlc
  • HasinduDilshan10/vlc
  • vagrantc/vlc
  • rafiv/macos-bigsur-icon
  • Aymeriic/vlc
  • saranshg20/vlc
  • metzlove24/vlc
  • linkfanel/vlc
  • Ds886/vlc
  • metehan-arslan/vlc
  • Skantes/vlc
  • kgsandundananjaya96/vlc
  • mitchcapper/vlc
  • advaitgupta/vlc
  • StefanBruens/vlc
  • ratajs/vlc
  • T.M.F.B.3761/vlc
  • m222059/vlc
  • casemerrick/vlc
  • joshuaword2alt/vlc
  • sjwaddy/vlc
  • dima/vlc
  • Ybalrid/vlc
  • umxprime/vlc
  • eschmidt/vlc
  • vannieuwenhuysenmichelle/vlc
  • badcf00d/vlc
  • wesinator/vlc
  • louis/vlc
  • xqq/vlc
  • EmperorYP7/vlc
  • NicoLiam/vlc
  • loveleen/vlc
  • rofferom/vlc
  • rbultje/vlc
  • TheUnamed/vlc
  • pratiksharma341/vlc
  • Saurab17/vlc
  • purist.coder/vlc
  • Shuicheng/vlc
  • mdrrubel292/vlc
  • silverbleu00/vlc
  • metif12/vlc
  • asher-m/vlc
  • jeffk/vlc
  • Brandonbr1/vlc
  • beautyyuyanli/vlc
  • rego21/vlc
  • muyangren907/vlc
  • collectionbylawrencejason/vlc
  • evelez/vlc
  • GSMgeeth/vlc
  • Oneric/vlc
  • TJ5/vlc
  • XuanTung95/vlc
  • darrenjenny21/vlc
  • Trenly/vlc
  • RockyTDR/vlc
  • mjakubowski/vlc
  • caprica/vlc
  • ForteFrankie/vlc
  • seannamiller19/vlc
  • junlon2006/vlc
  • kiwiren6666/vlc
  • iuseiphonexs/vlc
  • fenngtun/vlc
  • Rajdutt999/vlc
  • typx/vlc
  • leon.vitanos/vlc
  • robertogarci0938/vlc
  • gsoc/gsoc2022/luc65r/vlc-mpd
  • skeller/vlc
  • MCJack123/vlc
  • luc65r/vlc-mpd
  • popov895/vlc
  • claucambra/vlc
  • brad/vlc
  • matthewmurua88/vlc
  • Tomas8874/vlc
  • philenotfound/vlc
  • makita-do3/vlc
  • LZXCorp/vlc
  • mar0x/vlc
  • senojetkennedy0102/vlc
  • shaneb243/vlc
  • ahmadbader/vlc
  • rajduttcse26/vlc-audio-filters
  • Juniorzito8415/vlc
  • achernyakov/vlc
  • lucasjetgroup/vlc
  • pupdoggy666/vlc
  • gmde9363/vlc
  • alexnwayne/vlc
  • bahareebrahimi781/vlc
  • hamad633666/vlc
  • umghof3112/vlc
  • joe0199771874/vlc
  • Octocats66666666/vlc
  • jjm_223/vlc
  • btech10110.19/vlc
  • sunnykfc028/vlc-audio-filters
  • loic/vlc
  • nguyenminhducmx1/vlc
  • JanekKrueger/vlc
  • bstubbington2/vlc
  • rcombs/vlc
  • Ordissimo/vlc
  • king7532/vlc
  • noobsauce101/vlc
  • schong0525/vlc
  • myQwil/vlc
  • apisbg91/vlc
  • geeboy0101017/vlc
  • kim.faughey/vlc
  • nurupo/vlc
  • yyusea/vlc
  • 0711235879.khco/vlc
  • ialo/vlc
  • iloveyeye2/vlc
  • gdtdftdqtd/vlc
  • leandroconsiglio/vlc
  • AndyHTML2012/vlc
  • ncz/vlc
  • lucenticus/vlc
  • knr1931/vlc
  • kjoonlee/vlc
  • chandrakant100/vlc-qt
  • johge42/vlc
  • polter/vlc
  • hexchain/vlc
  • Tushwrld/vlc
  • mztea928/vlc
  • jbelloncastro/vlc
  • alvinhochun/vlc
  • ghostpiratecrow/vlc
  • ujjwaltwitx/vlc
  • alexsonarin06/vlc
  • adrianbon76/vlc
  • altsod/vlc
  • damien.lucas44/vlc
  • dmytrivtaisa/vlc
  • utk202/vlc
  • aaxhrj/vlc
  • thomas.hermes/vlc
  • structurenewworldorder/vlc
  • slomo/vlc
  • wantlamy/vlc
  • musc.o3cminc/vlc
  • thebarshablog/vlc
  • kerrick/vlc
  • kratos142518/vlc
  • leogps/vlc
  • vacantron/vlc
  • luna_koly/vlc
  • Ratio2/vlc
  • anuoshemohammad/vlc
  • apsun/vlc
  • aaa1115910/vlc
  • alimotmoyo/vlc
  • Ambossmann/vlc
  • Sam-LearnsToCode/vlc
  • Chilledheart/vlc
  • Labnann/vlc
  • ktcoooot1/vlc
  • mohit-marathe/vlc
  • johnddx/vlc
  • manstabuk/vlc
  • Omar-ahmed314/vlc
  • vineethkm/vlc
  • 9Enemi86/vlc
  • radoslav.m.panteleev/vlc
  • ashishami2002/vlc
  • Corbax/vlc
  • firnasahmed/vlc
  • pelayarmalam4/vlc
  • c0ff330k/vlc
  • shikhindahikar/vlc
  • l342723951/vlc
  • christianschwandner/vlc
  • douniwan5788/vlc
  • 7damian7/vlc
  • ferdnyc/vlc
  • f.ales1/vlc
  • pandagby/vlc
  • BaaBaa/vlc
  • jewe37/vlc
  • w00drow/vlc
  • russelltg/vlc
  • ironicallygod/vlc
  • soumyaDghosh/vlc
  • linzihao1999/vlc
  • deyayush6/vlc
  • mibi88/vlc
  • newabdallah10/vlc
  • jhorbincolombia/vlc
  • rimvihaqueshupto/vlc
  • andrewkhon98/vlc
  • fab78/vlc
  • lapaz17/vlc
  • amanna13/vlc
  • mdakram28/vlc
  • 07jw1980/vlc
  • sohamgupta/vlc
  • Eson-Jia1/vlc
  • Sumou/vlc
  • vikram-kangotra/vlc
  • chalice191/vlc
  • olivercalder/vlc
  • aaasg4001/vlc
  • zipdox/vlc
  • kwizart/vlc
  • Dragon-S/vlc
  • jdemeule/vlc
  • gabriel_lt/vlc
  • locutusofborg/vlc
  • sammirata/vlc-librist
  • another/vlc
  • Benjamin_Loison/vlc
  • ahmedmoselhi/vlc
  • petergaal/vlc
  • huynhsontung/vlc
  • dariusmihut/vlc
  • tvermaashutosh/vlc
  • buti/vlc
  • Niram7777/vlc
  • rohan-here/vlc
  • balaji-sivasakthi/vlc
  • rlindner81/vlc
  • Kakadus/vlc
  • djain/vlc
  • ABBurmeister/vlc
  • craighuggins/vlc
  • orbea/vlc
  • maxos/vlc
  • aakarshmj/vlc
  • kblaschke/vlc
  • ankitm/vlc
  • advait-0/vlc
  • mohak2003/vlc
  • yselkowitz/vlc
  • AZM999/vlc-azm
  • andrey.turkin/vlc
  • Disha-Baghel/vlc
  • nowrep/vlc
  • Apeng/vlc
  • Choucroute_melba/vlc
  • autra/vlc
  • eclipseo/vlc
  • fhuber/vlc
  • olafhering/vlc
  • sdasda7777/vlc
  • 1div0/vlc
  • skosnits/vlc-extended-playlist-support
  • dnicolson/vlc
  • Timshel/vlc
  • octopols/vlc
  • MangalK/vlc
  • nima64/vlc
  • misawai/vlc
  • Alexander-Wilms/vlc
  • Maxime2/vlc-fork-for-visualizer
  • ww/vlc
  • jeske/vlc
  • sgross-emlix/vlc
  • morenonatural/vlc
  • freakingLovesVLC/vlc
  • borisgolovnev/vlc
  • mpromonet/vlc
  • diogo.simao-marques/vlc
  • masstock/vlc
  • pratikpatel8982/vlc
  • hugok79/vlc
  • longervision/vlc
  • abhiudaysurya/vlc
  • rishabhgarg/vlc
  • tumic/vlc
  • cart/vlc
  • shubham442/vlc
  • Aditya692005/vlc
  • sammirata/vlc4
  • syrykh/vlc
  • Vvorcun/macos-new-icon
  • AyaanshC/vlc
  • nasso/vlc
  • Quark/vlc
  • sebastinas/vlc
  • rhstone/vlc
  • talregev/vlc
  • Managor/vlc
  • abdsaber000/vlc
  • falbrechtskirchinger/vlc
405 results
Show changes
Commits on Source (3)
......@@ -106,6 +106,7 @@
6BF5C5011EFE03CF008A9C12 /* VLCHUDStepperCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BF5C5001EFE03CF008A9C12 /* VLCHUDStepperCell.m */; };
6BF5C5041EFE66EF008A9C12 /* VLCHUDTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BF5C5031EFE66EF008A9C12 /* VLCHUDTableView.m */; };
6BF5C5071EFE7E58008A9C12 /* VLCTintedImageButtonCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BF5C5061EFE7E58008A9C12 /* VLCTintedImageButtonCell.m */; };
7D51CC072675FEF100EE18C2 /* VLCRemoteControlService.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D51CC062675FEF100EE18C2 /* VLCRemoteControlService.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
......@@ -681,6 +682,8 @@
6BF5C5031EFE66EF008A9C12 /* VLCHUDTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCHUDTableView.m; sourceTree = "<group>"; };
6BF5C5051EFE7E58008A9C12 /* VLCTintedImageButtonCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCTintedImageButtonCell.h; sourceTree = "<group>"; };
6BF5C5061EFE7E58008A9C12 /* VLCTintedImageButtonCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCTintedImageButtonCell.m; sourceTree = "<group>"; };
7D51CC052675FEF100EE18C2 /* VLCRemoteControlService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCRemoteControlService.h; sourceTree = "<group>"; };
7D51CC062675FEF100EE18C2 /* VLCRemoteControlService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCRemoteControlService.m; sourceTree = "<group>"; };
7D5678EB1D5BA1DC002698F3 /* VLCApplication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCApplication.h; sourceTree = "<group>"; };
7D5678EC1D5BA1DC002698F3 /* VLCApplication.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCApplication.m; sourceTree = "<group>"; };
7D5678EE1D5BA397002698F3 /* VLCMainWindowControlsBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCMainWindowControlsBar.h; sourceTree = "<group>"; };
......@@ -931,6 +934,8 @@
7DF812F41B5599E40052293C /* VLCPLModel.m */,
1C7CB91A1D787E7600388902 /* VLCPopupPanelController.h */,
1C7CB91B1D787E7600388902 /* VLCPopupPanelController.m */,
7D51CC052675FEF100EE18C2 /* VLCRemoteControlService.h */,
7D51CC062675FEF100EE18C2 /* VLCRemoteControlService.m */,
633121CA1B51122700E636DA /* VLCResumeDialogController.h */,
633121CB1B51122700E636DA /* VLCResumeDialogController.m */,
6B13E2A61BC67678001AD24A /* VLCScrollingClipView.h */,
......@@ -1822,6 +1827,7 @@
1C3113A71E508C6900D4DD76 /* VLCLogWindowController.m in Sources */,
6BF5C5071EFE7E58008A9C12 /* VLCTintedImageButtonCell.m in Sources */,
1C3113A91E508C6900D4DD76 /* VLCDocumentController.m in Sources */,
7D51CC072675FEF100EE18C2 /* VLCRemoteControlService.m in Sources */,
1C3113AB1E508C6900D4DD76 /* VLCExtensionsDialogProvider.m in Sources */,
1C3113AD1E508C6900D4DD76 /* VLCExtensionsManager.m in Sources */,
1C3113AF1E508C6900D4DD76 /* VLCFSPanelController.m in Sources */,
......
......@@ -6,7 +6,7 @@ libmacosx_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(guidir)' \
-Wl,-framework,AVFoundation -Wl,-framework,CoreMedia -Wl,-framework,IOKit \
-Wl,-framework,AddressBook -Wl,-framework,WebKit -Wl,-framework,CoreAudio \
-Wl,-framework,SystemConfiguration -Wl,-framework,ScriptingBridge \
-Wl,-framework,QuartzCore
-Wl,-framework,QuartzCore -Wl,-weak_framework,MediaPlayer
if HAVE_SPARKLE
libmacosx_plugin_la_LDFLAGS += -Wl,-framework,Sparkle
......@@ -106,7 +106,8 @@ libmacosx_plugin_la_SOURCES = \
gui/macosx/VLCSliderCell.h gui/macosx/VLCSliderCell.m \
gui/macosx/VLCVolumeSlider.h gui/macosx/VLCVolumeSlider.m \
gui/macosx/VLCVolumeSliderCell.h gui/macosx/VLCVolumeSliderCell.m \
gui/macosx/VLCWrappableTextField.h gui/macosx/VLCWrappableTextField.m
gui/macosx/VLCWrappableTextField.h gui/macosx/VLCWrappableTextField.m \
gui/macosx/VLCRemoteControlService.h gui/macosx/VLCRemoteControlService.m
# PXSourceList sources
libmacosx_plugin_la_SOURCES += \
......
/*****************************************************************************
* CoreInteraction.h: MacOS X interface module
*****************************************************************************
* Copyright (C) 2011-2015 Felix Paul Kühne
* Copyright (C) 2011-2021 Felix Paul Kühne
* $Id$
*
* Authors: Felix Paul Kühne <fkuehne -at- videolan -dot- org>
......@@ -30,13 +30,17 @@
@property (readwrite) int volume;
@property (readonly, nonatomic) float maxVolume;
@property (readwrite) int playbackRate;
@property (readonly) float internalPlaybackRate;
@property (nonatomic, readwrite) BOOL aspectRatioIsLocked;
@property (readonly) int durationOfCurrentPlaylistItem;
@property (readonly) NSURL * URLOfCurrentPlaylistItem;
@property (readonly) NSString * nameOfCurrentPlaylistItem;
@property (nonatomic, readwrite) BOOL mute;
@property (readonly) float currentPlaybackPosition;
@property (readonly) long long currentPlaybackTimeInSeconds;
- (void)playOrPause;
- (void)play;
- (void)pause;
- (void)stop;
- (void)faster;
......@@ -55,6 +59,7 @@
- (void)backwardMedium;
- (void)forwardLong;
- (void)backwardLong;
- (BOOL)seekToTime:(mtime_t)time;
- (void)repeatOne;
- (void)repeatAll;
......
/*****************************************************************************
* CoreInteraction.m: MacOS X interface module
*****************************************************************************
* Copyright (C) 2011-2015 Felix Paul Kühne
* Copyright (C) 2011-2021 Felix Paul Kühne
* $Id$
*
* Authors: Felix Paul Kühne <fkuehne -at- videolan -dot- org>
......@@ -40,6 +40,7 @@
#import "SPMediaKeyTap.h"
#import "AppleRemote.h"
#import "VLCInputManager.h"
#import "CompatibilityFixes.h"
#import "NSSound+VLCAdditions.h"
......@@ -98,15 +99,18 @@ static int BossCallback(vlc_object_t *p_this, const char *psz_var,
if (self) {
intf_thread_t *p_intf = getIntf();
/* init media key support */
b_mediaKeySupport = var_InheritBool(p_intf, "macosx-mediakeys");
if (b_mediaKeySupport) {
_mediaKeyController = [[SPMediaKeyTap alloc] initWithDelegate:self];
/* init media key support on earlier macOS versions
* this feature is covered by VLCRemoteControlService in later releases */
if (!OSX_SIERRA_AND_HIGHER) {
b_mediaKeySupport = var_InheritBool(p_intf, "macosx-mediakeys");
if (b_mediaKeySupport) {
_mediaKeyController = [[SPMediaKeyTap alloc] initWithDelegate:self];
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(coreChangedMediaKeySupportSetting:)
name:VLCMediaKeySupportSettingChangedNotification
object:nil];
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(coreChangedMediaKeySupportSetting:)
name:VLCMediaKeySupportSettingChangedNotification
object:nil];
/* init Apple Remote support */
_remote = [[AppleRemote alloc] init];
......@@ -128,6 +132,12 @@ static int BossCallback(vlc_object_t *p_this, const char *psz_var,
#pragma mark - Playback Controls
- (void)play
{
playlist_t *p_playlist = pl_Get(getIntf());
playlist_Play(p_playlist);
}
- (void)playOrPause
{
input_thread_t *p_input = pl_CurrentInput(getIntf());
......@@ -230,6 +240,19 @@ static int BossCallback(vlc_object_t *p_this, const char *psz_var,
return returnValue;
}
- (float)internalPlaybackRate
{
input_thread_t *p_input_thread = pl_CurrentInput(getIntf());
float rate = 0.;
if (p_input_thread) {
rate = var_GetFloat(p_input_thread, "rate");
vlc_object_release(p_input_thread);
}
return rate;
}
- (void)previous
{
playlist_Prev(pl_Get(getIntf()));
......@@ -331,6 +354,33 @@ static int BossCallback(vlc_object_t *p_this, const char *psz_var,
return o_name;
}
- (long long)currentPlaybackTimeInSeconds
{
input_thread_t *p_input_thread = pl_CurrentInput(getIntf());
long long timeInSeconds = 0;
if (p_input_thread) {
int64_t time = var_GetInteger(p_input_thread, "time");
timeInSeconds = time / CLOCK_FREQ;
vlc_object_release(p_input_thread);
}
return timeInSeconds;
}
- (float)currentPlaybackPosition
{
input_thread_t * p_input_thread = pl_CurrentInput(getIntf());
float position = 0.;
if (p_input_thread) {
position = var_GetFloat(p_input_thread, "position");
vlc_object_release(p_input_thread);
}
return position;
}
- (void)forward
{
//LEGACY SUPPORT
......@@ -349,12 +399,15 @@ static int BossCallback(vlc_object_t *p_this, const char *psz_var,
if (!p_input)
return;
int i_interval = var_InheritInteger( p_input, p_value );
if (i_interval > 0) {
mtime_t val = CLOCK_FREQ * i_interval;
if (!b_value)
val = val * -1;
var_SetInteger( p_input, "time-offset", val );
bool b_seekable = var_GetBool(p_input, "can-seek");
if (b_seekable) {
long long i_interval = var_InheritInteger( p_input, p_value );
if (i_interval > 0) {
mtime_t val = CLOCK_FREQ * i_interval;
if (!b_value)
val = val * -1;
var_SetInteger( p_input, "time-offset", val );
}
}
vlc_object_release(p_input);
}
......@@ -399,6 +452,21 @@ static int BossCallback(vlc_object_t *p_this, const char *psz_var,
[self jumpWithValue:"long-jump-size" forward:NO];
}
- (BOOL)seekToTime:(mtime_t)time
{
input_thread_t * p_input_thread = pl_CurrentInput(getIntf());
if (p_input_thread) {
bool b_seekable = var_GetBool(p_input_thread, "can-seek");
if (b_seekable) {
var_SetInteger(p_input_thread, "time", time);
vlc_object_release(p_input_thread);
return YES;
}
vlc_object_release(p_input_thread);
}
return NO;
}
- (void)shuffle
{
intf_thread_t *p_intf = getIntf();
......
......@@ -26,9 +26,10 @@
#import <IOKit/pwr_mgt/IOPMLib.h> /* for sleep prevention */
@class VLCMain;
extern NSString *VLCPlayerRateChanged;
@interface VLCInputManager : NSObject
- (id)initWithMain:(VLCMain *)o_mainObj;
......
......@@ -34,10 +34,13 @@
#import "VLCResumeDialogController.h"
#import "VLCTrackSynchronizationWindowController.h"
#import "VLCVoutView.h"
#import "VLCRemoteControlService.h"
#import "iTunes.h"
#import "Spotify.h"
NSString *VLCPlayerRateChanged = @"VLCPlayerRateChanged";
@interface VLCInputManager()
- (void)updateMainMenu;
- (void)updateMainWindow;
......@@ -72,6 +75,7 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
break;
case INPUT_EVENT_RATE:
[[[VLCMain sharedInstance] mainMenu] performSelectorOnMainThread:@selector(updatePlaybackRate) withObject: nil waitUntilDone:NO];
[[NSNotificationCenter defaultCenter] postNotificationName:VLCPlayerRateChanged object:nil];
break;
case INPUT_EVENT_POSITION:
......@@ -164,6 +168,8 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
BOOL b_has_spotify_paused;
NSTimer *hasEndedTimer;
VLCRemoteControlService *_remoteControlService;
}
@end
......@@ -190,6 +196,10 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
informInputChangedQueue = dispatch_queue_create("org.videolan.vlc.inputChangedQueue", DISPATCH_QUEUE_SERIAL);
if (@available(macOS 10.12.2, *)) {
_remoteControlService = [[VLCRemoteControlService alloc] init];
[_remoteControlService subscribeToRemoteCommands];
}
}
return self;
}
......@@ -213,6 +223,10 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
p_current_input = NULL;
}
if (@available(macOS 10.12.2, *)) {
[_remoteControlService unsubscribeFromRemoteCommands];
}
var_DelCallback(pl_Get(getIntf()), "input-current", InputThreadChanged, (__bridge void *)self);
#if !OS_OBJECT_USE_OBJC
......@@ -281,6 +295,7 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
{
[[[VLCMain sharedInstance] mainWindow] updateTimeSlider];
[[[VLCMain sharedInstance] statusBarIcon] updateProgress];
[_remoteControlService playbackPositionUpdated];
}
- (void)playbackStatusUpdated
......@@ -338,6 +353,7 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
[self updateMainWindow];
[self sendDistributedNotificationWithUpdatedPlaybackStatus];
[_remoteControlService playbackStateChangedTo:state];
}
// Called when playback has ended and likely no subsequent media will start playing
......@@ -514,6 +530,7 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
{
if (!p_current_input) {
[[[VLCMain sharedInstance] currentMediaInfoPanel] updatePanelWithItem:nil];
[_remoteControlService metaDataChangedForCurrentMediaItem:NULL];
return;
}
......@@ -521,6 +538,7 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
[[[o_main playlist] model] updateItem:p_input_item];
[[[VLCMain sharedInstance] currentMediaInfoPanel] updatePanelWithItem:p_input_item];
[_remoteControlService metaDataChangedForCurrentMediaItem:p_input_item];
}
- (void)updateMainWindow
......
/*****************************************************************************
* VLCRemoteControlService.h: MacOS X interface module
*****************************************************************************
* Copyright (C) 2017, 2018, 2021 VLC authors and VideoLAN
*
* Authors: Carola Nitz <nitz.carola # gmail.com>
* Felix Paul Kühne <fkuehne # videolan.org>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#include <vlc_common.h>
@interface VLCRemoteControlService : NSObject
- (void)subscribeToRemoteCommands;
- (void)unsubscribeFromRemoteCommands;
- (void)playbackPositionUpdated;
- (void)playbackStateChangedTo:(int)state;
- (void)metaDataChangedForCurrentMediaItem:(input_item_t *)p_input_item;
@end
/*****************************************************************************
* VLCRemoteControlService.m: MacOS X interface module
*****************************************************************************
* Copyright (C) 2017-2021 VLC authors and VideoLAN
*
* Authors: Carola Nitz <nitz.carola # gmail.com>
* Felix Paul Kühne <fkuehne # videolan.org>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import <MediaPlayer/MediaPlayer.h>
#import "VLCRemoteControlService.h"
#import "VLCMain.h"
#import "CompatibilityFixes.h"
#import "VLCPlaylist.h"
#import "VLCCoreInteraction.h"
#import "VLCInputManager.h"
#define kVLCSettingPlaybackForwardSkipLength @(60)
#define kVLCSettingPlaybackBackwardSkipLength @(60)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpartial-availability"
@interface VLCRemoteControlService()
{
VLCCoreInteraction *_coreInteraction;
}
@end
@implementation VLCRemoteControlService
static inline NSArray * RemoteCommandCenterCommandsToHandle()
{
MPRemoteCommandCenter *cc = [MPRemoteCommandCenter sharedCommandCenter];
NSMutableArray *commands = [NSMutableArray arrayWithObjects:
cc.playCommand,
cc.pauseCommand,
cc.stopCommand,
cc.togglePlayPauseCommand,
cc.nextTrackCommand,
cc.previousTrackCommand,
cc.skipForwardCommand,
cc.skipBackwardCommand,
cc.changePlaybackPositionCommand,
nil];
return [commands copy];
}
- (instancetype)init
{
self = [super init];
if (self) {
_coreInteraction = [VLCCoreInteraction sharedInstance];
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self
selector:@selector(playbackRateChanged:)
name:VLCPlayerRateChanged
object:nil];
}
return self;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)playbackStateChangedTo:(int)state
{
MPNowPlayingInfoCenter *nowPlayingInfoCenter = [MPNowPlayingInfoCenter defaultCenter];
switch (state) {
case PLAYING_S:
nowPlayingInfoCenter.playbackState = MPNowPlayingPlaybackStatePlaying;
break;
case PAUSE_S:
nowPlayingInfoCenter.playbackState = MPNowPlayingPlaybackStatePaused;
break;
case END_S:
case -1:
nowPlayingInfoCenter.playbackState = MPNowPlayingPlaybackStateStopped;
break;
default:
nowPlayingInfoCenter.playbackState = MPNowPlayingPlaybackStateUnknown;
break;
}
}
- (void)playbackPositionUpdated
{
MPNowPlayingInfoCenter *nowPlayingInfoCenter = [MPNowPlayingInfoCenter defaultCenter];
NSMutableDictionary *currentlyPlayingTrackInfo = [nowPlayingInfoCenter.nowPlayingInfo mutableCopy];
[self setTimeInformationForDictionary:currentlyPlayingTrackInfo];
nowPlayingInfoCenter.nowPlayingInfo = currentlyPlayingTrackInfo;
}
- (void)playbackRateChanged:(NSNotification *)aNotification
{
MPNowPlayingInfoCenter *nowPlayingInfoCenter = [MPNowPlayingInfoCenter defaultCenter];
NSMutableDictionary *currentlyPlayingTrackInfo = [nowPlayingInfoCenter.nowPlayingInfo mutableCopy];
[self setRateInformationForDictionary:currentlyPlayingTrackInfo];
nowPlayingInfoCenter.nowPlayingInfo = currentlyPlayingTrackInfo;
}
- (void)metaDataChangedForCurrentMediaItem:(input_item_t *)p_input_item
{
if (!p_input_item) {
[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = nil;
return;
}
NSMutableDictionary *currentlyPlayingTrackInfo = [NSMutableDictionary dictionary];
[self setTimeInformationForDictionary:currentlyPlayingTrackInfo];
[self setRateInformationForDictionary:currentlyPlayingTrackInfo];
/* fill title info */
char *psz_title = input_item_GetTitle(p_input_item);
if (!psz_title)
psz_title = input_item_GetName(p_input_item);
[currentlyPlayingTrackInfo setValue:toNSStr(psz_title) forKey:MPMediaItemPropertyTitle];
free(psz_title);
char *psz_artist = input_item_GetArtist(p_input_item);
[currentlyPlayingTrackInfo setValue:toNSStr(psz_artist) forKey:MPMediaItemPropertyArtist];
free(psz_artist);
char *psz_albumName = input_item_GetAlbum(p_input_item);
[currentlyPlayingTrackInfo setValue:toNSStr(psz_albumName) forKey:MPMediaItemPropertyAlbumTitle];
free(psz_albumName);
char *psz_trackNumber = input_item_GetTrackNumber(p_input_item);
[currentlyPlayingTrackInfo setValue:[NSNumber numberWithInt:[toNSStr(psz_trackNumber) intValue]] forKey:MPMediaItemPropertyAlbumTrackNumber];
free(psz_trackNumber);
mtime_t duration = input_item_GetDuration(p_input_item) / 1000000;
[currentlyPlayingTrackInfo setValue:[NSNumber numberWithLongLong:duration] forKey:MPMediaItemPropertyPlaybackDuration];
if (duration > 0) {
[currentlyPlayingTrackInfo setValue:[NSNumber numberWithBool:NO] forKey:MPNowPlayingInfoPropertyIsLiveStream];
} else {
[currentlyPlayingTrackInfo setValue:[NSNumber numberWithBool:YES] forKey:MPNowPlayingInfoPropertyIsLiveStream];
}
char *psz_artworkURL = input_item_GetArtworkURL(p_input_item);
if (psz_artworkURL) {
NSString *artworkURL = toNSStr(psz_artworkURL);
if (![artworkURL hasPrefix:@"attachment://"]) {
NSImage *coverArtImage = [[NSImage alloc] initWithContentsOfURL:[NSURL URLWithString:artworkURL]];
if (coverArtImage) {
MPMediaItemArtwork *mpartwork = [[MPMediaItemArtwork alloc] initWithBoundsSize:coverArtImage.size
requestHandler:^NSImage* _Nonnull(CGSize size) {
return coverArtImage;
}];
[currentlyPlayingTrackInfo setValue:mpartwork forKey:MPMediaItemPropertyArtwork];
}
}
}
free(psz_artworkURL);
[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = currentlyPlayingTrackInfo;
}
- (void)setTimeInformationForDictionary:(NSMutableDictionary *)dictionary
{
[dictionary setValue:[NSNumber numberWithLongLong:_coreInteraction.currentPlaybackTimeInSeconds] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
[dictionary setValue:[NSNumber numberWithFloat:_coreInteraction.currentPlaybackPosition] forKey:MPNowPlayingInfoPropertyPlaybackProgress];
}
- (void)setRateInformationForDictionary:(NSMutableDictionary *)dictionary
{
[dictionary setValue:[NSNumber numberWithFloat:_coreInteraction.internalPlaybackRate] forKey:MPNowPlayingInfoPropertyPlaybackRate];
}
- (void)subscribeToRemoteCommands
{
MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
//Enable when you want to support these
commandCenter.ratingCommand.enabled = NO;
commandCenter.likeCommand.enabled = NO;
commandCenter.dislikeCommand.enabled = NO;
commandCenter.bookmarkCommand.enabled = NO;
commandCenter.enableLanguageOptionCommand.enabled = NO;
commandCenter.disableLanguageOptionCommand.enabled = NO;
commandCenter.seekForwardCommand.enabled = NO;
commandCenter.seekBackwardCommand.enabled = NO;
commandCenter.skipForwardCommand.preferredIntervals = @[kVLCSettingPlaybackForwardSkipLength];
commandCenter.skipBackwardCommand.preferredIntervals = @[kVLCSettingPlaybackBackwardSkipLength];
for (MPRemoteCommand *command in RemoteCommandCenterCommandsToHandle()) {
[command addTarget:self action:@selector(remoteCommandEvent:)];
}
}
- (void)unsubscribeFromRemoteCommands
{
[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = nil;
for (MPRemoteCommand *command in RemoteCommandCenterCommandsToHandle()) {
[command removeTarget:self];
}
}
- (MPRemoteCommandHandlerStatus)remoteCommandEvent:(MPRemoteCommandEvent *)event
{
MPRemoteCommandCenter *cc = [MPRemoteCommandCenter sharedCommandCenter];
if (event.command == cc.playCommand) {
[_coreInteraction play];
return MPRemoteCommandHandlerStatusSuccess;
}
if (event.command == cc.pauseCommand) {
[_coreInteraction pause];
return MPRemoteCommandHandlerStatusSuccess;
}
if (event.command == cc.stopCommand) {
[_coreInteraction stop];
return MPRemoteCommandHandlerStatusSuccess;
}
if (event.command == cc.togglePlayPauseCommand) {
[_coreInteraction playOrPause];
return MPRemoteCommandHandlerStatusSuccess;
}
if (event.command == cc.nextTrackCommand) {
[_coreInteraction next];
return MPRemoteCommandHandlerStatusSuccess;
}
if (event.command == cc.previousTrackCommand) {
[_coreInteraction previous];
return MPRemoteCommandHandlerStatusSuccess;
}
if (event.command == cc.skipForwardCommand) {
[_coreInteraction forwardMedium];
return MPRemoteCommandHandlerStatusSuccess;
}
if (event.command == cc.skipBackwardCommand) {
[_coreInteraction backwardMedium];
return MPRemoteCommandHandlerStatusSuccess;
}
if (event.command == cc.changePlaybackPositionCommand) {
MPChangePlaybackPositionCommandEvent *positionEvent = (MPChangePlaybackPositionCommandEvent *)event;
return [_coreInteraction seekToTime:positionEvent.positionTime * 1000000] ? MPRemoteCommandHandlerStatusSuccess : MPRemoteCommandHandlerStatusCommandFailed;
}
if (event.command == cc.changeRepeatModeCommand) {
MPChangeRepeatModeCommandEvent *repeatEvent = (MPChangeRepeatModeCommandEvent *)event;
MPRepeatType repeatType = repeatEvent.repeatType;
switch (repeatType) {
case MPRepeatTypeAll:
[_coreInteraction repeatAll];
break;
case MPRepeatTypeOne:
[_coreInteraction repeatOne];
break;
default:
[_coreInteraction repeatOff];
break;
}
return MPRemoteCommandHandlerStatusSuccess;
}
if (event.command == cc.changeShuffleModeCommand) {
[_coreInteraction shuffle];
return MPRemoteCommandHandlerStatusSuccess;
}
msg_Dbg(getIntf(), "%s Wasn't able to handle remote control event: %s",__PRETTY_FUNCTION__,[event.description UTF8String]);
return MPRemoteCommandHandlerStatusCommandFailed;
}
@end
#pragma clang diagnostic pop