├── .editorconfig ├── .gitattributes ├── .gitignore ├── LICENSE ├── LibVLCSharp.Forms.MediaPlayerElement.sln ├── LibVLCSharp.Forms.MediaPlayerElement ├── LibVLCSharp.Forms.MediaPlayerElement.csproj ├── Platforms │ ├── Android │ │ ├── Platform.cs │ │ └── PowerManager.cs │ ├── WPF │ │ ├── Platform.cs │ │ └── PowerManager.cs │ └── iOS │ │ ├── Platform.cs │ │ └── PowerManager.cs └── Shared │ ├── ChromecastLocator.cs │ ├── Converters │ ├── BufferingProgressToBoolConverter.cs │ └── ObjectToBoolConverter.cs │ ├── Effects │ └── ClickEffect.cs │ ├── IPowerManager.cs │ ├── LifecycleMessage.cs │ ├── MediaPlayerElement.xaml │ ├── MediaPlayerElement.xaml.cs │ ├── PlaybackControls.xaml │ ├── PlaybackControls.xaml.cs │ ├── Resources │ ├── Strings.Designer.cs │ ├── Strings.fr.resx │ └── Strings.resx │ ├── Themes │ ├── Generic.xaml │ └── Generic.xaml.cs │ ├── TimeSpanExtensions.cs │ └── VisualTreeHelper.cs ├── README.md ├── Sample ├── Sample.Android │ ├── Assets │ │ ├── AboutAssets.txt │ │ └── PlaybackControlsIcons.ttf │ ├── MainActivity.cs │ ├── Properties │ │ ├── AndroidManifest.xml │ │ └── AssemblyInfo.cs │ ├── Resources │ │ ├── AboutResources.txt │ │ ├── Resource.designer.cs │ │ ├── layout │ │ │ ├── Tabbar.axml │ │ │ └── Toolbar.axml │ │ ├── mipmap-anydpi-v26 │ │ │ ├── icon.xml │ │ │ └── icon_round.xml │ │ ├── mipmap-hdpi │ │ │ ├── icon.png │ │ │ └── launcher_foreground.png │ │ ├── mipmap-mdpi │ │ │ ├── icon.png │ │ │ └── launcher_foreground.png │ │ ├── mipmap-xhdpi │ │ │ ├── icon.png │ │ │ └── launcher_foreground.png │ │ ├── mipmap-xxhdpi │ │ │ ├── icon.png │ │ │ └── launcher_foreground.png │ │ ├── mipmap-xxxhdpi │ │ │ ├── icon.png │ │ │ └── launcher_foreground.png │ │ └── values │ │ │ ├── colors.xml │ │ │ └── styles.xml │ └── Sample.Android.csproj └── Sample │ ├── App.xaml │ ├── App.xaml.cs │ ├── MainPage.xaml │ ├── MainPage.xaml.cs │ ├── MainViewModel.cs │ ├── Sample.csproj │ └── Sample.xml └── Screenshot.jpeg /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: 2 | http://EditorConfig.org 3 | 4 | # top-most EditorConfig file 5 | root = true 6 | 7 | # Default settings: 8 | # A newline ending every file 9 | # Use 4 spaces as indentation 10 | # Trim trailing whitespace 11 | [*] 12 | guidelines = 150 13 | insert_final_newline = true 14 | indent_style = space 15 | indent_size = 4 16 | 17 | # C# files 18 | [*.cs] 19 | 20 | # New line preferences 21 | csharp_new_line_before_open_brace = all 22 | csharp_new_line_before_else = true 23 | csharp_new_line_before_catch = true 24 | csharp_new_line_before_finally = true 25 | csharp_new_line_before_members_in_object_initializers = true 26 | csharp_new_line_before_members_in_anonymous_types = true 27 | csharp_new_line_within_query_expression_clauses = true 28 | 29 | # Indentation preferences 30 | csharp_indent_block_contents = true 31 | csharp_indent_braces = false 32 | csharp_indent_case_contents = true 33 | csharp_indent_switch_labels = true 34 | csharp_indent_labels = flush_left 35 | 36 | # avoid this. unless absolutely necessary 37 | dotnet_style_qualification_for_field = false:error 38 | dotnet_style_qualification_for_property = false:error 39 | dotnet_style_qualification_for_method = false:error 40 | dotnet_style_qualification_for_event = false:error 41 | 42 | # always use var 43 | csharp_style_var_for_built_in_types = true:error 44 | csharp_style_var_when_type_is_apparent = true:error 45 | csharp_style_var_elsewhere = true:error 46 | 47 | # use language keywords instead of BCL types 48 | dotnet_style_predefined_type_for_locals_parameters_members = true:error 49 | dotnet_style_predefined_type_for_member_access = true:error 50 | 51 | # name all classes, structs, interfaces, enums, properties, methods, events and delegates using PascalCase 52 | dotnet_naming_rule.properties_should_be_pascal_case.severity = error 53 | dotnet_naming_rule.properties_should_be_pascal_case.symbols = members 54 | dotnet_naming_rule.properties_should_be_pascal_case.style = pascal_case_style 55 | 56 | dotnet_naming_symbols.members.applicable_kinds = class,struct,interface,enum,property,method,event,delegate 57 | 58 | dotnet_naming_style.pascal_case_style.capitalization = pascal_case 59 | 60 | #name parameters using camel_case 61 | dotnet_naming_rule.parameters_should_be_camel_case.severity = error 62 | dotnet_naming_rule.parameters_should_be_camel_case.symbols = parameters 63 | dotnet_naming_rule.parameters_should_be_camel_case.style = camel_case_style 64 | 65 | dotnet_naming_symbols.parameters.applicable_kinds = parameter 66 | 67 | dotnet_naming_style.camel_case_style.capitalization = camel_case 68 | 69 | # name all constant fields using PascalCase 70 | dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = error 71 | dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields 72 | dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style 73 | 74 | dotnet_naming_symbols.constant_fields.applicable_kinds = field 75 | dotnet_naming_symbols.constant_fields.required_modifiers = const 76 | 77 | # static fields should not have prefix 78 | dotnet_naming_rule.static_fields_should_have_prefix.severity = error 79 | dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields 80 | dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style 81 | 82 | dotnet_naming_symbols.static_fields.applicable_kinds = field 83 | dotnet_naming_symbols.static_fields.required_modifiers = static 84 | 85 | dotnet_naming_style.static_prefix_style.required_prefix = 86 | dotnet_naming_style.static_prefix_style.capitalization = pascal_case 87 | 88 | # async methods end in Async 89 | dotnet_naming_rule.async_methods_end_in_async.symbols = any_async_methods 90 | dotnet_naming_rule.async_methods_end_in_async.style = end_in_async 91 | dotnet_naming_rule.async_methods_end_in_async.severity = error 92 | 93 | dotnet_naming_symbols.any_async_methods.applicable_kinds = method 94 | dotnet_naming_symbols.any_async_methods.applicable_accessibilities = * 95 | dotnet_naming_symbols.any_async_methods.required_modifiers = async 96 | 97 | dotnet_naming_style.end_in_async.required_suffix = Async 98 | dotnet_naming_style.end_in_async.capitalization = pascal_case 99 | 100 | # Code style defaults 101 | dotnet_sort_system_directives_first = true 102 | csharp_preserve_single_line_blocks = true 103 | csharp_preserve_single_line_statements = false 104 | 105 | # Expression-level preferences 106 | dotnet_style_object_initializer = true:error 107 | dotnet_style_collection_initializer = true:error 108 | dotnet_style_explicit_tuple_names = true:error 109 | dotnet_style_coalesce_expression = true:error 110 | dotnet_style_null_propagation = true:error 111 | 112 | # Expression-bodied members 113 | csharp_style_expression_bodied_methods = false:error 114 | csharp_style_expression_bodied_constructors = false:error 115 | csharp_style_expression_bodied_operators = false:error 116 | csharp_style_expression_bodied_properties = true:error 117 | csharp_style_expression_bodied_indexers = true:error 118 | csharp_style_expression_bodied_accessors = true:error 119 | 120 | # Pattern matching 121 | csharp_style_pattern_matching_over_is_with_cast_check = true:error 122 | csharp_style_pattern_matching_over_as_with_null_check = true:error 123 | csharp_style_inlined_variable_declaration = true:error 124 | 125 | # Null checking preferences 126 | csharp_style_throw_expression = true:error 127 | csharp_style_conditional_delegate_call = true:error 128 | 129 | # Prefers simple default expression 130 | csharp_prefer_simple_default_expression = true:error 131 | 132 | # Space preferences 133 | csharp_space_after_cast = false 134 | csharp_space_after_colon_in_inheritance_clause = true 135 | csharp_space_after_comma = true 136 | csharp_space_after_dot = false 137 | csharp_space_after_keywords_in_control_flow_statements = true 138 | csharp_space_after_semicolon_in_for_statement = true 139 | csharp_space_around_binary_operators = before_and_after 140 | csharp_space_around_declaration_statements = do_not_ignore 141 | csharp_space_before_colon_in_inheritance_clause = true 142 | csharp_space_before_comma = false 143 | csharp_space_before_dot = false 144 | csharp_space_before_open_square_brackets = false 145 | csharp_space_before_semicolon_in_for_statement = false 146 | csharp_space_between_empty_square_brackets = false 147 | csharp_space_between_method_call_empty_parameter_list_parentheses = false 148 | csharp_space_between_method_call_name_and_opening_parenthesis = false 149 | csharp_space_between_method_call_parameter_list_parentheses = false 150 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false 151 | csharp_space_between_method_declaration_name_and_open_parenthesis = false 152 | csharp_space_between_method_declaration_parameter_list_parentheses = false 153 | csharp_space_between_parentheses = false 154 | csharp_space_between_square_brackets = false 155 | 156 | [*.{asm,inc}] 157 | indent_size = 8 158 | 159 | # Xml project files 160 | [*.{csproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj,props,targets,config,nuspec,cmd,json}] 161 | indent_size = 2 162 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.jfm 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | 256 | # CodeRush 257 | .cr/ 258 | 259 | # Python Tools for Visual Studio (PTVS) 260 | __pycache__/ 261 | *.pyc 262 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 2.1, February 1999 3 | 4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | [This is the first released version of the Lesser GPL. It also counts 10 | as the successor of the GNU Library Public License, version 2, hence 11 | the version number 2.1.] 12 | 13 | Preamble 14 | 15 | The licenses for most software are designed to take away your 16 | freedom to share and change it. By contrast, the GNU General Public 17 | Licenses are intended to guarantee your freedom to share and change 18 | free software--to make sure the software is free for all its users. 19 | 20 | This license, the Lesser General Public License, applies to some 21 | specially designated software packages--typically libraries--of the 22 | Free Software Foundation and other authors who decide to use it. You 23 | can use it too, but we suggest you first think carefully about whether 24 | this license or the ordinary General Public License is the better 25 | strategy to use in any particular case, based on the explanations below. 26 | 27 | When we speak of free software, we are referring to freedom of use, 28 | not price. Our General Public Licenses are designed to make sure that 29 | you have the freedom to distribute copies of free software (and charge 30 | for this service if you wish); that you receive source code or can get 31 | it if you want it; that you can change the software and use pieces of 32 | it in new free programs; and that you are informed that you can do 33 | these things. 34 | 35 | To protect your rights, we need to make restrictions that forbid 36 | distributors to deny you these rights or to ask you to surrender these 37 | rights. These restrictions translate to certain responsibilities for 38 | you if you distribute copies of the library or if you modify it. 39 | 40 | For example, if you distribute copies of the library, whether gratis 41 | or for a fee, you must give the recipients all the rights that we gave 42 | you. You must make sure that they, too, receive or can get the source 43 | code. If you link other code with the library, you must provide 44 | complete object files to the recipients, so that they can relink them 45 | with the library after making changes to the library and recompiling 46 | it. And you must show them these terms so they know their rights. 47 | 48 | We protect your rights with a two-step method: (1) we copyright the 49 | library, and (2) we offer you this license, which gives you legal 50 | permission to copy, distribute and/or modify the library. 51 | 52 | To protect each distributor, we want to make it very clear that 53 | there is no warranty for the free library. Also, if the library is 54 | modified by someone else and passed on, the recipients should know 55 | that what they have is not the original version, so that the original 56 | author's reputation will not be affected by problems that might be 57 | introduced by others. 58 | 59 | Finally, software patents pose a constant threat to the existence of 60 | any free program. We wish to make sure that a company cannot 61 | effectively restrict the users of a free program by obtaining a 62 | restrictive license from a patent holder. Therefore, we insist that 63 | any patent license obtained for a version of the library must be 64 | consistent with the full freedom of use specified in this license. 65 | 66 | Most GNU software, including some libraries, is covered by the 67 | ordinary GNU General Public License. This license, the GNU Lesser 68 | General Public License, applies to certain designated libraries, and 69 | is quite different from the ordinary General Public License. We use 70 | this license for certain libraries in order to permit linking those 71 | libraries into non-free programs. 72 | 73 | When a program is linked with a library, whether statically or using 74 | a shared library, the combination of the two is legally speaking a 75 | combined work, a derivative of the original library. The ordinary 76 | General Public License therefore permits such linking only if the 77 | entire combination fits its criteria of freedom. The Lesser General 78 | Public License permits more lax criteria for linking other code with 79 | the library. 80 | 81 | We call this license the "Lesser" General Public License because it 82 | does Less to protect the user's freedom than the ordinary General 83 | Public License. It also provides other free software developers Less 84 | of an advantage over competing non-free programs. These disadvantages 85 | are the reason we use the ordinary General Public License for many 86 | libraries. However, the Lesser license provides advantages in certain 87 | special circumstances. 88 | 89 | For example, on rare occasions, there may be a special need to 90 | encourage the widest possible use of a certain library, so that it becomes 91 | a de-facto standard. To achieve this, non-free programs must be 92 | allowed to use the library. A more frequent case is that a free 93 | library does the same job as widely used non-free libraries. In this 94 | case, there is little to gain by limiting the free library to free 95 | software only, so we use the Lesser General Public License. 96 | 97 | In other cases, permission to use a particular library in non-free 98 | programs enables a greater number of people to use a large body of 99 | free software. For example, permission to use the GNU C Library in 100 | non-free programs enables many more people to use the whole GNU 101 | operating system, as well as its variant, the GNU/Linux operating 102 | system. 103 | 104 | Although the Lesser General Public License is Less protective of the 105 | users' freedom, it does ensure that the user of a program that is 106 | linked with the Library has the freedom and the wherewithal to run 107 | that program using a modified version of the Library. 108 | 109 | The precise terms and conditions for copying, distribution and 110 | modification follow. Pay close attention to the difference between a 111 | "work based on the library" and a "work that uses the library". The 112 | former contains code derived from the library, whereas the latter must 113 | be combined with the library in order to run. 114 | 115 | GNU LESSER GENERAL PUBLIC LICENSE 116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 117 | 118 | 0. This License Agreement applies to any software library or other 119 | program which contains a notice placed by the copyright holder or 120 | other authorized party saying it may be distributed under the terms of 121 | this Lesser General Public License (also called "this License"). 122 | Each licensee is addressed as "you". 123 | 124 | A "library" means a collection of software functions and/or data 125 | prepared so as to be conveniently linked with application programs 126 | (which use some of those functions and data) to form executables. 127 | 128 | The "Library", below, refers to any such software library or work 129 | which has been distributed under these terms. A "work based on the 130 | Library" means either the Library or any derivative work under 131 | copyright law: that is to say, a work containing the Library or a 132 | portion of it, either verbatim or with modifications and/or translated 133 | straightforwardly into another language. (Hereinafter, translation is 134 | included without limitation in the term "modification".) 135 | 136 | "Source code" for a work means the preferred form of the work for 137 | making modifications to it. For a library, complete source code means 138 | all the source code for all modules it contains, plus any associated 139 | interface definition files, plus the scripts used to control compilation 140 | and installation of the library. 141 | 142 | Activities other than copying, distribution and modification are not 143 | covered by this License; they are outside its scope. The act of 144 | running a program using the Library is not restricted, and output from 145 | such a program is covered only if its contents constitute a work based 146 | on the Library (independent of the use of the Library in a tool for 147 | writing it). Whether that is true depends on what the Library does 148 | and what the program that uses the Library does. 149 | 150 | 1. You may copy and distribute verbatim copies of the Library's 151 | complete source code as you receive it, in any medium, provided that 152 | you conspicuously and appropriately publish on each copy an 153 | appropriate copyright notice and disclaimer of warranty; keep intact 154 | all the notices that refer to this License and to the absence of any 155 | warranty; and distribute a copy of this License along with the 156 | Library. 157 | 158 | You may charge a fee for the physical act of transferring a copy, 159 | and you may at your option offer warranty protection in exchange for a 160 | fee. 161 | 162 | 2. You may modify your copy or copies of the Library or any portion 163 | of it, thus forming a work based on the Library, and copy and 164 | distribute such modifications or work under the terms of Section 1 165 | above, provided that you also meet all of these conditions: 166 | 167 | a) The modified work must itself be a software library. 168 | 169 | b) You must cause the files modified to carry prominent notices 170 | stating that you changed the files and the date of any change. 171 | 172 | c) You must cause the whole of the work to be licensed at no 173 | charge to all third parties under the terms of this License. 174 | 175 | d) If a facility in the modified Library refers to a function or a 176 | table of data to be supplied by an application program that uses 177 | the facility, other than as an argument passed when the facility 178 | is invoked, then you must make a good faith effort to ensure that, 179 | in the event an application does not supply such function or 180 | table, the facility still operates, and performs whatever part of 181 | its purpose remains meaningful. 182 | 183 | (For example, a function in a library to compute square roots has 184 | a purpose that is entirely well-defined independent of the 185 | application. Therefore, Subsection 2d requires that any 186 | application-supplied function or table used by this function must 187 | be optional: if the application does not supply it, the square 188 | root function must still compute square roots.) 189 | 190 | These requirements apply to the modified work as a whole. If 191 | identifiable sections of that work are not derived from the Library, 192 | and can be reasonably considered independent and separate works in 193 | themselves, then this License, and its terms, do not apply to those 194 | sections when you distribute them as separate works. But when you 195 | distribute the same sections as part of a whole which is a work based 196 | on the Library, the distribution of the whole must be on the terms of 197 | this License, whose permissions for other licensees extend to the 198 | entire whole, and thus to each and every part regardless of who wrote 199 | it. 200 | 201 | Thus, it is not the intent of this section to claim rights or contest 202 | your rights to work written entirely by you; rather, the intent is to 203 | exercise the right to control the distribution of derivative or 204 | collective works based on the Library. 205 | 206 | In addition, mere aggregation of another work not based on the Library 207 | with the Library (or with a work based on the Library) on a volume of 208 | a storage or distribution medium does not bring the other work under 209 | the scope of this License. 210 | 211 | 3. You may opt to apply the terms of the ordinary GNU General Public 212 | License instead of this License to a given copy of the Library. To do 213 | this, you must alter all the notices that refer to this License, so 214 | that they refer to the ordinary GNU General Public License, version 2, 215 | instead of to this License. (If a newer version than version 2 of the 216 | ordinary GNU General Public License has appeared, then you can specify 217 | that version instead if you wish.) Do not make any other change in 218 | these notices. 219 | 220 | Once this change is made in a given copy, it is irreversible for 221 | that copy, so the ordinary GNU General Public License applies to all 222 | subsequent copies and derivative works made from that copy. 223 | 224 | This option is useful when you wish to copy part of the code of 225 | the Library into a program that is not a library. 226 | 227 | 4. You may copy and distribute the Library (or a portion or 228 | derivative of it, under Section 2) in object code or executable form 229 | under the terms of Sections 1 and 2 above provided that you accompany 230 | it with the complete corresponding machine-readable source code, which 231 | must be distributed under the terms of Sections 1 and 2 above on a 232 | medium customarily used for software interchange. 233 | 234 | If distribution of object code is made by offering access to copy 235 | from a designated place, then offering equivalent access to copy the 236 | source code from the same place satisfies the requirement to 237 | distribute the source code, even though third parties are not 238 | compelled to copy the source along with the object code. 239 | 240 | 5. A program that contains no derivative of any portion of the 241 | Library, but is designed to work with the Library by being compiled or 242 | linked with it, is called a "work that uses the Library". Such a 243 | work, in isolation, is not a derivative work of the Library, and 244 | therefore falls outside the scope of this License. 245 | 246 | However, linking a "work that uses the Library" with the Library 247 | creates an executable that is a derivative of the Library (because it 248 | contains portions of the Library), rather than a "work that uses the 249 | library". The executable is therefore covered by this License. 250 | Section 6 states terms for distribution of such executables. 251 | 252 | When a "work that uses the Library" uses material from a header file 253 | that is part of the Library, the object code for the work may be a 254 | derivative work of the Library even though the source code is not. 255 | Whether this is true is especially significant if the work can be 256 | linked without the Library, or if the work is itself a library. The 257 | threshold for this to be true is not precisely defined by law. 258 | 259 | If such an object file uses only numerical parameters, data 260 | structure layouts and accessors, and small macros and small inline 261 | functions (ten lines or less in length), then the use of the object 262 | file is unrestricted, regardless of whether it is legally a derivative 263 | work. (Executables containing this object code plus portions of the 264 | Library will still fall under Section 6.) 265 | 266 | Otherwise, if the work is a derivative of the Library, you may 267 | distribute the object code for the work under the terms of Section 6. 268 | Any executables containing that work also fall under Section 6, 269 | whether or not they are linked directly with the Library itself. 270 | 271 | 6. As an exception to the Sections above, you may also combine or 272 | link a "work that uses the Library" with the Library to produce a 273 | work containing portions of the Library, and distribute that work 274 | under terms of your choice, provided that the terms permit 275 | modification of the work for the customer's own use and reverse 276 | engineering for debugging such modifications. 277 | 278 | You must give prominent notice with each copy of the work that the 279 | Library is used in it and that the Library and its use are covered by 280 | this License. You must supply a copy of this License. If the work 281 | during execution displays copyright notices, you must include the 282 | copyright notice for the Library among them, as well as a reference 283 | directing the user to the copy of this License. Also, you must do one 284 | of these things: 285 | 286 | a) Accompany the work with the complete corresponding 287 | machine-readable source code for the Library including whatever 288 | changes were used in the work (which must be distributed under 289 | Sections 1 and 2 above); and, if the work is an executable linked 290 | with the Library, with the complete machine-readable "work that 291 | uses the Library", as object code and/or source code, so that the 292 | user can modify the Library and then relink to produce a modified 293 | executable containing the modified Library. (It is understood 294 | that the user who changes the contents of definitions files in the 295 | Library will not necessarily be able to recompile the application 296 | to use the modified definitions.) 297 | 298 | b) Use a suitable shared library mechanism for linking with the 299 | Library. A suitable mechanism is one that (1) uses at run time a 300 | copy of the library already present on the user's computer system, 301 | rather than copying library functions into the executable, and (2) 302 | will operate properly with a modified version of the library, if 303 | the user installs one, as long as the modified version is 304 | interface-compatible with the version that the work was made with. 305 | 306 | c) Accompany the work with a written offer, valid for at 307 | least three years, to give the same user the materials 308 | specified in Subsection 6a, above, for a charge no more 309 | than the cost of performing this distribution. 310 | 311 | d) If distribution of the work is made by offering access to copy 312 | from a designated place, offer equivalent access to copy the above 313 | specified materials from the same place. 314 | 315 | e) Verify that the user has already received a copy of these 316 | materials or that you have already sent this user a copy. 317 | 318 | For an executable, the required form of the "work that uses the 319 | Library" must include any data and utility programs needed for 320 | reproducing the executable from it. However, as a special exception, 321 | the materials to be distributed need not include anything that is 322 | normally distributed (in either source or binary form) with the major 323 | components (compiler, kernel, and so on) of the operating system on 324 | which the executable runs, unless that component itself accompanies 325 | the executable. 326 | 327 | It may happen that this requirement contradicts the license 328 | restrictions of other proprietary libraries that do not normally 329 | accompany the operating system. Such a contradiction means you cannot 330 | use both them and the Library together in an executable that you 331 | distribute. 332 | 333 | 7. You may place library facilities that are a work based on the 334 | Library side-by-side in a single library together with other library 335 | facilities not covered by this License, and distribute such a combined 336 | library, provided that the separate distribution of the work based on 337 | the Library and of the other library facilities is otherwise 338 | permitted, and provided that you do these two things: 339 | 340 | a) Accompany the combined library with a copy of the same work 341 | based on the Library, uncombined with any other library 342 | facilities. This must be distributed under the terms of the 343 | Sections above. 344 | 345 | b) Give prominent notice with the combined library of the fact 346 | that part of it is a work based on the Library, and explaining 347 | where to find the accompanying uncombined form of the same work. 348 | 349 | 8. You may not copy, modify, sublicense, link with, or distribute 350 | the Library except as expressly provided under this License. Any 351 | attempt otherwise to copy, modify, sublicense, link with, or 352 | distribute the Library is void, and will automatically terminate your 353 | rights under this License. However, parties who have received copies, 354 | or rights, from you under this License will not have their licenses 355 | terminated so long as such parties remain in full compliance. 356 | 357 | 9. You are not required to accept this License, since you have not 358 | signed it. However, nothing else grants you permission to modify or 359 | distribute the Library or its derivative works. These actions are 360 | prohibited by law if you do not accept this License. Therefore, by 361 | modifying or distributing the Library (or any work based on the 362 | Library), you indicate your acceptance of this License to do so, and 363 | all its terms and conditions for copying, distributing or modifying 364 | the Library or works based on it. 365 | 366 | 10. Each time you redistribute the Library (or any work based on the 367 | Library), the recipient automatically receives a license from the 368 | original licensor to copy, distribute, link with or modify the Library 369 | subject to these terms and conditions. You may not impose any further 370 | restrictions on the recipients' exercise of the rights granted herein. 371 | You are not responsible for enforcing compliance by third parties with 372 | this License. 373 | 374 | 11. If, as a consequence of a court judgment or allegation of patent 375 | infringement or for any other reason (not limited to patent issues), 376 | conditions are imposed on you (whether by court order, agreement or 377 | otherwise) that contradict the conditions of this License, they do not 378 | excuse you from the conditions of this License. If you cannot 379 | distribute so as to satisfy simultaneously your obligations under this 380 | License and any other pertinent obligations, then as a consequence you 381 | may not distribute the Library at all. For example, if a patent 382 | license would not permit royalty-free redistribution of the Library by 383 | all those who receive copies directly or indirectly through you, then 384 | the only way you could satisfy both it and this License would be to 385 | refrain entirely from distribution of the Library. 386 | 387 | If any portion of this section is held invalid or unenforceable under any 388 | particular circumstance, the balance of the section is intended to apply, 389 | and the section as a whole is intended to apply in other circumstances. 390 | 391 | It is not the purpose of this section to induce you to infringe any 392 | patents or other property right claims or to contest validity of any 393 | such claims; this section has the sole purpose of protecting the 394 | integrity of the free software distribution system which is 395 | implemented by public license practices. Many people have made 396 | generous contributions to the wide range of software distributed 397 | through that system in reliance on consistent application of that 398 | system; it is up to the author/donor to decide if he or she is willing 399 | to distribute software through any other system and a licensee cannot 400 | impose that choice. 401 | 402 | This section is intended to make thoroughly clear what is believed to 403 | be a consequence of the rest of this License. 404 | 405 | 12. If the distribution and/or use of the Library is restricted in 406 | certain countries either by patents or by copyrighted interfaces, the 407 | original copyright holder who places the Library under this License may add 408 | an explicit geographical distribution limitation excluding those countries, 409 | so that distribution is permitted only in or among countries not thus 410 | excluded. In such case, this License incorporates the limitation as if 411 | written in the body of this License. 412 | 413 | 13. The Free Software Foundation may publish revised and/or new 414 | versions of the Lesser General Public License from time to time. 415 | Such new versions will be similar in spirit to the present version, 416 | but may differ in detail to address new problems or concerns. 417 | 418 | Each version is given a distinguishing version number. If the Library 419 | specifies a version number of this License which applies to it and 420 | "any later version", you have the option of following the terms and 421 | conditions either of that version or of any later version published by 422 | the Free Software Foundation. If the Library does not specify a 423 | license version number, you may choose any version ever published by 424 | the Free Software Foundation. 425 | 426 | 14. If you wish to incorporate parts of the Library into other free 427 | programs whose distribution conditions are incompatible with these, 428 | write to the author to ask for permission. For software which is 429 | copyrighted by the Free Software Foundation, write to the Free 430 | Software Foundation; we sometimes make exceptions for this. Our 431 | decision will be guided by the two goals of preserving the free status 432 | of all derivatives of our free software and of promoting the sharing 433 | and reuse of software generally. 434 | 435 | NO WARRANTY 436 | 437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 446 | 447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 456 | DAMAGES. 457 | 458 | END OF TERMS AND CONDITIONS 459 | 460 | How to Apply These Terms to Your New Libraries 461 | 462 | If you develop a new library, and you want it to be of the greatest 463 | possible use to the public, we recommend making it free software that 464 | everyone can redistribute and change. You can do so by permitting 465 | redistribution under these terms (or, alternatively, under the terms of the 466 | ordinary General Public License). 467 | 468 | To apply these terms, attach the following notices to the library. It is 469 | safest to attach them to the start of each source file to most effectively 470 | convey the exclusion of warranty; and each file should have at least the 471 | "copyright" line and a pointer to where the full notice is found. 472 | 473 | 474 | Copyright (C) 475 | 476 | This library is free software; you can redistribute it and/or 477 | modify it under the terms of the GNU Lesser General Public 478 | License as published by the Free Software Foundation; either 479 | version 2.1 of the License, or (at your option) any later version. 480 | 481 | This library is distributed in the hope that it will be useful, 482 | but WITHOUT ANY WARRANTY; without even the implied warranty of 483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 484 | Lesser General Public License for more details. 485 | 486 | You should have received a copy of the GNU Lesser General Public 487 | License along with this library; if not, write to the Free Software 488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 489 | USA 490 | 491 | Also add information on how to contact you by electronic and paper mail. 492 | 493 | You should also get your employer (if you work as a programmer) or your 494 | school, if any, to sign a "copyright disclaimer" for the library, if 495 | necessary. Here is a sample; alter the names: 496 | 497 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 498 | library `Frob' (a library for tweaking knobs) written by James Random 499 | Hacker. 500 | 501 | , 1 April 1990 502 | Ty Coon, President of Vice 503 | 504 | That's all there is to it! 505 | -------------------------------------------------------------------------------- /LibVLCSharp.Forms.MediaPlayerElement.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.489 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibVLCSharp.Forms.MediaPlayerElement", "LibVLCSharp.Forms.MediaPlayerElement\LibVLCSharp.Forms.MediaPlayerElement.csproj", "{46A2F2FE-9D99-4D56-8E82-BA1B5868B3B4}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.Android", "Sample\Sample.Android\Sample.Android.csproj", "{315BB606-A490-4CFB-8DFC-313563C330AE}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample", "Sample\Sample\Sample.csproj", "{5DB0C9A7-06F7-4551-9AAA-39AECCC9D24D}" 11 | EndProject 12 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F2EFCF3E-3E37-4E7F-9EFD-1119FDA16510}" 13 | ProjectSection(SolutionItems) = preProject 14 | .editorconfig = .editorconfig 15 | .gitattributes = .gitattributes 16 | .gitignore = .gitignore 17 | LICENSE = LICENSE 18 | README.md = README.md 19 | Screenshot.jpeg = Screenshot.jpeg 20 | EndProjectSection 21 | EndProject 22 | Global 23 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 24 | Debug|Any CPU = Debug|Any CPU 25 | Release|Any CPU = Release|Any CPU 26 | EndGlobalSection 27 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 28 | {46A2F2FE-9D99-4D56-8E82-BA1B5868B3B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {46A2F2FE-9D99-4D56-8E82-BA1B5868B3B4}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {46A2F2FE-9D99-4D56-8E82-BA1B5868B3B4}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {46A2F2FE-9D99-4D56-8E82-BA1B5868B3B4}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {315BB606-A490-4CFB-8DFC-313563C330AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {315BB606-A490-4CFB-8DFC-313563C330AE}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {315BB606-A490-4CFB-8DFC-313563C330AE}.Debug|Any CPU.Deploy.0 = Debug|Any CPU 35 | {315BB606-A490-4CFB-8DFC-313563C330AE}.Release|Any CPU.ActiveCfg = Release|Any CPU 36 | {315BB606-A490-4CFB-8DFC-313563C330AE}.Release|Any CPU.Build.0 = Release|Any CPU 37 | {315BB606-A490-4CFB-8DFC-313563C330AE}.Release|Any CPU.Deploy.0 = Release|Any CPU 38 | {5DB0C9A7-06F7-4551-9AAA-39AECCC9D24D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {5DB0C9A7-06F7-4551-9AAA-39AECCC9D24D}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {5DB0C9A7-06F7-4551-9AAA-39AECCC9D24D}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {5DB0C9A7-06F7-4551-9AAA-39AECCC9D24D}.Release|Any CPU.Build.0 = Release|Any CPU 42 | EndGlobalSection 43 | GlobalSection(SolutionProperties) = preSolution 44 | HideSolutionNode = FALSE 45 | EndGlobalSection 46 | GlobalSection(ExtensibilityGlobals) = postSolution 47 | SolutionGuid = {81E9D41B-1C31-43E1-8366-4993D0453957} 48 | EndGlobalSection 49 | EndGlobal 50 | -------------------------------------------------------------------------------- /LibVLCSharp.Forms.MediaPlayerElement/LibVLCSharp.Forms.MediaPlayerElement.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0;MonoAndroid81;Xamarin.iOS10;Xamarin.Mac20 5 | LibVLCSharp.Forms 6 | Stéphane Mitermite 7 | Stéphane Mitermite 8 | https://github.com/kakone/VLC.MediaElement/blob/master/LICENSE 9 | https://github.com/kakone/VLC.MediaElement 10 | vlc libvlc mediaplayer mediaplayerelement player video audio 11 | VLC MediaPlayerElement for Xamarin.Forms 12 | 0.1 13 | true 14 | https://github.com/kakone/VLC.MediaElement.git 15 | Git 16 | latest 17 | 18 | 19 | 20 | bin\Debug\LibVLCSharp.Forms.MediaPlayerElement.xml 21 | 22 | 23 | 24 | bin\Release\LibVLCSharp.Forms.MediaPlayerElement.xml 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | True 39 | True 40 | Strings.resx 41 | 42 | 43 | 44 | 45 | 46 | MSBuild:UpdateDesignTimeXaml 47 | 48 | 49 | MSBuild:UpdateDesignTimeXaml 50 | 51 | 52 | ResXFileCodeGenerator 53 | Strings.Designer.cs 54 | 55 | 56 | MSBuild:UpdateDesignTimeXaml 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /LibVLCSharp.Forms.MediaPlayerElement/Platforms/Android/Platform.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Android.App; 3 | using Android.OS; 4 | using static Android.App.Application; 5 | 6 | namespace LibVLCSharp.Forms.Platforms.Android 7 | { 8 | /// 9 | /// To get the current activity. 10 | /// 11 | public static class Platform 12 | { 13 | private class ActivityLifecycleContextListener : Java.Lang.Object, IActivityLifecycleCallbacks 14 | { 15 | private WeakReference CurrentActivity { get; } = new WeakReference(null); 16 | 17 | /// 18 | /// Gets or sets the current activity 19 | /// 20 | public Activity Activity 21 | { 22 | get => CurrentActivity.TryGetTarget(out var a) ? a : null; 23 | set => CurrentActivity.SetTarget(value); 24 | } 25 | 26 | public void OnActivityCreated(Activity activity, Bundle savedInstanceState) 27 | { 28 | Activity = activity; 29 | } 30 | 31 | public void OnActivityDestroyed(Activity activity) 32 | { 33 | } 34 | 35 | public void OnActivityPaused(Activity activity) 36 | { 37 | Activity = activity; 38 | } 39 | 40 | public void OnActivityResumed(Activity activity) 41 | { 42 | Activity = activity; 43 | } 44 | 45 | public void OnActivitySaveInstanceState(Activity activity, Bundle outState) 46 | { 47 | } 48 | 49 | public void OnActivityStarted(Activity activity) 50 | { 51 | } 52 | 53 | public void OnActivityStopped(Activity activity) 54 | { 55 | } 56 | } 57 | 58 | private static ActivityLifecycleContextListener LifecycleListener { get; set; } 59 | 60 | /// 61 | /// Gets the current activity. 62 | /// 63 | public static Activity Activity => LifecycleListener?.Activity; 64 | 65 | /// 66 | /// Sets the activity. 67 | /// 68 | /// Current activity. 69 | public static void Init(Activity activity) 70 | { 71 | var lifecycleListener = LifecycleListener; 72 | if (lifecycleListener == null) 73 | { 74 | lifecycleListener = new ActivityLifecycleContextListener(); 75 | LifecycleListener = lifecycleListener; 76 | activity.Application.RegisterActivityLifecycleCallbacks(lifecycleListener); 77 | } 78 | lifecycleListener.Activity = activity; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /LibVLCSharp.Forms.MediaPlayerElement/Platforms/Android/PowerManager.cs: -------------------------------------------------------------------------------- 1 | using Android.Views; 2 | using LibVLCSharp.Forms.Platforms.Android; 3 | using LibVLCSharp.Forms.Shared; 4 | using Xamarin.Forms; 5 | 6 | [assembly: Dependency(typeof(PowerManager))] 7 | namespace LibVLCSharp.Forms.Platforms.Android 8 | { 9 | /// 10 | /// Power manager. 11 | /// 12 | public class PowerManager : IPowerManager 13 | { 14 | /// 15 | /// Gets or sets a value indicating whether the screen should be kept on. 16 | /// 17 | public bool KeepScreenOn 18 | { 19 | get => (Platform.Activity?.Window?.Attributes?.Flags ?? 0).HasFlag(WindowManagerFlags.KeepScreenOn); 20 | set 21 | { 22 | var window = Platform.Activity?.Window; 23 | if (window != null) 24 | { 25 | if (value) 26 | { 27 | window.AddFlags(WindowManagerFlags.KeepScreenOn); 28 | } 29 | else 30 | { 31 | window.ClearFlags(WindowManagerFlags.KeepScreenOn); 32 | } 33 | } 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /LibVLCSharp.Forms.MediaPlayerElement/Platforms/WPF/Platform.cs: -------------------------------------------------------------------------------- 1 | namespace LibVLCSharp.Forms.Platforms.WPF 2 | { 3 | /// 4 | /// Empty shell used to load the custom renderer assembly. 5 | /// 6 | public static class Platform 7 | { 8 | /// 9 | /// Call this to load the custom renderer assembly. 10 | /// 11 | public static void Init() 12 | { 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /LibVLCSharp.Forms.MediaPlayerElement/Platforms/WPF/PowerManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using LibVLCSharp.Forms.Platforms.WPF; 4 | using LibVLCSharp.Forms.Shared; 5 | using Xamarin.Forms; 6 | 7 | [assembly: Dependency(typeof(PowerManager))] 8 | namespace LibVLCSharp.Forms.Platforms.WPF 9 | { 10 | /// 11 | /// Power manager. 12 | /// 13 | public class PowerManager : IPowerManager 14 | { 15 | [DllImport("kernel32.dll")] 16 | private static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags); 17 | 18 | [Flags] 19 | private enum EXECUTION_STATE : uint 20 | { 21 | ES_AWAYMODE_REQUIRED = 0x00000040, 22 | ES_CONTINUOUS = 0x80000000, 23 | ES_DISPLAY_REQUIRED = 0x00000002, 24 | ES_SYSTEM_REQUIRED = 0x00000001 25 | } 26 | 27 | private bool _keepScreenOn; 28 | /// 29 | /// Gets or sets a value indicating whether the screen should be kept on. 30 | /// 31 | public bool KeepScreenOn 32 | { 33 | get => _keepScreenOn; 34 | set 35 | { 36 | if (value) 37 | { 38 | SetThreadExecutionState(EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS); 39 | } 40 | else 41 | { 42 | SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS); 43 | } 44 | _keepScreenOn = value; 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /LibVLCSharp.Forms.MediaPlayerElement/Platforms/iOS/Platform.cs: -------------------------------------------------------------------------------- 1 | namespace LibVLCSharp.Forms.Platforms.iOS 2 | { 3 | /// 4 | /// Empty shell used to load the custom renderer assembly. 5 | /// 6 | public static class Platform 7 | { 8 | /// 9 | /// Call this to load the custom renderer assembly. 10 | /// 11 | public static void Init() 12 | { 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /LibVLCSharp.Forms.MediaPlayerElement/Platforms/iOS/PowerManager.cs: -------------------------------------------------------------------------------- 1 | using LibVLCSharp.Forms.Platforms.iOS; 2 | using LibVLCSharp.Forms.Shared; 3 | using UIKit; 4 | using Xamarin.Forms; 5 | 6 | [assembly: Dependency(typeof(PowerManager))] 7 | namespace LibVLCSharp.Forms.Platforms.iOS 8 | { 9 | /// 10 | /// Power manager. 11 | /// 12 | public class PowerManager : IPowerManager 13 | { 14 | /// 15 | /// Gets or sets a value indicating whether the screen should be kept on. 16 | /// 17 | public bool KeepScreenOn 18 | { 19 | get => UIApplication.SharedApplication.IdleTimerDisabled; 20 | set => UIApplication.SharedApplication.IdleTimerDisabled = value; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /LibVLCSharp.Forms.MediaPlayerElement/Shared/ChromecastLocator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using LibVLCSharp.Shared; 4 | using Xamarin.Forms; 5 | 6 | namespace LibVLCSharp.Forms.Shared 7 | { 8 | /// 9 | /// Helper class to manage the cast. 10 | /// 11 | public static class ChromecastLocator 12 | { 13 | /// 14 | /// Finds the Chromecast renderers. 15 | /// 16 | /// The instance. 17 | /// An enumerable collection of representing the Chromecast renderers. 18 | public static async Task> FindRenderersAsync(this LibVLC libVLC) 19 | { 20 | var renderers = new List(); 21 | using (var rendererDiscover = new RendererDiscoverer(libVLC, 22 | Device.RuntimePlatform == Device.iOS ? "Bonjour_renderer" : "microdns_renderer")) 23 | { 24 | rendererDiscover.ItemAdded += (sender, e) => renderers.Add(e.RendererItem); 25 | rendererDiscover.Start(); 26 | await Task.Delay(3000); 27 | } 28 | return renderers; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /LibVLCSharp.Forms.MediaPlayerElement/Shared/Converters/BufferingProgressToBoolConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using Xamarin.Forms; 4 | 5 | namespace LibVLCSharp.Forms.Shared.Converters 6 | { 7 | /// 8 | /// Converts a value not equals to 0 and 1 to true. 9 | /// 10 | public class BufferingProgressToBoolConverter : IValueConverter 11 | { 12 | /// 13 | /// Modifies the source data before passing it to the target for display in the UI. 14 | /// 15 | /// The source data being passed to the target. 16 | /// The type of the target property. 17 | /// An optional parameter to be used in the converter logic. 18 | /// The culture of the conversion. 19 | /// true if value is not equals to 0, false otherwise 20 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 21 | { 22 | return value is double d && d != 0 && d != 1; 23 | } 24 | 25 | /// 26 | /// Not implemented 27 | /// 28 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 29 | { 30 | throw new NotImplementedException(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /LibVLCSharp.Forms.MediaPlayerElement/Shared/Converters/ObjectToBoolConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using Xamarin.Forms; 4 | 5 | namespace LibVLCSharp.Forms.Shared.Converters 6 | { 7 | /// 8 | /// Converts not null object to true. 9 | /// 10 | public class ObjectToBoolConverter : IValueConverter 11 | { 12 | /// 13 | /// Modifies the source data before passing it to the target for display in the UI. 14 | /// 15 | /// The source data being passed to the target. 16 | /// The type of the target property. 17 | /// An optional parameter to be used in the converter logic. 18 | /// The culture of the conversion. 19 | /// true if value is not null, false otherwise 20 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 21 | { 22 | return value != null; 23 | } 24 | 25 | /// 26 | /// Not implemented 27 | /// 28 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 29 | { 30 | throw new NotImplementedException(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /LibVLCSharp.Forms.MediaPlayerElement/Shared/Effects/ClickEffect.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace LibVLCSharp.Forms.Shared.Effects 4 | { 5 | /// 6 | /// Click effect. 7 | /// 8 | public class ClickEffect : TriggerAction 9 | { 10 | /// 11 | /// Apply a click effect. 12 | /// 13 | /// The object on which to invoke the trigger action. 14 | protected override async void Invoke(VisualElement sender) 15 | { 16 | await sender.ScaleTo(0.85, 100); 17 | await sender.ScaleTo(1, 50); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /LibVLCSharp.Forms.MediaPlayerElement/Shared/IPowerManager.cs: -------------------------------------------------------------------------------- 1 | namespace LibVLCSharp.Forms.Shared 2 | { 3 | /// 4 | /// Interface for power management. 5 | /// 6 | public interface IPowerManager 7 | { 8 | /// 9 | /// Gets or sets a value indicating whether the screen should be kept on. 10 | /// 11 | bool KeepScreenOn { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /LibVLCSharp.Forms.MediaPlayerElement/Shared/LifecycleMessage.cs: -------------------------------------------------------------------------------- 1 | namespace LibVLCSharp.Forms.Shared 2 | { 3 | /// 4 | /// Lifecycle message 5 | /// 6 | public class LifecycleMessage 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /LibVLCSharp.Forms.MediaPlayerElement/Shared/MediaPlayerElement.xaml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /LibVLCSharp.Forms.MediaPlayerElement/Shared/MediaPlayerElement.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using LibVLCSharp.Shared; 3 | using Xamarin.Forms; 4 | using Xamarin.Forms.Xaml; 5 | 6 | namespace LibVLCSharp.Forms.Shared 7 | { 8 | /// 9 | /// Represents an object that uses a to render audio and video to the display. 10 | /// 11 | [XamlCompilation(XamlCompilationOptions.Compile)] 12 | public partial class MediaPlayerElement : ContentView 13 | { 14 | /// 15 | /// Initializes a new instance of the class. 16 | /// 17 | public MediaPlayerElement() 18 | { 19 | InitializeComponent(); 20 | } 21 | 22 | private bool Initialized { get; set; } 23 | 24 | /// 25 | /// Identifies the dependency property. 26 | /// 27 | public static readonly BindableProperty LibVLCProperty = BindableProperty.Create(nameof(LibVLC), typeof(LibVLC), 28 | typeof(MediaPlayerElement), propertyChanged: LibVLCPropertyChanged); 29 | /// 30 | /// Gets the instance. 31 | /// 32 | public LibVLC LibVLC 33 | { 34 | get => (LibVLC)GetValue(LibVLCProperty); 35 | set => SetValue(LibVLCProperty, value); 36 | } 37 | 38 | /// 39 | /// Identifies the dependency property. 40 | /// 41 | public static readonly BindableProperty MediaPlayerProperty = BindableProperty.Create(nameof(MediaPlayer), 42 | typeof(LibVLCSharp.Shared.MediaPlayer), typeof(MediaPlayerElement), propertyChanged: MediaPlayerPropertyChanged); 43 | /// 44 | /// Gets the instance. 45 | /// 46 | public LibVLCSharp.Shared.MediaPlayer MediaPlayer 47 | { 48 | get => (LibVLCSharp.Shared.MediaPlayer)GetValue(MediaPlayerProperty); 49 | set => SetValue(MediaPlayerProperty, value); 50 | } 51 | 52 | private static readonly BindableProperty PlaybackControlsProperty = BindableProperty.Create(nameof(PlaybackControls), 53 | typeof(PlaybackControls), typeof(MediaPlayerElement), propertyChanged: PlaybackControlsPropertyChanged); 54 | /// 55 | /// Gets or sets the playback controls for the media. 56 | /// 57 | public PlaybackControls PlaybackControls 58 | { 59 | get => (PlaybackControls)GetValue(PlaybackControlsProperty); 60 | set => SetValue(PlaybackControlsProperty, value); 61 | } 62 | 63 | private static readonly BindableProperty VideoViewProperty = BindableProperty.Create(nameof(VideoView), typeof(VideoView), 64 | typeof(MediaPlayerElement), propertyChanged: VideoViewPropertyChanged); 65 | /// 66 | /// Gets or sets the video view. 67 | /// 68 | public VideoView VideoView 69 | { 70 | get => (VideoView)GetValue(VideoViewProperty); 71 | private set => SetValue(VideoViewProperty, value); 72 | } 73 | 74 | private void OnVideoViewChanged(VideoView videoView) 75 | { 76 | if (videoView != null) 77 | { 78 | videoView.MediaPlayer = MediaPlayer; 79 | var playbackControls = PlaybackControls; 80 | if (playbackControls != null) 81 | { 82 | playbackControls.VideoView = videoView; 83 | } 84 | } 85 | } 86 | 87 | private void OnLibVLCChanged(LibVLC libVLC) 88 | { 89 | var playbackControls = PlaybackControls; 90 | if (playbackControls != null) 91 | { 92 | playbackControls.LibVLC = LibVLC; 93 | } 94 | } 95 | 96 | private void OnMediaPlayerChanged(LibVLCSharp.Shared.MediaPlayer mediaPlayer) 97 | { 98 | var videoView = VideoView; 99 | if (videoView != null) 100 | { 101 | videoView.MediaPlayer = mediaPlayer; 102 | } 103 | var playbackControls = PlaybackControls; 104 | if (playbackControls != null) 105 | { 106 | playbackControls.MediaPlayer = mediaPlayer; 107 | } 108 | } 109 | 110 | private void OnPlayControlsChanged(PlaybackControls playbackControls) 111 | { 112 | if (playbackControls != null) 113 | { 114 | playbackControls.MediaPlayer = MediaPlayer; 115 | playbackControls.VideoView = VideoView; 116 | } 117 | } 118 | 119 | private static void VideoViewPropertyChanged(BindableObject bindable, object oldValue, object newValue) 120 | { 121 | ((MediaPlayerElement)bindable).OnVideoViewChanged((VideoView)newValue); 122 | } 123 | 124 | private static void LibVLCPropertyChanged(BindableObject bindable, object oldValue, object newValue) 125 | { 126 | ((MediaPlayerElement)bindable).OnLibVLCChanged((LibVLC)newValue); 127 | } 128 | 129 | private static void MediaPlayerPropertyChanged(BindableObject bindable, object oldValue, object newValue) 130 | { 131 | ((MediaPlayerElement)bindable).OnMediaPlayerChanged((LibVLCSharp.Shared.MediaPlayer)newValue); 132 | } 133 | 134 | private static void PlaybackControlsPropertyChanged(BindableObject bindable, object oldValue, object newValue) 135 | { 136 | ((MediaPlayerElement)bindable).OnPlayControlsChanged((PlaybackControls)newValue); 137 | } 138 | 139 | /// 140 | /// Invoked whenever the of an element is set. 141 | /// Implement this method in order to add behavior when the element is added to a parent. 142 | /// 143 | /// Implementors must call the base method. 144 | protected override void OnParentSet() 145 | { 146 | base.OnParentSet(); 147 | 148 | if (Parent != null && !Initialized) 149 | { 150 | Initialized = true; 151 | 152 | if (VideoView == null) 153 | { 154 | VideoView = new VideoView(); 155 | } 156 | if (PlaybackControls == null) 157 | { 158 | PlaybackControls = new PlaybackControls(); 159 | } 160 | 161 | var application = Application.Current; 162 | application.PageAppearing += PageAppearing; 163 | application.PageDisappearing += PageDisappearing; 164 | } 165 | } 166 | 167 | private void PageAppearing(object sender, Page e) 168 | { 169 | if (e == this.FindAncestor()) 170 | { 171 | MessagingCenter.Subscribe(this, "OnSleep", m => 172 | { 173 | var applicationProperties = Application.Current.Properties; 174 | applicationProperties["VLC_MediaPlayerElement_Position"] = MediaPlayer?.Position; 175 | applicationProperties["VLC_MediaPlayerElement_IsPlaying"] = MediaPlayer?.State == VLCState.Playing; 176 | MediaPlayer?.Stop(); 177 | VideoView = null; 178 | }); 179 | MessagingCenter.Subscribe(this, "OnResume", m => 180 | { 181 | VideoView = new VideoView(); 182 | var mediaPlayer = MediaPlayer; 183 | if (mediaPlayer != null) 184 | { 185 | var applicationProperties = Application.Current.Properties; 186 | if (applicationProperties["VLC_MediaPlayerElement_IsPlaying"] is bool play && play) 187 | { 188 | mediaPlayer.Play(); 189 | mediaPlayer.Position = applicationProperties["VLC_MediaPlayerElement_Position"] is float position ? position : 0; 190 | } 191 | } 192 | }); 193 | } 194 | } 195 | 196 | private void PageDisappearing(object sender, Page e) 197 | { 198 | if (e == this.FindAncestor()) 199 | { 200 | MessagingCenter.Unsubscribe(this, "OnSleep"); 201 | MessagingCenter.Unsubscribe(this, "OnResume"); 202 | } 203 | } 204 | 205 | private async void GestureRecognized(object sender, EventArgs e) 206 | { 207 | await PlaybackControls.FadeInAsync(); 208 | } 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /LibVLCSharp.Forms.MediaPlayerElement/Shared/PlaybackControls.xaml: -------------------------------------------------------------------------------- 1 |  2 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /LibVLCSharp.Forms.MediaPlayerElement/Shared/PlaybackControls.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Resources; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using LibVLCSharp.Forms.Shared.Resources; 8 | using LibVLCSharp.Shared; 9 | using LibVLCSharp.Shared.Structures; 10 | using Xamarin.Forms; 11 | using Xamarin.Forms.Xaml; 12 | 13 | namespace LibVLCSharp.Forms.Shared 14 | { 15 | /// 16 | /// Represents the playback controls for a . 17 | /// 18 | [XamlCompilation(XamlCompilationOptions.Compile)] 19 | public partial class PlaybackControls : TemplatedView 20 | { 21 | private const string AudioSelectionAvailableState = "AudioSelectionAvailable"; 22 | private const string AudioSelectionUnavailableState = "AudioSelectionUnavailable"; 23 | private const string ClosedCaptionsSelectionAvailableState = "ClosedCaptionsSelectionAvailable"; 24 | private const string ClosedCaptionsSelectionUnavailableState = "ClosedCaptionsSelectionUnavailable"; 25 | private const string PlayState = "PlayState"; 26 | private const string PauseState = "PauseState"; 27 | private const string PauseAvailableState = "PauseAvailable"; 28 | private const string PauseUnavailableState = "PauseUnavailable"; 29 | private const string SeekAvailableState = "SeekAvailable"; 30 | private const string SeekUnavailableState = "SeekUnavailable"; 31 | private const string CastAvailableState = "CastAvailable"; 32 | private const string CastUnavailableState = "CastUnavailable"; 33 | 34 | /// 35 | /// Initializes a new instance of class. 36 | /// 37 | public PlaybackControls() 38 | { 39 | InitializeComponent(); 40 | 41 | IconFontFamily = Resources[nameof(IconFontFamily)] as OnPlatform; 42 | ButtonColor = (Color)(Resources[nameof(ButtonColor)] ?? Color.Transparent); 43 | ForeColor = (Color)(Resources[nameof(ForeColor)] ?? Color.White); 44 | MainColor = (Color)(Resources[nameof(MainColor)] ?? Color.Transparent); 45 | AudioTracksSelectionButtonStyle = Resources[nameof(AudioTracksSelectionButtonStyle)] as Style; 46 | BufferingProgressBarStyle = Resources[nameof(BufferingProgressBarStyle)] as Style; 47 | ButtonBarStyle = Resources[nameof(ButtonBarStyle)] as Style; 48 | CastButtonStyle = Resources[nameof(CastButtonStyle)] as Style; 49 | ClosedCaptionsSelectionButtonStyle = Resources[nameof(ClosedCaptionsSelectionButtonStyle)] as Style; 50 | ControlsPanelStyle = Resources[nameof(ControlsPanelStyle)] as Style; 51 | ErrorMessageStyle = Resources[nameof(ErrorMessageStyle)] as Style; 52 | PlayPauseButtonStyle = Resources[nameof(PlayPauseButtonStyle)] as Style; 53 | RemainingTimeLabelStyle = Resources[nameof(RemainingTimeLabelStyle)] as Style; 54 | SeekBarStyle = Resources[nameof(SeekBarStyle)] as Style; 55 | StopButtonStyle = Resources[nameof(StopButtonStyle)] as Style; 56 | ZoomButtonStyle = Resources[nameof(ZoomButtonStyle)] as Style; 57 | 58 | FadeOutTimer = new Timer(obj => FadeOut()); 59 | SeekBarTimer = new Timer(obj => UpdateMediaPlayerPosition()); 60 | 61 | Device.Info.PropertyChanged += (sender, e) => UpdateZoom(); 62 | } 63 | 64 | private Button AudioTracksSelectionButton { get; set; } 65 | private Button CastButton { get; set; } 66 | private Button ClosedCaptionsSelectionButton { get; set; } 67 | private VisualElement ControlsPanel { get; set; } 68 | private Button PlayPauseButton { get; set; } 69 | private Label RemainingTimeLabel { get; set; } 70 | private Slider SeekBar { get; set; } 71 | 72 | private bool Initialized { get; set; } 73 | private IPowerManager PowerManager => DependencyService.Get(); 74 | 75 | private Timer FadeOutTimer { get; } 76 | private bool FadeOutEnabled { get; set; } = true; 77 | private Timer SeekBarTimer { get; set; } 78 | private bool SeekBarTimerEnabled { get; set; } 79 | 80 | /// 81 | /// Identifies the dependency property. 82 | /// 83 | public static readonly BindableProperty IconFontFamilyProperty = BindableProperty.Create(nameof(IconFontFamily), typeof(string), 84 | typeof(PlaybackControls)); 85 | /// 86 | /// Gets or sets the icon font family. 87 | /// 88 | public string IconFontFamily 89 | { 90 | get => (string)GetValue(IconFontFamilyProperty); 91 | set => SetValue(IconFontFamilyProperty, value); 92 | } 93 | 94 | /// 95 | /// Identifies the dependency property. 96 | /// 97 | public static readonly BindableProperty ButtonColorProperty = BindableProperty.Create(nameof(ButtonColor), typeof(Color), 98 | typeof(PlaybackControls)); 99 | /// 100 | /// Gets or sets the button color. 101 | /// 102 | public Color ButtonColor 103 | { 104 | get => (Color)GetValue(ButtonColorProperty); 105 | set => SetValue(ButtonColorProperty, value); 106 | } 107 | 108 | /// 109 | /// Identifies the dependency property. 110 | /// 111 | public static readonly BindableProperty ForeColorProperty = BindableProperty.Create(nameof(ForeColor), typeof(Color), 112 | typeof(PlaybackControls)); 113 | /// 114 | /// Gets or sets the button color. 115 | /// 116 | public Color ForeColor 117 | { 118 | get => (Color)GetValue(ForeColorProperty); 119 | set => SetValue(ForeColorProperty, value); 120 | } 121 | 122 | /// 123 | /// Identifies the dependency property. 124 | /// 125 | public static readonly BindableProperty MainColorProperty = BindableProperty.Create(nameof(MainColor), typeof(Color), 126 | typeof(PlaybackControls)); 127 | /// 128 | /// Gets or sets the main color. 129 | /// 130 | public Color MainColor 131 | { 132 | get => (Color)GetValue(MainColorProperty); 133 | set => SetValue(MainColorProperty, value); 134 | } 135 | 136 | /// 137 | /// Identifies the dependency property. 138 | /// 139 | public static readonly BindableProperty AudioTracksSelectionButtonStyleProperty = BindableProperty.Create( 140 | nameof(AudioTracksSelectionButtonStyle), typeof(Style), typeof(PlaybackControls)); 141 | /// 142 | /// Gets or sets the audio tracks selection button style. 143 | /// 144 | public Style AudioTracksSelectionButtonStyle 145 | { 146 | get => (Style)GetValue(AudioTracksSelectionButtonStyleProperty); 147 | set => SetValue(AudioTracksSelectionButtonStyleProperty, value); 148 | } 149 | 150 | /// 151 | /// Identifies the dependency property. 152 | /// 153 | public static readonly BindableProperty BufferingProgressBarStyleProperty = BindableProperty.Create(nameof(BufferingProgressBarStyle), 154 | typeof(Style), typeof(PlaybackControls)); 155 | /// 156 | /// Gets or sets the controls panel style. 157 | /// 158 | public Style BufferingProgressBarStyle 159 | { 160 | get => (Style)GetValue(BufferingProgressBarStyleProperty); 161 | set => SetValue(BufferingProgressBarStyleProperty, value); 162 | } 163 | 164 | /// 165 | /// Identifies the dependency property. 166 | /// 167 | public static readonly BindableProperty ButtonBarStyleProperty = BindableProperty.Create(nameof(ButtonBarStyle), typeof(Style), 168 | typeof(PlaybackControls)); 169 | /// 170 | /// Gets or sets the button bar style. 171 | /// 172 | public Style ButtonBarStyle 173 | { 174 | get => (Style)GetValue(ButtonBarStyleProperty); 175 | set => SetValue(ButtonBarStyleProperty, value); 176 | } 177 | 178 | /// 179 | /// Identifies the dependency property. 180 | /// 181 | public static readonly BindableProperty CastButtonStyleProperty = BindableProperty.Create(nameof(CastButtonStyle), typeof(Style), 182 | typeof(PlaybackControls)); 183 | /// 184 | /// Gets or sets the cast button style. 185 | /// 186 | public Style CastButtonStyle 187 | { 188 | get => (Style)GetValue(CastButtonStyleProperty); 189 | set => SetValue(CastButtonStyleProperty, value); 190 | } 191 | 192 | /// 193 | /// Identifies the dependency property. 194 | /// 195 | public static readonly BindableProperty ClosedCaptionsSelectionButtonStyleProperty = BindableProperty.Create( 196 | nameof(ClosedCaptionsSelectionButtonStyle), typeof(Style), typeof(PlaybackControls)); 197 | /// 198 | /// Gets or sets the closed captions selection button style. 199 | /// 200 | public Style ClosedCaptionsSelectionButtonStyle 201 | { 202 | get => (Style)GetValue(ClosedCaptionsSelectionButtonStyleProperty); 203 | set => SetValue(ClosedCaptionsSelectionButtonStyleProperty, value); 204 | } 205 | 206 | /// 207 | /// Identifies the dependency property. 208 | /// 209 | public static readonly BindableProperty ControlsPanelStyleProperty = BindableProperty.Create(nameof(ControlsPanelStyle), typeof(Style), 210 | typeof(PlaybackControls)); 211 | /// 212 | /// Gets or sets the controls panel style. 213 | /// 214 | public Style ControlsPanelStyle 215 | { 216 | get => (Style)GetValue(ControlsPanelStyleProperty); 217 | set => SetValue(ControlsPanelStyleProperty, value); 218 | } 219 | 220 | /// 221 | /// Identifies the dependency property. 222 | /// 223 | public static readonly BindableProperty ErrorMessageStyleProperty = BindableProperty.Create(nameof(ErrorMessageStyle), typeof(Style), 224 | typeof(PlaybackControls)); 225 | /// 226 | /// Gets or sets the error message style. 227 | /// 228 | public Style ErrorMessageStyle 229 | { 230 | get => (Style)GetValue(ErrorMessageStyleProperty); 231 | set => SetValue(ErrorMessageStyleProperty, value); 232 | } 233 | 234 | /// 235 | /// Identifies the dependency property. 236 | /// 237 | public static readonly BindableProperty PlayPauseButtonStyleProperty = BindableProperty.Create(nameof(PlayPauseButtonStyle), typeof(Style), 238 | typeof(PlaybackControls)); 239 | /// 240 | /// Gets or sets the play/pause button style. 241 | /// 242 | public Style PlayPauseButtonStyle 243 | { 244 | get => (Style)GetValue(PlayPauseButtonStyleProperty); 245 | set => SetValue(PlayPauseButtonStyleProperty, value); 246 | } 247 | 248 | /// 249 | /// Identifies the dependency property. 250 | /// 251 | public static readonly BindableProperty RemainingTimeLabelStyleProperty = BindableProperty.Create(nameof(RemainingTimeLabelStyle), 252 | typeof(Style), typeof(PlaybackControls)); 253 | /// 254 | /// Gets or sets the remaining time label style. 255 | /// 256 | public Style RemainingTimeLabelStyle 257 | { 258 | get => (Style)GetValue(RemainingTimeLabelStyleProperty); 259 | set => SetValue(RemainingTimeLabelStyleProperty, value); 260 | } 261 | 262 | /// 263 | /// Identifies the dependency property. 264 | /// 265 | public static readonly BindableProperty SeekBarStyleProperty = BindableProperty.Create(nameof(SeekBarStyle), typeof(Style), 266 | typeof(PlaybackControls)); 267 | /// 268 | /// Gets or sets the seek bar style. 269 | /// 270 | public Style SeekBarStyle 271 | { 272 | get => (Style)GetValue(SeekBarStyleProperty); 273 | set => SetValue(SeekBarStyleProperty, value); 274 | } 275 | 276 | /// 277 | /// Identifies the dependency property. 278 | /// 279 | public static readonly BindableProperty StopButtonStyleProperty = BindableProperty.Create(nameof(StopButtonStyle), typeof(Style), 280 | typeof(PlaybackControls)); 281 | /// 282 | /// Gets or sets the stop button style. 283 | /// 284 | public Style StopButtonStyle 285 | { 286 | get => (Style)GetValue(StopButtonStyleProperty); 287 | set => SetValue(StopButtonStyleProperty, value); 288 | } 289 | 290 | /// 291 | /// Identifies the dependency property. 292 | /// 293 | public static readonly BindableProperty ZoomButtonStyleProperty = BindableProperty.Create(nameof(ZoomButtonStyle), typeof(Style), 294 | typeof(PlaybackControls)); 295 | /// 296 | /// Gets or sets the zoom button style. 297 | /// 298 | public Style ZoomButtonStyle 299 | { 300 | get => (Style)GetValue(ZoomButtonStyleProperty); 301 | set => SetValue(ZoomButtonStyleProperty, value); 302 | } 303 | 304 | /// 305 | /// Identifies the dependency property. 306 | /// 307 | public static readonly BindableProperty ButtonBarStartAreaProperty = BindableProperty.Create(nameof(ButtonBarStartArea), typeof(View), 308 | typeof(PlaybackControls)); 309 | /// 310 | /// Gets or sets the view in the button bar start area. 311 | /// 312 | public View ButtonBarStartArea 313 | { 314 | get => (View)GetValue(ButtonBarStartAreaProperty); 315 | set => SetValue(ButtonBarStartAreaProperty, value); 316 | } 317 | 318 | /// 319 | /// Identifies the dependency property. 320 | /// 321 | public static readonly BindableProperty ButtonBarEndAreaProperty = BindableProperty.Create(nameof(ButtonBarEndArea), typeof(View), 322 | typeof(PlaybackControls)); 323 | /// 324 | /// Gets or sets the view in the button bar end area. 325 | /// 326 | public View ButtonBarEndArea 327 | { 328 | get => (View)GetValue(ButtonBarEndAreaProperty); 329 | set => SetValue(ButtonBarEndAreaProperty, value); 330 | } 331 | 332 | /// 333 | /// Identifies the dependency property. 334 | /// 335 | public static readonly BindableProperty LibVLCProperty = BindableProperty.Create(nameof(LibVLC), typeof(LibVLC), typeof(PlaybackControls), 336 | propertyChanged: LibVLCPropertyChanged); 337 | /// 338 | /// Gets or sets the instance. 339 | /// 340 | public LibVLC LibVLC 341 | { 342 | get => (LibVLC)GetValue(LibVLCProperty); 343 | set => SetValue(LibVLCProperty, value); 344 | } 345 | 346 | /// 347 | /// Identifies the dependency property. 348 | /// 349 | public static readonly BindableProperty MediaPlayerProperty = BindableProperty.Create(nameof(MediaPlayer), 350 | typeof(LibVLCSharp.Shared.MediaPlayer), typeof(PlaybackControls), propertyChanged: MediaPlayerPropertyChanged); 351 | /// 352 | /// Gets or sets the instance. 353 | /// 354 | public LibVLCSharp.Shared.MediaPlayer MediaPlayer 355 | { 356 | get => (LibVLCSharp.Shared.MediaPlayer)GetValue(MediaPlayerProperty); 357 | set => SetValue(MediaPlayerProperty, value); 358 | } 359 | 360 | /// 361 | /// Identifies the dependency property. 362 | /// 363 | public static readonly BindableProperty BufferingProgressProperty = BindableProperty.Create(nameof(BufferingProgress), typeof(double), 364 | typeof(PlaybackControls)); 365 | /// 366 | /// Gets or sets a value corresponding to the buffering progress. 367 | /// 368 | public double BufferingProgress 369 | { 370 | get => (double)GetValue(BufferingProgressProperty); 371 | set => SetValue(BufferingProgressProperty, value); 372 | } 373 | 374 | /// 375 | /// Identifies the dependency property. 376 | /// 377 | public static readonly BindableProperty ErrorMessageProperty = BindableProperty.Create(nameof(ErrorMessage), typeof(string), 378 | typeof(PlaybackControls)); 379 | /// 380 | /// Gets the last error message. 381 | /// 382 | public string ErrorMessage 383 | { 384 | get => (string)GetValue(ErrorMessageProperty); 385 | private set => SetValue(ErrorMessageProperty, value); 386 | } 387 | 388 | /// 389 | /// Identifies the dependency property. 390 | /// 391 | public static readonly BindableProperty KeepScreenOnProperty = BindableProperty.Create(nameof(KeepScreenOn), typeof(bool), 392 | typeof(PlaybackControls), true, propertyChanged: KeepScreenOnPropertyChanged); 393 | /// 394 | /// Gets or sets a value indicating whether the screen must be kept on when playing. 395 | /// 396 | public bool KeepScreenOn 397 | { 398 | get => (bool)GetValue(KeepScreenOnProperty); 399 | set => SetValue(KeepScreenOnProperty, value); 400 | } 401 | 402 | /// 403 | /// Identifies the dependency property. 404 | /// 405 | public static readonly BindableProperty PositionProperty = BindableProperty.Create(nameof(Position), typeof(TimeSpan), 406 | typeof(PlaybackControls)); 407 | /// 408 | /// Gets or sets the playback position within the media. 409 | /// 410 | public TimeSpan Position 411 | { 412 | get => (TimeSpan)GetValue(PositionProperty); 413 | set => SetValue(PositionProperty, value); 414 | } 415 | 416 | /// 417 | /// Identifies the dependency property. 418 | /// 419 | public static readonly BindableProperty ResourceManagerProperty = BindableProperty.Create(nameof(ResourceManager), typeof(ResourceManager), 420 | typeof(PlaybackControls)); 421 | /// 422 | /// Gets or sets the resource manager to localize strings. 423 | /// 424 | public ResourceManager ResourceManager 425 | { 426 | get => (ResourceManager)GetValue(ResourceManagerProperty) ?? Strings.ResourceManager; 427 | set => SetValue(ResourceManagerProperty, value); 428 | } 429 | 430 | /// 431 | /// Identifies the dependency property. 432 | /// 433 | public static readonly BindableProperty ShowAndHideAutomaticallyProperty = BindableProperty.Create(nameof(ShowAndHideAutomatically), 434 | typeof(bool), typeof(PlaybackControls), true); 435 | /// 436 | /// Gets or sets a value that indicates whether the controls are shown and hidden automatically. 437 | /// 438 | public bool ShowAndHideAutomatically 439 | { 440 | get => (bool)GetValue(ShowAndHideAutomaticallyProperty); 441 | set => SetValue(ShowAndHideAutomaticallyProperty, value); 442 | } 443 | 444 | /// 445 | /// Identifies the dependency property. 446 | /// 447 | public static readonly BindableProperty VideoViewProperty = BindableProperty.Create(nameof(VideoView), typeof(VideoView), 448 | typeof(PlaybackControls), propertyChanged: VideoViewPropertyChanged); 449 | /// 450 | /// Gets or sets the associated . 451 | /// 452 | /// It is only useful to set this property for the zoom feature. 453 | public VideoView VideoView 454 | { 455 | get => (VideoView)GetValue(VideoViewProperty); 456 | set => SetValue(VideoViewProperty, value); 457 | } 458 | 459 | /// 460 | /// Identifies the dependency property. 461 | /// 462 | public static readonly BindableProperty ZoomProperty = BindableProperty.Create(nameof(Zoom), typeof(bool), typeof(PlaybackControls), 463 | propertyChanged: ZoomPropertyChanged); 464 | /// 465 | /// Gets or sets a value indicating whether the video is zoomed. 466 | /// 467 | public bool Zoom 468 | { 469 | get => (bool)GetValue(ZoomProperty); 470 | set => SetValue(ZoomProperty, value); 471 | } 472 | 473 | /// 474 | /// Identifies the dependency property. 475 | /// 476 | public static readonly BindableProperty IsAudioTracksSelectionButtonVisibleProperty = BindableProperty.Create( 477 | nameof(IsAudioTracksSelectionButtonVisible), typeof(bool), typeof(PlaybackControls), true, 478 | propertyChanged: IsAudioTracksSelectionButtonVisiblePropertyChanged); 479 | /// 480 | /// Gets or sets a value indicating whether the audio tracks selection button is shown. 481 | /// 482 | public bool IsAudioTracksSelectionButtonVisible 483 | { 484 | get => (bool)GetValue(IsAudioTracksSelectionButtonVisibleProperty); 485 | set => SetValue(IsAudioTracksSelectionButtonVisibleProperty, value); 486 | } 487 | 488 | /// 489 | /// Identifies the dependency property. 490 | /// 491 | public static readonly BindableProperty IsCastButtonVisibleProperty = BindableProperty.Create(nameof(IsCastButtonVisible), typeof(bool), 492 | typeof(PlaybackControls), true, propertyChanged: IsCastButtonVisiblePropertyChanged); 493 | /// 494 | /// Gets or sets a value indicating whether the cast button is shown. 495 | /// 496 | public bool IsCastButtonVisible 497 | { 498 | get => (bool)GetValue(IsCastButtonVisibleProperty); 499 | set => SetValue(IsCastButtonVisibleProperty, value); 500 | } 501 | 502 | /// 503 | /// Identifies the dependency property. 504 | /// 505 | public static readonly BindableProperty IsClosedCaptionsSelectionButtonVisibleProperty = BindableProperty.Create( 506 | nameof(IsClosedCaptionsSelectionButtonVisible), typeof(bool), typeof(PlaybackControls), true, 507 | propertyChanged: IsClosedCaptionsSelectionButtonVisiblePropertyChanged); 508 | /// 509 | /// Gets or sets a value indicating whether the closed captions selection button is shown. 510 | /// 511 | public bool IsClosedCaptionsSelectionButtonVisible 512 | { 513 | get => (bool)GetValue(IsClosedCaptionsSelectionButtonVisibleProperty); 514 | set => SetValue(IsClosedCaptionsSelectionButtonVisibleProperty, value); 515 | } 516 | 517 | /// 518 | /// Identifies the dependency property. 519 | /// 520 | public static readonly BindableProperty IsPlayPauseButtonVisibleProperty = BindableProperty.Create(nameof(IsPlayPauseButtonVisible), 521 | typeof(bool), typeof(PlaybackControls), true, propertyChanged: IsPlayPauseButtonVisiblePropertyChanged); 522 | /// 523 | /// Gets or sets a value indicating whether the play/pause button is shown. 524 | /// 525 | public bool IsPlayPauseButtonVisible 526 | { 527 | get => (bool)GetValue(IsPlayPauseButtonVisibleProperty); 528 | set => SetValue(IsPlayPauseButtonVisibleProperty, value); 529 | } 530 | 531 | /// 532 | /// Identifies the dependency property. 533 | /// 534 | public static readonly BindableProperty IsSeekEnabledProperty = BindableProperty.Create(nameof(IsSeekEnabled), typeof(bool), 535 | typeof(PlaybackControls), true); 536 | /// 537 | /// Gets or sets a value that indicates whether a user can use the seek bar to find a location in the media. 538 | /// 539 | public bool IsSeekEnabled 540 | { 541 | get => (bool)GetValue(IsSeekEnabledProperty); 542 | set => SetValue(IsSeekEnabledProperty, value); 543 | } 544 | 545 | /// 546 | /// Identifies the dependency property. 547 | /// 548 | public static readonly BindableProperty IsSeekBarVisibleProperty = BindableProperty.Create(nameof(IsSeekBarVisible), typeof(bool), 549 | typeof(PlaybackControls), true); 550 | /// 551 | /// Gets or sets a value that indicates whether the seek bar is shown. 552 | /// 553 | public bool IsSeekBarVisible 554 | { 555 | get => (bool)GetValue(IsSeekBarVisibleProperty); 556 | set => SetValue(IsSeekBarVisibleProperty, value); 557 | } 558 | 559 | /// 560 | /// Identifies the dependency property. 561 | /// 562 | public static readonly BindableProperty IsStopButtonVisibleProperty = BindableProperty.Create(nameof(IsStopButtonVisible), typeof(bool), 563 | typeof(PlaybackControls)); 564 | /// 565 | /// Gets or sets a value that indicates whether the stop button is shown. 566 | /// 567 | public bool IsStopButtonVisible 568 | { 569 | get => (bool)GetValue(IsStopButtonVisibleProperty); 570 | set => SetValue(IsStopButtonVisibleProperty, value); 571 | } 572 | 573 | /// 574 | /// Identifies the dependency property. 575 | /// 576 | public static readonly BindableProperty IsZoomButtonVisibleProperty = BindableProperty.Create(nameof(IsZoomButtonVisible), 577 | typeof(bool), typeof(PlaybackControls), true); 578 | /// 579 | /// Gets or sets a value indicating whether the zoom button is shown. 580 | /// 581 | public bool IsZoomButtonVisible 582 | { 583 | get => (bool)GetValue(IsZoomButtonVisibleProperty); 584 | set => SetValue(IsZoomButtonVisibleProperty, value); 585 | } 586 | 587 | /// 588 | /// Called when the property has changed. 589 | /// 590 | protected override void OnParentSet() 591 | { 592 | base.OnParentSet(); 593 | if (Parent != null && !Initialized) 594 | { 595 | Initialized = true; 596 | OnApplyTemplate(); 597 | UpdateCastAvailability(); 598 | Reset(); 599 | } 600 | } 601 | 602 | private void OnApplyTemplate() 603 | { 604 | AudioTracksSelectionButton = SetClickEventHandler(nameof(AudioTracksSelectionButton), AudioTracksSelectionButton_Clicked, true); 605 | CastButton = SetClickEventHandler(nameof(CastButton), CastButton_Clicked); 606 | ClosedCaptionsSelectionButton = SetClickEventHandler(nameof(ClosedCaptionsSelectionButton), ClosedCaptionsSelectionButton_Clicked, 607 | true); 608 | PlayPauseButton = SetClickEventHandler(nameof(PlayPauseButton), PlayPauseButton_Clicked); 609 | SetClickEventHandler("StopButton", StopButton_Clicked, true); 610 | SetClickEventHandler("ZoomButton", ZoomButton_Clicked, true); 611 | ControlsPanel = this.FindChild(nameof(ControlsPanel)); 612 | SeekBar = this.FindChild(nameof(SeekBar)); 613 | RemainingTimeLabel = this.FindChild