@ -1,3 +1,19 @@ |
|||||||
# oemProject |
# README |
||||||
|
|
||||||
一键打包生成oem项目exe |
## About |
||||||
|
|
||||||
|
This is the official Wails Vue template. |
||||||
|
|
||||||
|
You can configure the project by editing `wails.json`. More information about the project settings can be found |
||||||
|
here: https://wails.io/docs/reference/project-config |
||||||
|
|
||||||
|
## Live Development |
||||||
|
|
||||||
|
To run in live development mode, run `wails dev` in the project directory. This will run a Vite development |
||||||
|
server that will provide very fast hot reload of your frontend changes. If you want to develop in a browser |
||||||
|
and have access to your Go methods, there is also a dev server that runs on http://localhost:34115. Connect |
||||||
|
to this in your browser, and you can call your Go code from devtools. |
||||||
|
|
||||||
|
## Building |
||||||
|
|
||||||
|
To build a redistributable, production mode package, use `wails build`. |
||||||
|
|||||||
@ -0,0 +1,7 @@ |
|||||||
|
package main |
||||||
|
|
||||||
|
// App struct
|
||||||
|
// type App struct {
|
||||||
|
// ctx context.Context
|
||||||
|
// }
|
||||||
|
|
||||||
@ -0,0 +1,35 @@ |
|||||||
|
# Build Directory |
||||||
|
|
||||||
|
The build directory is used to house all the build files and assets for your application. |
||||||
|
|
||||||
|
The structure is: |
||||||
|
|
||||||
|
* bin - Output directory |
||||||
|
* darwin - macOS specific files |
||||||
|
* windows - Windows specific files |
||||||
|
|
||||||
|
## Mac |
||||||
|
|
||||||
|
The `darwin` directory holds files specific to Mac builds. |
||||||
|
These may be customised and used as part of the build. To return these files to the default state, simply delete them |
||||||
|
and |
||||||
|
build with `wails build`. |
||||||
|
|
||||||
|
The directory contains the following files: |
||||||
|
|
||||||
|
- `Info.plist` - the main plist file used for Mac builds. It is used when building using `wails build`. |
||||||
|
- `Info.dev.plist` - same as the main plist file but used when building using `wails dev`. |
||||||
|
|
||||||
|
## Windows |
||||||
|
|
||||||
|
The `windows` directory contains the manifest and rc files used when building with `wails build`. |
||||||
|
These may be customised for your application. To return these files to the default state, simply delete them and |
||||||
|
build with `wails build`. |
||||||
|
|
||||||
|
- `icon.ico` - The icon used for the application. This is used when building using `wails build`. If you wish to |
||||||
|
use a different icon, simply replace this file with your own. If it is missing, a new `icon.ico` file |
||||||
|
will be created using the `appicon.png` file in the build directory. |
||||||
|
- `installer/*` - The files used to create the Windows installer. These are used when building using `wails build`. |
||||||
|
- `info.json` - Application details used for Windows builds. The data here will be used by the Windows installer, |
||||||
|
as well as the application itself (right click the exe -> properties -> details) |
||||||
|
- `wails.exe.manifest` - The main application manifest file. |
||||||
|
After Width: | Height: | Size: 130 KiB |
@ -0,0 +1,68 @@ |
|||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
||||||
|
<plist version="1.0"> |
||||||
|
<dict> |
||||||
|
<key>CFBundlePackageType</key> |
||||||
|
<string>APPL</string> |
||||||
|
<key>CFBundleName</key> |
||||||
|
<string>{{.Info.ProductName}}</string> |
||||||
|
<key>CFBundleExecutable</key> |
||||||
|
<string>{{.Name}}</string> |
||||||
|
<key>CFBundleIdentifier</key> |
||||||
|
<string>com.wails.{{.Name}}</string> |
||||||
|
<key>CFBundleVersion</key> |
||||||
|
<string>{{.Info.ProductVersion}}</string> |
||||||
|
<key>CFBundleGetInfoString</key> |
||||||
|
<string>{{.Info.Comments}}</string> |
||||||
|
<key>CFBundleShortVersionString</key> |
||||||
|
<string>{{.Info.ProductVersion}}</string> |
||||||
|
<key>CFBundleIconFile</key> |
||||||
|
<string>iconfile</string> |
||||||
|
<key>LSMinimumSystemVersion</key> |
||||||
|
<string>10.13.0</string> |
||||||
|
<key>NSHighResolutionCapable</key> |
||||||
|
<string>true</string> |
||||||
|
<key>NSHumanReadableCopyright</key> |
||||||
|
<string>{{.Info.Copyright}}</string> |
||||||
|
{{if .Info.FileAssociations}} |
||||||
|
<key>CFBundleDocumentTypes</key> |
||||||
|
<array> |
||||||
|
{{range .Info.FileAssociations}} |
||||||
|
<dict> |
||||||
|
<key>CFBundleTypeExtensions</key> |
||||||
|
<array> |
||||||
|
<string>{{.Ext}}</string> |
||||||
|
</array> |
||||||
|
<key>CFBundleTypeName</key> |
||||||
|
<string>{{.Name}}</string> |
||||||
|
<key>CFBundleTypeRole</key> |
||||||
|
<string>{{.Role}}</string> |
||||||
|
<key>CFBundleTypeIconFile</key> |
||||||
|
<string>{{.IconName}}</string> |
||||||
|
</dict> |
||||||
|
{{end}} |
||||||
|
</array> |
||||||
|
{{end}} |
||||||
|
{{if .Info.Protocols}} |
||||||
|
<key>CFBundleURLTypes</key> |
||||||
|
<array> |
||||||
|
{{range .Info.Protocols}} |
||||||
|
<dict> |
||||||
|
<key>CFBundleURLName</key> |
||||||
|
<string>com.wails.{{.Scheme}}</string> |
||||||
|
<key>CFBundleURLSchemes</key> |
||||||
|
<array> |
||||||
|
<string>{{.Scheme}}</string> |
||||||
|
</array> |
||||||
|
<key>CFBundleTypeRole</key> |
||||||
|
<string>{{.Role}}</string> |
||||||
|
</dict> |
||||||
|
{{end}} |
||||||
|
</array> |
||||||
|
{{end}} |
||||||
|
<key>NSAppTransportSecurity</key> |
||||||
|
<dict> |
||||||
|
<key>NSAllowsLocalNetworking</key> |
||||||
|
<true/> |
||||||
|
</dict> |
||||||
|
</dict> |
||||||
|
</plist> |
||||||
@ -0,0 +1,63 @@ |
|||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
||||||
|
<plist version="1.0"> |
||||||
|
<dict> |
||||||
|
<key>CFBundlePackageType</key> |
||||||
|
<string>APPL</string> |
||||||
|
<key>CFBundleName</key> |
||||||
|
<string>{{.Info.ProductName}}</string> |
||||||
|
<key>CFBundleExecutable</key> |
||||||
|
<string>{{.Name}}</string> |
||||||
|
<key>CFBundleIdentifier</key> |
||||||
|
<string>com.wails.{{.Name}}</string> |
||||||
|
<key>CFBundleVersion</key> |
||||||
|
<string>{{.Info.ProductVersion}}</string> |
||||||
|
<key>CFBundleGetInfoString</key> |
||||||
|
<string>{{.Info.Comments}}</string> |
||||||
|
<key>CFBundleShortVersionString</key> |
||||||
|
<string>{{.Info.ProductVersion}}</string> |
||||||
|
<key>CFBundleIconFile</key> |
||||||
|
<string>iconfile</string> |
||||||
|
<key>LSMinimumSystemVersion</key> |
||||||
|
<string>10.13.0</string> |
||||||
|
<key>NSHighResolutionCapable</key> |
||||||
|
<string>true</string> |
||||||
|
<key>NSHumanReadableCopyright</key> |
||||||
|
<string>{{.Info.Copyright}}</string> |
||||||
|
{{if .Info.FileAssociations}} |
||||||
|
<key>CFBundleDocumentTypes</key> |
||||||
|
<array> |
||||||
|
{{range .Info.FileAssociations}} |
||||||
|
<dict> |
||||||
|
<key>CFBundleTypeExtensions</key> |
||||||
|
<array> |
||||||
|
<string>{{.Ext}}</string> |
||||||
|
</array> |
||||||
|
<key>CFBundleTypeName</key> |
||||||
|
<string>{{.Name}}</string> |
||||||
|
<key>CFBundleTypeRole</key> |
||||||
|
<string>{{.Role}}</string> |
||||||
|
<key>CFBundleTypeIconFile</key> |
||||||
|
<string>{{.IconName}}</string> |
||||||
|
</dict> |
||||||
|
{{end}} |
||||||
|
</array> |
||||||
|
{{end}} |
||||||
|
{{if .Info.Protocols}} |
||||||
|
<key>CFBundleURLTypes</key> |
||||||
|
<array> |
||||||
|
{{range .Info.Protocols}} |
||||||
|
<dict> |
||||||
|
<key>CFBundleURLName</key> |
||||||
|
<string>com.wails.{{.Scheme}}</string> |
||||||
|
<key>CFBundleURLSchemes</key> |
||||||
|
<array> |
||||||
|
<string>{{.Scheme}}</string> |
||||||
|
</array> |
||||||
|
<key>CFBundleTypeRole</key> |
||||||
|
<string>{{.Role}}</string> |
||||||
|
</dict> |
||||||
|
{{end}} |
||||||
|
</array> |
||||||
|
{{end}} |
||||||
|
</dict> |
||||||
|
</plist> |
||||||
|
After Width: | Height: | Size: 20 KiB |
@ -0,0 +1,15 @@ |
|||||||
|
{ |
||||||
|
"fixed": { |
||||||
|
"file_version": "{{.Info.ProductVersion}}" |
||||||
|
}, |
||||||
|
"info": { |
||||||
|
"0000": { |
||||||
|
"ProductVersion": "{{.Info.ProductVersion}}", |
||||||
|
"CompanyName": "{{.Info.CompanyName}}", |
||||||
|
"FileDescription": "{{.Info.ProductName}}", |
||||||
|
"LegalCopyright": "{{.Info.Copyright}}", |
||||||
|
"ProductName": "{{.Info.ProductName}}", |
||||||
|
"Comments": "{{.Info.Comments}}" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,114 @@ |
|||||||
|
Unicode true |
||||||
|
|
||||||
|
#### |
||||||
|
## Please note: Template replacements don't work in this file. They are provided with default defines like |
||||||
|
## mentioned underneath. |
||||||
|
## If the keyword is not defined, "wails_tools.nsh" will populate them with the values from ProjectInfo. |
||||||
|
## If they are defined here, "wails_tools.nsh" will not touch them. This allows to use this project.nsi manually |
||||||
|
## from outside of Wails for debugging and development of the installer. |
||||||
|
## |
||||||
|
## For development first make a wails nsis build to populate the "wails_tools.nsh": |
||||||
|
## > wails build --target windows/amd64 --nsis |
||||||
|
## Then you can call makensis on this file with specifying the path to your binary: |
||||||
|
## For a AMD64 only installer: |
||||||
|
## > makensis -DARG_WAILS_AMD64_BINARY=..\..\bin\app.exe |
||||||
|
## For a ARM64 only installer: |
||||||
|
## > makensis -DARG_WAILS_ARM64_BINARY=..\..\bin\app.exe |
||||||
|
## For a installer with both architectures: |
||||||
|
## > makensis -DARG_WAILS_AMD64_BINARY=..\..\bin\app-amd64.exe -DARG_WAILS_ARM64_BINARY=..\..\bin\app-arm64.exe |
||||||
|
#### |
||||||
|
## The following information is taken from the ProjectInfo file, but they can be overwritten here. |
||||||
|
#### |
||||||
|
## !define INFO_PROJECTNAME "MyProject" # Default "{{.Name}}" |
||||||
|
## !define INFO_COMPANYNAME "MyCompany" # Default "{{.Info.CompanyName}}" |
||||||
|
## !define INFO_PRODUCTNAME "MyProduct" # Default "{{.Info.ProductName}}" |
||||||
|
## !define INFO_PRODUCTVERSION "1.0.0" # Default "{{.Info.ProductVersion}}" |
||||||
|
## !define INFO_COPYRIGHT "Copyright" # Default "{{.Info.Copyright}}" |
||||||
|
### |
||||||
|
## !define PRODUCT_EXECUTABLE "Application.exe" # Default "${INFO_PROJECTNAME}.exe" |
||||||
|
## !define UNINST_KEY_NAME "UninstKeyInRegistry" # Default "${INFO_COMPANYNAME}${INFO_PRODUCTNAME}" |
||||||
|
#### |
||||||
|
## !define REQUEST_EXECUTION_LEVEL "admin" # Default "admin" see also https://nsis.sourceforge.io/Docs/Chapter4.html |
||||||
|
#### |
||||||
|
## Include the wails tools |
||||||
|
#### |
||||||
|
!include "wails_tools.nsh" |
||||||
|
|
||||||
|
# The version information for this two must consist of 4 parts |
||||||
|
VIProductVersion "${INFO_PRODUCTVERSION}.0" |
||||||
|
VIFileVersion "${INFO_PRODUCTVERSION}.0" |
||||||
|
|
||||||
|
VIAddVersionKey "CompanyName" "${INFO_COMPANYNAME}" |
||||||
|
VIAddVersionKey "FileDescription" "${INFO_PRODUCTNAME} Installer" |
||||||
|
VIAddVersionKey "ProductVersion" "${INFO_PRODUCTVERSION}" |
||||||
|
VIAddVersionKey "FileVersion" "${INFO_PRODUCTVERSION}" |
||||||
|
VIAddVersionKey "LegalCopyright" "${INFO_COPYRIGHT}" |
||||||
|
VIAddVersionKey "ProductName" "${INFO_PRODUCTNAME}" |
||||||
|
|
||||||
|
# Enable HiDPI support. https://nsis.sourceforge.io/Reference/ManifestDPIAware |
||||||
|
ManifestDPIAware true |
||||||
|
|
||||||
|
!include "MUI.nsh" |
||||||
|
|
||||||
|
!define MUI_ICON "..\icon.ico" |
||||||
|
!define MUI_UNICON "..\icon.ico" |
||||||
|
# !define MUI_WELCOMEFINISHPAGE_BITMAP "resources\leftimage.bmp" #Include this to add a bitmap on the left side of the Welcome Page. Must be a size of 164x314 |
||||||
|
!define MUI_FINISHPAGE_NOAUTOCLOSE # Wait on the INSTFILES page so the user can take a look into the details of the installation steps |
||||||
|
!define MUI_ABORTWARNING # This will warn the user if they exit from the installer. |
||||||
|
|
||||||
|
!insertmacro MUI_PAGE_WELCOME # Welcome to the installer page. |
||||||
|
# !insertmacro MUI_PAGE_LICENSE "resources\eula.txt" # Adds a EULA page to the installer |
||||||
|
!insertmacro MUI_PAGE_DIRECTORY # In which folder install page. |
||||||
|
!insertmacro MUI_PAGE_INSTFILES # Installing page. |
||||||
|
!insertmacro MUI_PAGE_FINISH # Finished installation page. |
||||||
|
|
||||||
|
!insertmacro MUI_UNPAGE_INSTFILES # Uinstalling page |
||||||
|
|
||||||
|
!insertmacro MUI_LANGUAGE "English" # Set the Language of the installer |
||||||
|
|
||||||
|
## The following two statements can be used to sign the installer and the uninstaller. The path to the binaries are provided in %1 |
||||||
|
#!uninstfinalize 'signtool --file "%1"' |
||||||
|
#!finalize 'signtool --file "%1"' |
||||||
|
|
||||||
|
Name "${INFO_PRODUCTNAME}" |
||||||
|
OutFile "..\..\bin\${INFO_PROJECTNAME}-${ARCH}-installer.exe" # Name of the installer's file. |
||||||
|
InstallDir "$PROGRAMFILES64\${INFO_COMPANYNAME}\${INFO_PRODUCTNAME}" # Default installing folder ($PROGRAMFILES is Program Files folder). |
||||||
|
ShowInstDetails show # This will always show the installation details. |
||||||
|
|
||||||
|
Function .onInit |
||||||
|
!insertmacro wails.checkArchitecture |
||||||
|
FunctionEnd |
||||||
|
|
||||||
|
Section |
||||||
|
!insertmacro wails.setShellContext |
||||||
|
|
||||||
|
!insertmacro wails.webview2runtime |
||||||
|
|
||||||
|
SetOutPath $INSTDIR |
||||||
|
|
||||||
|
!insertmacro wails.files |
||||||
|
|
||||||
|
CreateShortcut "$SMPROGRAMS\${INFO_PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCT_EXECUTABLE}" |
||||||
|
CreateShortCut "$DESKTOP\${INFO_PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCT_EXECUTABLE}" |
||||||
|
|
||||||
|
!insertmacro wails.associateFiles |
||||||
|
!insertmacro wails.associateCustomProtocols |
||||||
|
|
||||||
|
!insertmacro wails.writeUninstaller |
||||||
|
SectionEnd |
||||||
|
|
||||||
|
Section "uninstall" |
||||||
|
!insertmacro wails.setShellContext |
||||||
|
|
||||||
|
RMDir /r "$AppData\${PRODUCT_EXECUTABLE}" # Remove the WebView2 DataPath |
||||||
|
|
||||||
|
RMDir /r $INSTDIR |
||||||
|
|
||||||
|
Delete "$SMPROGRAMS\${INFO_PRODUCTNAME}.lnk" |
||||||
|
Delete "$DESKTOP\${INFO_PRODUCTNAME}.lnk" |
||||||
|
|
||||||
|
!insertmacro wails.unassociateFiles |
||||||
|
!insertmacro wails.unassociateCustomProtocols |
||||||
|
|
||||||
|
!insertmacro wails.deleteUninstaller |
||||||
|
SectionEnd |
||||||
@ -0,0 +1,249 @@ |
|||||||
|
# DO NOT EDIT - Generated automatically by `wails build` |
||||||
|
|
||||||
|
!include "x64.nsh" |
||||||
|
!include "WinVer.nsh" |
||||||
|
!include "FileFunc.nsh" |
||||||
|
|
||||||
|
!ifndef INFO_PROJECTNAME |
||||||
|
!define INFO_PROJECTNAME "{{.Name}}" |
||||||
|
!endif |
||||||
|
!ifndef INFO_COMPANYNAME |
||||||
|
!define INFO_COMPANYNAME "{{.Info.CompanyName}}" |
||||||
|
!endif |
||||||
|
!ifndef INFO_PRODUCTNAME |
||||||
|
!define INFO_PRODUCTNAME "{{.Info.ProductName}}" |
||||||
|
!endif |
||||||
|
!ifndef INFO_PRODUCTVERSION |
||||||
|
!define INFO_PRODUCTVERSION "{{.Info.ProductVersion}}" |
||||||
|
!endif |
||||||
|
!ifndef INFO_COPYRIGHT |
||||||
|
!define INFO_COPYRIGHT "{{.Info.Copyright}}" |
||||||
|
!endif |
||||||
|
!ifndef PRODUCT_EXECUTABLE |
||||||
|
!define PRODUCT_EXECUTABLE "${INFO_PROJECTNAME}.exe" |
||||||
|
!endif |
||||||
|
!ifndef UNINST_KEY_NAME |
||||||
|
!define UNINST_KEY_NAME "${INFO_COMPANYNAME}${INFO_PRODUCTNAME}" |
||||||
|
!endif |
||||||
|
!define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINST_KEY_NAME}" |
||||||
|
|
||||||
|
!ifndef REQUEST_EXECUTION_LEVEL |
||||||
|
!define REQUEST_EXECUTION_LEVEL "admin" |
||||||
|
!endif |
||||||
|
|
||||||
|
RequestExecutionLevel "${REQUEST_EXECUTION_LEVEL}" |
||||||
|
|
||||||
|
!ifdef ARG_WAILS_AMD64_BINARY |
||||||
|
!define SUPPORTS_AMD64 |
||||||
|
!endif |
||||||
|
|
||||||
|
!ifdef ARG_WAILS_ARM64_BINARY |
||||||
|
!define SUPPORTS_ARM64 |
||||||
|
!endif |
||||||
|
|
||||||
|
!ifdef SUPPORTS_AMD64 |
||||||
|
!ifdef SUPPORTS_ARM64 |
||||||
|
!define ARCH "amd64_arm64" |
||||||
|
!else |
||||||
|
!define ARCH "amd64" |
||||||
|
!endif |
||||||
|
!else |
||||||
|
!ifdef SUPPORTS_ARM64 |
||||||
|
!define ARCH "arm64" |
||||||
|
!else |
||||||
|
!error "Wails: Undefined ARCH, please provide at least one of ARG_WAILS_AMD64_BINARY or ARG_WAILS_ARM64_BINARY" |
||||||
|
!endif |
||||||
|
!endif |
||||||
|
|
||||||
|
!macro wails.checkArchitecture |
||||||
|
!ifndef WAILS_WIN10_REQUIRED |
||||||
|
!define WAILS_WIN10_REQUIRED "This product is only supported on Windows 10 (Server 2016) and later." |
||||||
|
!endif |
||||||
|
|
||||||
|
!ifndef WAILS_ARCHITECTURE_NOT_SUPPORTED |
||||||
|
!define WAILS_ARCHITECTURE_NOT_SUPPORTED "This product can't be installed on the current Windows architecture. Supports: ${ARCH}" |
||||||
|
!endif |
||||||
|
|
||||||
|
${If} ${AtLeastWin10} |
||||||
|
!ifdef SUPPORTS_AMD64 |
||||||
|
${if} ${IsNativeAMD64} |
||||||
|
Goto ok |
||||||
|
${EndIf} |
||||||
|
!endif |
||||||
|
|
||||||
|
!ifdef SUPPORTS_ARM64 |
||||||
|
${if} ${IsNativeARM64} |
||||||
|
Goto ok |
||||||
|
${EndIf} |
||||||
|
!endif |
||||||
|
|
||||||
|
IfSilent silentArch notSilentArch |
||||||
|
silentArch: |
||||||
|
SetErrorLevel 65 |
||||||
|
Abort |
||||||
|
notSilentArch: |
||||||
|
MessageBox MB_OK "${WAILS_ARCHITECTURE_NOT_SUPPORTED}" |
||||||
|
Quit |
||||||
|
${else} |
||||||
|
IfSilent silentWin notSilentWin |
||||||
|
silentWin: |
||||||
|
SetErrorLevel 64 |
||||||
|
Abort |
||||||
|
notSilentWin: |
||||||
|
MessageBox MB_OK "${WAILS_WIN10_REQUIRED}" |
||||||
|
Quit |
||||||
|
${EndIf} |
||||||
|
|
||||||
|
ok: |
||||||
|
!macroend |
||||||
|
|
||||||
|
!macro wails.files |
||||||
|
!ifdef SUPPORTS_AMD64 |
||||||
|
${if} ${IsNativeAMD64} |
||||||
|
File "/oname=${PRODUCT_EXECUTABLE}" "${ARG_WAILS_AMD64_BINARY}" |
||||||
|
${EndIf} |
||||||
|
!endif |
||||||
|
|
||||||
|
!ifdef SUPPORTS_ARM64 |
||||||
|
${if} ${IsNativeARM64} |
||||||
|
File "/oname=${PRODUCT_EXECUTABLE}" "${ARG_WAILS_ARM64_BINARY}" |
||||||
|
${EndIf} |
||||||
|
!endif |
||||||
|
!macroend |
||||||
|
|
||||||
|
!macro wails.writeUninstaller |
||||||
|
WriteUninstaller "$INSTDIR\uninstall.exe" |
||||||
|
|
||||||
|
SetRegView 64 |
||||||
|
WriteRegStr HKLM "${UNINST_KEY}" "Publisher" "${INFO_COMPANYNAME}" |
||||||
|
WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "${INFO_PRODUCTNAME}" |
||||||
|
WriteRegStr HKLM "${UNINST_KEY}" "DisplayVersion" "${INFO_PRODUCTVERSION}" |
||||||
|
WriteRegStr HKLM "${UNINST_KEY}" "DisplayIcon" "$INSTDIR\${PRODUCT_EXECUTABLE}" |
||||||
|
WriteRegStr HKLM "${UNINST_KEY}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\"" |
||||||
|
WriteRegStr HKLM "${UNINST_KEY}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S" |
||||||
|
|
||||||
|
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2 |
||||||
|
IntFmt $0 "0x%08X" $0 |
||||||
|
WriteRegDWORD HKLM "${UNINST_KEY}" "EstimatedSize" "$0" |
||||||
|
!macroend |
||||||
|
|
||||||
|
!macro wails.deleteUninstaller |
||||||
|
Delete "$INSTDIR\uninstall.exe" |
||||||
|
|
||||||
|
SetRegView 64 |
||||||
|
DeleteRegKey HKLM "${UNINST_KEY}" |
||||||
|
!macroend |
||||||
|
|
||||||
|
!macro wails.setShellContext |
||||||
|
${If} ${REQUEST_EXECUTION_LEVEL} == "admin" |
||||||
|
SetShellVarContext all |
||||||
|
${else} |
||||||
|
SetShellVarContext current |
||||||
|
${EndIf} |
||||||
|
!macroend |
||||||
|
|
||||||
|
# Install webview2 by launching the bootstrapper |
||||||
|
# See https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#online-only-deployment |
||||||
|
!macro wails.webview2runtime |
||||||
|
!ifndef WAILS_INSTALL_WEBVIEW_DETAILPRINT |
||||||
|
!define WAILS_INSTALL_WEBVIEW_DETAILPRINT "Installing: WebView2 Runtime" |
||||||
|
!endif |
||||||
|
|
||||||
|
SetRegView 64 |
||||||
|
# If the admin key exists and is not empty then webview2 is already installed |
||||||
|
ReadRegStr $0 HKLM "SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" |
||||||
|
${If} $0 != "" |
||||||
|
Goto ok |
||||||
|
${EndIf} |
||||||
|
|
||||||
|
${If} ${REQUEST_EXECUTION_LEVEL} == "user" |
||||||
|
# If the installer is run in user level, check the user specific key exists and is not empty then webview2 is already installed |
||||||
|
ReadRegStr $0 HKCU "Software\Microsoft\EdgeUpdate\Clients{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" |
||||||
|
${If} $0 != "" |
||||||
|
Goto ok |
||||||
|
${EndIf} |
||||||
|
${EndIf} |
||||||
|
|
||||||
|
SetDetailsPrint both |
||||||
|
DetailPrint "${WAILS_INSTALL_WEBVIEW_DETAILPRINT}" |
||||||
|
SetDetailsPrint listonly |
||||||
|
|
||||||
|
InitPluginsDir |
||||||
|
CreateDirectory "$pluginsdir\webview2bootstrapper" |
||||||
|
SetOutPath "$pluginsdir\webview2bootstrapper" |
||||||
|
File "tmp\MicrosoftEdgeWebview2Setup.exe" |
||||||
|
ExecWait '"$pluginsdir\webview2bootstrapper\MicrosoftEdgeWebview2Setup.exe" /silent /install' |
||||||
|
|
||||||
|
SetDetailsPrint both |
||||||
|
ok: |
||||||
|
!macroend |
||||||
|
|
||||||
|
# Copy of APP_ASSOCIATE and APP_UNASSOCIATE macros from here https://gist.github.com/nikku/281d0ef126dbc215dd58bfd5b3a5cd5b |
||||||
|
!macro APP_ASSOCIATE EXT FILECLASS DESCRIPTION ICON COMMANDTEXT COMMAND |
||||||
|
; Backup the previously associated file class |
||||||
|
ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" "" |
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "${FILECLASS}_backup" "$R0" |
||||||
|
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "${FILECLASS}" |
||||||
|
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}" "" `${DESCRIPTION}` |
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\DefaultIcon" "" `${ICON}` |
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell" "" "open" |
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\open" "" `${COMMANDTEXT}` |
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\open\command" "" `${COMMAND}` |
||||||
|
!macroend |
||||||
|
|
||||||
|
!macro APP_UNASSOCIATE EXT FILECLASS |
||||||
|
; Backup the previously associated file class |
||||||
|
ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" `${FILECLASS}_backup` |
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "$R0" |
||||||
|
|
||||||
|
DeleteRegKey SHELL_CONTEXT `Software\Classes\${FILECLASS}` |
||||||
|
!macroend |
||||||
|
|
||||||
|
!macro wails.associateFiles |
||||||
|
; Create file associations |
||||||
|
{{range .Info.FileAssociations}} |
||||||
|
!insertmacro APP_ASSOCIATE "{{.Ext}}" "{{.Name}}" "{{.Description}}" "$INSTDIR\{{.IconName}}.ico" "Open with ${INFO_PRODUCTNAME}" "$INSTDIR\${PRODUCT_EXECUTABLE} $\"%1$\"" |
||||||
|
|
||||||
|
File "..\{{.IconName}}.ico" |
||||||
|
{{end}} |
||||||
|
!macroend |
||||||
|
|
||||||
|
!macro wails.unassociateFiles |
||||||
|
; Delete app associations |
||||||
|
{{range .Info.FileAssociations}} |
||||||
|
!insertmacro APP_UNASSOCIATE "{{.Ext}}" "{{.Name}}" |
||||||
|
|
||||||
|
Delete "$INSTDIR\{{.IconName}}.ico" |
||||||
|
{{end}} |
||||||
|
!macroend |
||||||
|
|
||||||
|
!macro CUSTOM_PROTOCOL_ASSOCIATE PROTOCOL DESCRIPTION ICON COMMAND |
||||||
|
DeleteRegKey SHELL_CONTEXT "Software\Classes\${PROTOCOL}" |
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${PROTOCOL}" "" "${DESCRIPTION}" |
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${PROTOCOL}" "URL Protocol" "" |
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${PROTOCOL}\DefaultIcon" "" "${ICON}" |
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${PROTOCOL}\shell" "" "" |
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${PROTOCOL}\shell\open" "" "" |
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${PROTOCOL}\shell\open\command" "" "${COMMAND}" |
||||||
|
!macroend |
||||||
|
|
||||||
|
!macro CUSTOM_PROTOCOL_UNASSOCIATE PROTOCOL |
||||||
|
DeleteRegKey SHELL_CONTEXT "Software\Classes\${PROTOCOL}" |
||||||
|
!macroend |
||||||
|
|
||||||
|
!macro wails.associateCustomProtocols |
||||||
|
; Create custom protocols associations |
||||||
|
{{range .Info.Protocols}} |
||||||
|
!insertmacro CUSTOM_PROTOCOL_ASSOCIATE "{{.Scheme}}" "{{.Description}}" "$INSTDIR\${PRODUCT_EXECUTABLE},0" "$INSTDIR\${PRODUCT_EXECUTABLE} $\"%1$\"" |
||||||
|
|
||||||
|
{{end}} |
||||||
|
!macroend |
||||||
|
|
||||||
|
!macro wails.unassociateCustomProtocols |
||||||
|
; Delete app custom protocol associations |
||||||
|
{{range .Info.Protocols}} |
||||||
|
!insertmacro CUSTOM_PROTOCOL_UNASSOCIATE "{{.Scheme}}" |
||||||
|
{{end}} |
||||||
|
!macroend |
||||||
@ -0,0 +1,15 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> |
||||||
|
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"> |
||||||
|
<assemblyIdentity type="win32" name="com.wails.{{.Name}}" version="{{.Info.ProductVersion}}.0" processorArchitecture="*"/> |
||||||
|
<dependency> |
||||||
|
<dependentAssembly> |
||||||
|
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/> |
||||||
|
</dependentAssembly> |
||||||
|
</dependency> |
||||||
|
<asmv3:application> |
||||||
|
<asmv3:windowsSettings> |
||||||
|
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware> <!-- fallback for Windows 7 and 8 --> |
||||||
|
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">permonitorv2,permonitor</dpiAwareness> <!-- falls back to per-monitor if per-monitor v2 is not supported --> |
||||||
|
</asmv3:windowsSettings> |
||||||
|
</asmv3:application> |
||||||
|
</assembly> |
||||||
@ -0,0 +1,8 @@ |
|||||||
|
# Vue 3 + Vite |
||||||
|
|
||||||
|
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, |
||||||
|
check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more. |
||||||
|
|
||||||
|
## Recommended IDE Setup |
||||||
|
|
||||||
|
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html lang="en"> |
||||||
|
<head> |
||||||
|
<meta charset="UTF-8"/> |
||||||
|
<meta content="width=device-width, initial-scale=1.0" name="viewport"/> |
||||||
|
<title>testWails</title> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<div id="app"></div> |
||||||
|
<script src="./src/main.js" type="module"></script> |
||||||
|
</body> |
||||||
|
</html> |
||||||
|
|
||||||
@ -0,0 +1,18 @@ |
|||||||
|
{ |
||||||
|
"name": "frontend", |
||||||
|
"private": true, |
||||||
|
"version": "0.0.0", |
||||||
|
"type": "module", |
||||||
|
"scripts": { |
||||||
|
"dev": "vite", |
||||||
|
"build": "vite build", |
||||||
|
"preview": "vite preview" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"vue": "^3.2.37" |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"@vitejs/plugin-vue": "^3.0.3", |
||||||
|
"vite": "^3.0.7" |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,50 @@ |
|||||||
|
{ |
||||||
|
"server": { |
||||||
|
"debug": true, |
||||||
|
"http_debug": false, |
||||||
|
"http_demo": true, |
||||||
|
"http_dir": "web", |
||||||
|
"http_login": "demo", |
||||||
|
"http_password": "demo", |
||||||
|
"http_port": ":8083", |
||||||
|
"https": false, |
||||||
|
"https_auto_tls": false, |
||||||
|
"https_auto_tls_name": "", |
||||||
|
"https_cert": "server.crt", |
||||||
|
"https_key": "server.key", |
||||||
|
"https_port": ":443", |
||||||
|
"ice_servers": ["stun:stun.l.google.com:193022"], |
||||||
|
"log_level": "debug", |
||||||
|
"rtsp_port": ":5541", |
||||||
|
"token": { |
||||||
|
"backend": "http://127.0.0.1/test.php" |
||||||
|
}, |
||||||
|
"defaults": { |
||||||
|
"audio": true |
||||||
|
} |
||||||
|
}, |
||||||
|
"streams": { |
||||||
|
"dahua108": { |
||||||
|
"channels": { |
||||||
|
"0": { |
||||||
|
"url": "rtsp://admin:@Sua123sua@192.168.88.7:554/h264/ch1/sub/av_stream", |
||||||
|
"debug": false, |
||||||
|
"on_demand": false, |
||||||
|
"audio": true |
||||||
|
} |
||||||
|
}, |
||||||
|
"name": "dahua" |
||||||
|
}, |
||||||
|
"dahua107": { |
||||||
|
"channels": { |
||||||
|
"0": { |
||||||
|
"url": "rtsp://admin:@Sua123sua@192.168.88.7:554/stream2&channel=2", |
||||||
|
"debug": false, |
||||||
|
"on_demand": false, |
||||||
|
"audio": true |
||||||
|
} |
||||||
|
}, |
||||||
|
"name": "dahua" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,163 @@ |
|||||||
|
.grid-wrapper{ |
||||||
|
height: calc(100vh - 30px); |
||||||
|
margin: 0px; |
||||||
|
background: transparent; |
||||||
|
display: flex; |
||||||
|
flex-wrap: wrap; |
||||||
|
} |
||||||
|
.layout-top-nav .wrapper .main-header { |
||||||
|
margin-left: 0; |
||||||
|
height: 30px; |
||||||
|
} |
||||||
|
video.background{ |
||||||
|
pointer-events: none; |
||||||
|
position: absolute; |
||||||
|
top:0; |
||||||
|
left: 0; |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
object-fit: cover; |
||||||
|
} |
||||||
|
.control-sidebar.custom{ |
||||||
|
background: black; |
||||||
|
height: 100%; |
||||||
|
margin-top: -57px; |
||||||
|
padding: 30px 8px 8px; |
||||||
|
background: linear-gradient(45deg, black, transparent); |
||||||
|
overflow: hidden; |
||||||
|
} |
||||||
|
.control-sidebar.custom .row{ |
||||||
|
height:100%; |
||||||
|
overflow: auto; |
||||||
|
} |
||||||
|
.control-sidebar.custom>h5{ |
||||||
|
color: white; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
.grid-wrapper .player video.video-class { |
||||||
|
background: #000; |
||||||
|
object-fit: fill; |
||||||
|
} |
||||||
|
.grid-wrapper .player video.video-class.empty { |
||||||
|
background: transparent; |
||||||
|
} |
||||||
|
|
||||||
|
.img-background{ |
||||||
|
/* background: url(/../static/img/back.jpg); */ |
||||||
|
background-color: #343a40; |
||||||
|
background-position: center; |
||||||
|
background-repeat: no-repeat; |
||||||
|
background-size: cover; |
||||||
|
backdrop-filter: sepia(0.5) grayscale(0.4); |
||||||
|
} |
||||||
|
.img-background .content-wrapper{ |
||||||
|
background: transparent; |
||||||
|
} |
||||||
|
.img-background .main-header{ |
||||||
|
background: |
||||||
|
} |
||||||
|
.grid-wrapper .player { |
||||||
|
|
||||||
|
padding: 0px; |
||||||
|
border: 2px solid #000; |
||||||
|
} |
||||||
|
|
||||||
|
.grid-wrapper .player .remove-btn{ |
||||||
|
color:white; |
||||||
|
display: none; |
||||||
|
position: absolute; |
||||||
|
right: 0px; |
||||||
|
top: 0px; |
||||||
|
cursor: pointer; |
||||||
|
padding: 5px 10px; |
||||||
|
border-radius: 50px; |
||||||
|
filter: drop-shadow(1px 1px 1px black); |
||||||
|
} |
||||||
|
.grid-wrapper .player.empty .remove-btn{ |
||||||
|
display: none; |
||||||
|
} |
||||||
|
.grid-wrapper .player:not(.empty):hover .remove-btn{ |
||||||
|
display: block; |
||||||
|
} |
||||||
|
|
||||||
|
.grid-wrapper .player .add-stream-btn{ |
||||||
|
position: absolute; |
||||||
|
left: 0; |
||||||
|
top: calc(50% - 2vw); |
||||||
|
text-align: center; |
||||||
|
width: 100%; |
||||||
|
font-variant-caps: all-petite-caps; |
||||||
|
font-size: 1.5vw; |
||||||
|
line-height: 1; |
||||||
|
color: white; |
||||||
|
cursor: pointer; |
||||||
|
display: none; |
||||||
|
filter: drop-shadow(2px 4px 6px black); |
||||||
|
} |
||||||
|
.grid-wrapper .player.empty .add-stream-btn{ |
||||||
|
display: block; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
.carousel-caption { |
||||||
|
pointer-events: none; |
||||||
|
filter: drop-shadow(1px 1px 1px black); |
||||||
|
} |
||||||
|
.stream-img{ |
||||||
|
height: 150px; |
||||||
|
} |
||||||
|
.player .loader, .main-player .loader{ |
||||||
|
position: absolute; |
||||||
|
width: 100px; |
||||||
|
height: 70px; |
||||||
|
top: calc(50% - 35px); |
||||||
|
left: calc(50% - 50px); |
||||||
|
} |
||||||
|
.control-sidebar-close-btn{ |
||||||
|
position: absolute; |
||||||
|
top: 37px; |
||||||
|
right: 12px; |
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
.control-sidebar-close-btn:hover{ |
||||||
|
color: #999; |
||||||
|
} |
||||||
|
.dropdown-menu.custom-dropdown.show{ |
||||||
|
color: #ffF; |
||||||
|
border: 1px solid #343a40; |
||||||
|
background: linear-gradient(45deg, #000000d1 30%,#343a40); |
||||||
|
padding: 0; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
.dropdown-menu.custom-dropdown .custom-dropdown-item{ |
||||||
|
float: left; |
||||||
|
width: 33%; |
||||||
|
padding: 10px; |
||||||
|
font-size: 12px; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.dropdown-menu.custom-dropdown .custom-dropdown-item.active,.dropdown-menu.custom-dropdown .custom-dropdown-item:hover{ |
||||||
|
border-radius: 5px; |
||||||
|
box-shadow: inset 0px 0px 15px -5px; |
||||||
|
} |
||||||
|
.dropdown-menu.custom-dropdown .dropdown-item{ |
||||||
|
color: #fff; |
||||||
|
|
||||||
|
} |
||||||
|
.dropdown-menu.custom-dropdown .dropdown-item:hover{ |
||||||
|
box-shadow: inset 0px 0px 15px -5px; |
||||||
|
background: transparent; |
||||||
|
} |
||||||
|
|
||||||
|
.custom-dropdown-item.with-img{ |
||||||
|
width: 50%!important; |
||||||
|
height: auto; |
||||||
|
padding: 2px!important; |
||||||
|
|
||||||
|
} |
||||||
|
.custom-dropdown-item.with-img img{ |
||||||
|
width: 100%; |
||||||
|
height: auto; |
||||||
|
} |
||||||
@ -0,0 +1,224 @@ |
|||||||
|
/* cyrillic-ext */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: italic; |
||||||
|
font-weight: 400; |
||||||
|
src: url(fonts/6xK1dSBYKcSV-LCoeQqfX1RYOo3qPZ7qsDJB9cme_xc.woff2) format('woff2'); |
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; |
||||||
|
} |
||||||
|
/* cyrillic */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: italic; |
||||||
|
font-weight: 400; |
||||||
|
src: url(fonts/6xK1dSBYKcSV-LCoeQqfX1RYOo3qPZ7jsDJB9cme_xc.woff2) format('woff2'); |
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; |
||||||
|
} |
||||||
|
/* greek-ext */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: italic; |
||||||
|
font-weight: 400; |
||||||
|
src: url(fonts/6xK1dSBYKcSV-LCoeQqfX1RYOo3qPZ7rsDJB9cme_xc.woff2) format('woff2'); |
||||||
|
unicode-range: U+1F00-1FFF; |
||||||
|
} |
||||||
|
/* greek */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: italic; |
||||||
|
font-weight: 400; |
||||||
|
src: url(fonts/6xK1dSBYKcSV-LCoeQqfX1RYOo3qPZ7ksDJB9cme_xc.woff2) format('woff2'); |
||||||
|
unicode-range: U+0370-03FF; |
||||||
|
} |
||||||
|
/* vietnamese */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: italic; |
||||||
|
font-weight: 400; |
||||||
|
src: url(fonts/6xK1dSBYKcSV-LCoeQqfX1RYOo3qPZ7osDJB9cme_xc.woff2) format('woff2'); |
||||||
|
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; |
||||||
|
} |
||||||
|
/* latin-ext */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: italic; |
||||||
|
font-weight: 400; |
||||||
|
src: url(fonts/6xK1dSBYKcSV-LCoeQqfX1RYOo3qPZ7psDJB9cme_xc.woff2) format('woff2'); |
||||||
|
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; |
||||||
|
} |
||||||
|
/* latin */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: italic; |
||||||
|
font-weight: 400; |
||||||
|
src: url(fonts/6xK1dSBYKcSV-LCoeQqfX1RYOo3qPZ7nsDJB9cme.woff2) format('woff2'); |
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; |
||||||
|
} |
||||||
|
/* cyrillic-ext */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 300; |
||||||
|
src: url(fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwmhdu3cOWxy40.woff2) format('woff2'); |
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; |
||||||
|
} |
||||||
|
/* cyrillic */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 300; |
||||||
|
src: url(fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwkxdu3cOWxy40.woff2) format('woff2'); |
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; |
||||||
|
} |
||||||
|
/* greek-ext */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 300; |
||||||
|
src: url(fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwmxdu3cOWxy40.woff2) format('woff2'); |
||||||
|
unicode-range: U+1F00-1FFF; |
||||||
|
} |
||||||
|
/* greek */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 300; |
||||||
|
src: url(fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwlBdu3cOWxy40.woff2) format('woff2'); |
||||||
|
unicode-range: U+0370-03FF; |
||||||
|
} |
||||||
|
/* vietnamese */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 300; |
||||||
|
src: url(fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwmBdu3cOWxy40.woff2) format('woff2'); |
||||||
|
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; |
||||||
|
} |
||||||
|
/* latin-ext */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 300; |
||||||
|
src: url(fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwmRdu3cOWxy40.woff2) format('woff2'); |
||||||
|
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; |
||||||
|
} |
||||||
|
/* latin */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 300; |
||||||
|
src: url(fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwlxdu3cOWxw.woff2) format('woff2'); |
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; |
||||||
|
} |
||||||
|
/* cyrillic-ext */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 400; |
||||||
|
src: url(fonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNa7lujVj9_mf.woff2) format('woff2'); |
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; |
||||||
|
} |
||||||
|
/* cyrillic */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 400; |
||||||
|
src: url(fonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qPK7lujVj9_mf.woff2) format('woff2'); |
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; |
||||||
|
} |
||||||
|
/* greek-ext */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 400; |
||||||
|
src: url(fonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNK7lujVj9_mf.woff2) format('woff2'); |
||||||
|
unicode-range: U+1F00-1FFF; |
||||||
|
} |
||||||
|
/* greek */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 400; |
||||||
|
src: url(fonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qO67lujVj9_mf.woff2) format('woff2'); |
||||||
|
unicode-range: U+0370-03FF; |
||||||
|
} |
||||||
|
/* vietnamese */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 400; |
||||||
|
src: url(fonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qN67lujVj9_mf.woff2) format('woff2'); |
||||||
|
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; |
||||||
|
} |
||||||
|
/* latin-ext */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 400; |
||||||
|
src: url(fonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNq7lujVj9_mf.woff2) format('woff2'); |
||||||
|
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; |
||||||
|
} |
||||||
|
/* latin */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 400; |
||||||
|
src: url(fonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7lujVj9w.woff2) format('woff2'); |
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; |
||||||
|
} |
||||||
|
/* cyrillic-ext */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 700; |
||||||
|
src: url(fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmhdu3cOWxy40.woff2) format('woff2'); |
||||||
|
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; |
||||||
|
} |
||||||
|
/* cyrillic */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 700; |
||||||
|
src: url(fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwkxdu3cOWxy40.woff2) format('woff2'); |
||||||
|
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; |
||||||
|
} |
||||||
|
/* greek-ext */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 700; |
||||||
|
src: url(fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmxdu3cOWxy40.woff2) format('woff2'); |
||||||
|
unicode-range: U+1F00-1FFF; |
||||||
|
} |
||||||
|
/* greek */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 700; |
||||||
|
src: url(fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlBdu3cOWxy40.woff2) format('woff2'); |
||||||
|
unicode-range: U+0370-03FF; |
||||||
|
} |
||||||
|
/* vietnamese */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 700; |
||||||
|
src: url(fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmBdu3cOWxy40.woff2) format('woff2'); |
||||||
|
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; |
||||||
|
} |
||||||
|
/* latin-ext */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 700; |
||||||
|
src: url(fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmRdu3cOWxy40.woff2) format('woff2'); |
||||||
|
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; |
||||||
|
} |
||||||
|
/* latin */ |
||||||
|
@font-face { |
||||||
|
font-family: 'Source Sans Pro'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 700; |
||||||
|
src: url(fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlxdu3cOWxw.woff2) format('woff2'); |
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; |
||||||
|
} |
||||||
@ -0,0 +1,223 @@ |
|||||||
|
#videoPlayer{ |
||||||
|
width: 100%; |
||||||
|
background: black; |
||||||
|
position: -webkit-sticky; /* Safari */ |
||||||
|
position: sticky; |
||||||
|
top: 15px; |
||||||
|
margin-bottom: -6px; |
||||||
|
|
||||||
|
} |
||||||
|
.videoPlayer{ |
||||||
|
width: 100%; |
||||||
|
background: black; |
||||||
|
position: -webkit-sticky; /* Safari */ |
||||||
|
position: sticky; |
||||||
|
top: 15px; |
||||||
|
margin-bottom: -6px; |
||||||
|
|
||||||
|
} |
||||||
|
.btn-group.stream{ |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
flex-wrap: wrap; |
||||||
|
} |
||||||
|
.btn-group.stream .btn{ |
||||||
|
flex: 1 0 30%; |
||||||
|
} |
||||||
|
.btn-group.stream .input-group-prepend{ |
||||||
|
flex: 1 0 30%; |
||||||
|
} |
||||||
|
.img-wrapper{ |
||||||
|
width: 100%; |
||||||
|
height: 180px; |
||||||
|
background: black; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.img-wrapper img{ |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
} |
||||||
|
.text-wrapper{ |
||||||
|
padding: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
@media (min-width: 576px){ |
||||||
|
.card-columns { |
||||||
|
-webkit-column-count: 4; |
||||||
|
-moz-column-count: 4; |
||||||
|
column-count: 4; |
||||||
|
-webkit-column-gap: 1.25rem; |
||||||
|
-moz-column-gap: 1.25rem; |
||||||
|
column-gap: 1.25rem; |
||||||
|
orphans: 1; |
||||||
|
widows: 1; |
||||||
|
} |
||||||
|
} |
||||||
|
@media (min-width: 576px){ |
||||||
|
.card-column { |
||||||
|
column-count: 2; |
||||||
|
} |
||||||
|
} |
||||||
|
@media (min-width: 768px){ |
||||||
|
.card-column { |
||||||
|
column-count: 4; |
||||||
|
} |
||||||
|
} |
||||||
|
@media (min-width: 1920px){ |
||||||
|
.card-column { |
||||||
|
column-count: 6; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
.grid-wrapper{ |
||||||
|
height: 80vh; |
||||||
|
margin: -1px; |
||||||
|
background: #000; |
||||||
|
display: flex; |
||||||
|
flex-wrap: wrap; |
||||||
|
} |
||||||
|
:-webkit-full-screen .grid-wrapper{/*WebKit, Opera 15+*/ |
||||||
|
height: 100vh; |
||||||
|
width: 100vw; |
||||||
|
} |
||||||
|
:-moz-full-screen .grid-wrapper{/*FireFox*/ |
||||||
|
height: 100vh; |
||||||
|
width: 100vw; |
||||||
|
} |
||||||
|
:full-screen .grid-wrapper{/*Opera 12.15-, Blink, w3c standard*/ |
||||||
|
height: 100vh; |
||||||
|
width: 100vw; |
||||||
|
} |
||||||
|
.grid-wrapper .player{ |
||||||
|
height: 50%; |
||||||
|
width: 50%; |
||||||
|
position: relative; |
||||||
|
padding: 2px; |
||||||
|
} |
||||||
|
.grid-wrapper .player.grid-1{ |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
} |
||||||
|
.grid-wrapper .player.grid-6{ |
||||||
|
width: 33.33%; |
||||||
|
} |
||||||
|
.grid-wrapper .player.grid-9{ |
||||||
|
width: 33.33%; |
||||||
|
height: 33.33%; |
||||||
|
} |
||||||
|
.grid-wrapper .player.grid-12{ |
||||||
|
width: 25%; |
||||||
|
height: 33.33%; |
||||||
|
} |
||||||
|
.grid-wrapper .player.grid-16{ |
||||||
|
width: 25%; |
||||||
|
height: 25%; |
||||||
|
} |
||||||
|
.grid-wrapper .player.grid-25{ |
||||||
|
width: 20%; |
||||||
|
height: 20%; |
||||||
|
} |
||||||
|
.grid-wrapper .player.grid-36{ |
||||||
|
width: 16.66%; |
||||||
|
height: 16.66%; |
||||||
|
} |
||||||
|
.grid-wrapper .player.grid-49{ |
||||||
|
width: 14.285%; |
||||||
|
height: 14.29%; |
||||||
|
} |
||||||
|
.grid-wrapper .player video{ |
||||||
|
height: 100%; |
||||||
|
width: 100%; |
||||||
|
background: #343a40; |
||||||
|
margin-bottom: -6px; |
||||||
|
} |
||||||
|
.grid-wrapper .player .play-info{ |
||||||
|
position: absolute; |
||||||
|
padding: 10px; |
||||||
|
text-align: center; |
||||||
|
color: #fff; |
||||||
|
top:0; |
||||||
|
left: 0; |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
.grid-wrapper .player .control{ |
||||||
|
width: 100%; |
||||||
|
position: absolute; |
||||||
|
bottom: 0; |
||||||
|
padding: 10px; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
.grid-wrapper .player .control .btn{ |
||||||
|
margin: 0 0 10px 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.card .stream-name{ |
||||||
|
position: absolute; |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
.card .stream-name .card-title{ |
||||||
|
color: #FFF; |
||||||
|
width: 100%; |
||||||
|
filter: drop-shadow(1px 0px 1px black); |
||||||
|
font-size: 30px; |
||||||
|
} |
||||||
|
.one-line-header{ |
||||||
|
white-space: nowrap; |
||||||
|
overflow: hidden; |
||||||
|
text-overflow: ellipsis; |
||||||
|
max-width: 95%; |
||||||
|
} |
||||||
|
.main-player-wrapper{ |
||||||
|
position: fixed; |
||||||
|
top: 0; |
||||||
|
left: 0; |
||||||
|
width: 100vw; |
||||||
|
height: 100vh; |
||||||
|
background: rgb(0 0 0 / 0.8); |
||||||
|
z-index: 1100; |
||||||
|
padding: 15px; |
||||||
|
} |
||||||
|
.main-player-wrapper a{ |
||||||
|
color: #fff; |
||||||
|
position: absolute; |
||||||
|
right: 5px; |
||||||
|
top: 5px; |
||||||
|
font-size: 30px; |
||||||
|
padding: 0 12px; |
||||||
|
border-radius: 50px; |
||||||
|
box-shadow: 0px 0px 10px -1px #fff; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.main-player-wrapper a:hover{ |
||||||
|
color: #dc3545; |
||||||
|
box-shadow: 0px 0px 10px -1px #dc3545; |
||||||
|
} |
||||||
|
.main-player-wrapper .main-player{ |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
.main-player-wrapper .main-player video{ |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
background: #000; |
||||||
|
} |
||||||
|
.main-player-wrapper .main-player .play-info{ |
||||||
|
position: absolute; |
||||||
|
padding: 10px; |
||||||
|
text-align: center; |
||||||
|
color: #fff; |
||||||
|
top: 0; |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
.carousel-caption{ |
||||||
|
pointer-events: none; |
||||||
|
} |
||||||
|
.fix-height{ |
||||||
|
object-fit: fill; |
||||||
|
aspect-ratio: 16/9; |
||||||
|
} |
||||||
|
After Width: | Height: | Size: 298 KiB |
|
After Width: | Height: | Size: 493 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 411 KiB |
|
After Width: | Height: | Size: 221 KiB |
@ -0,0 +1,218 @@ |
|||||||
|
var rtspPlayer={ |
||||||
|
active:false, |
||||||
|
type:'live', |
||||||
|
hls:null, |
||||||
|
ws:null, |
||||||
|
mseSourceBuffer:null, |
||||||
|
mse:null, |
||||||
|
mseQueue:[], |
||||||
|
mseStreamingStarted:false, |
||||||
|
webrtc:null, |
||||||
|
webrtcSendChannel:null, |
||||||
|
webrtcSendChannelInterval:null, |
||||||
|
uuid:null, |
||||||
|
|
||||||
|
clearPlayer:function(){ |
||||||
|
if(this.active){ |
||||||
|
|
||||||
|
if(this.hls!=null){ |
||||||
|
this.hls.destroy(); |
||||||
|
this.hls=null; |
||||||
|
} |
||||||
|
if(this.ws!=null){ |
||||||
|
//close WebSocket connection if opened
|
||||||
|
this.ws.close(1000); |
||||||
|
this.ws=null; |
||||||
|
} |
||||||
|
if(this.webrtc!=null){ |
||||||
|
clearInterval(this.webrtcSendChannelInterval); |
||||||
|
|
||||||
|
this.webrtc=null; |
||||||
|
} |
||||||
|
$('#videoPlayer')[0].src = ''; |
||||||
|
$('#videoPlayer')[0].load(); |
||||||
|
|
||||||
|
|
||||||
|
this.active=false; |
||||||
|
} |
||||||
|
}, |
||||||
|
livePlayer:function(type,uuid){ |
||||||
|
this.clearPlayer(); |
||||||
|
this.uuid=uuid; |
||||||
|
this.active=true; |
||||||
|
|
||||||
|
$('.streams-vs-player').addClass('active-player'); |
||||||
|
if(type==0){ |
||||||
|
type=$('input[name=defaultPlayer]:checked').val() |
||||||
|
} |
||||||
|
switch (type) { |
||||||
|
case 'hls': |
||||||
|
this.playHls(); |
||||||
|
break; |
||||||
|
case 'mse': |
||||||
|
this.playMse(); |
||||||
|
break; |
||||||
|
case 'webrtc': |
||||||
|
this.playWebrtc(); |
||||||
|
break; |
||||||
|
default: |
||||||
|
Swal.fire( |
||||||
|
'Sorry', |
||||||
|
'This option is still under development', |
||||||
|
'question' |
||||||
|
) |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
}, |
||||||
|
playHls:function(){ |
||||||
|
if(this.hls==null && Hls.isSupported()){ |
||||||
|
this.hls = new Hls(); |
||||||
|
} |
||||||
|
if ($("#videoPlayer")[0].canPlayType('application/vnd.apple.mpegurl')) { |
||||||
|
$("#videoPlayer")[0].src = this.streamPlayUrl('hls'); |
||||||
|
$("#videoPlayer")[0].load(); |
||||||
|
} else { |
||||||
|
if (this.hls != null) { |
||||||
|
this.hls.loadSource(this.streamPlayUrl('hls')); |
||||||
|
this.hls.attachMedia($("#videoPlayer")[0]); |
||||||
|
} else { |
||||||
|
Swal.fire({ |
||||||
|
icon: 'error', |
||||||
|
title: 'Oops...', |
||||||
|
text: 'Your browser don`t support hls ' |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
playWebrtc:function(){ |
||||||
|
var _this=this; |
||||||
|
this.webrtc=new RTCPeerConnection({ |
||||||
|
iceServers: [{ |
||||||
|
urls: ["stun:stun.l.google.com:19302"] |
||||||
|
}] |
||||||
|
}); |
||||||
|
this.webrtc.onnegotiationneeded = this.handleNegotiationNeeded; |
||||||
|
this.webrtc.ontrack = function(event) { |
||||||
|
console.log(event.streams.length + ' track is delivered'); |
||||||
|
$("#videoPlayer")[0].srcObject = event.streams[0]; |
||||||
|
$("#videoPlayer")[0].play(); |
||||||
|
} |
||||||
|
this.webrtc.addTransceiver('video', { |
||||||
|
'direction': 'sendrecv' |
||||||
|
}); |
||||||
|
this.webrtcSendChannel = this.webrtc.createDataChannel('foo'); |
||||||
|
this.webrtcSendChannel.onclose = () => console.log('sendChannel has closed'); |
||||||
|
this.webrtcSendChannel.onopen = () => { |
||||||
|
console.log('sendChannel has opened'); |
||||||
|
this.webrtcSendChannel.send('ping'); |
||||||
|
this.webrtcSendChannelInterval = setInterval(() => { |
||||||
|
this.webrtcSendChannel.send('ping'); |
||||||
|
}, 1000) |
||||||
|
} |
||||||
|
|
||||||
|
this.webrtcSendChannel.onmessage = e => console.log(e.data); |
||||||
|
}, |
||||||
|
handleNegotiationNeeded: async function(){ |
||||||
|
var _this=rtspPlayer; |
||||||
|
|
||||||
|
offer = await _this.webrtc.createOffer(); |
||||||
|
await _this.webrtc.setLocalDescription(offer); |
||||||
|
$.post(_this.streamPlayUrl('webrtc'), { |
||||||
|
data: btoa(_this.webrtc.localDescription.sdp) |
||||||
|
}, function(data) { |
||||||
|
//console.log(data)
|
||||||
|
try { |
||||||
|
|
||||||
|
_this.webrtc.setRemoteDescription(new RTCSessionDescription({ |
||||||
|
type: 'answer', |
||||||
|
sdp: atob(data) |
||||||
|
})) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} catch (e) { |
||||||
|
console.warn(e); |
||||||
|
} |
||||||
|
|
||||||
|
}); |
||||||
|
}, |
||||||
|
playMse:function(){ |
||||||
|
//console.log(this.streamPlayUrl('mse'));
|
||||||
|
var _this=this; |
||||||
|
this.mse = new MediaSource(); |
||||||
|
$("#videoPlayer")[0].src=window.URL.createObjectURL(this.mse); |
||||||
|
this.mse.addEventListener('sourceopen', function(){ |
||||||
|
_this.ws=new WebSocket(_this.streamPlayUrl('mse')); |
||||||
|
_this.ws.binaryType = "arraybuffer"; |
||||||
|
_this.ws.onopen = function(event) { |
||||||
|
console.log('Connect to ws'); |
||||||
|
} |
||||||
|
|
||||||
|
_this.ws.onmessage = function(event) { |
||||||
|
var data = new Uint8Array(event.data); |
||||||
|
if (data[0] == 9) { |
||||||
|
decoded_arr=data.slice(1); |
||||||
|
if (window.TextDecoder) { |
||||||
|
mimeCodec = new TextDecoder("utf-8").decode(decoded_arr); |
||||||
|
} else { |
||||||
|
mimeCodec = Utf8ArrayToStr(decoded_arr); |
||||||
|
} |
||||||
|
console.log(mimeCodec); |
||||||
|
_this.mseSourceBuffer = _this.mse.addSourceBuffer('video/mp4; codecs="' + mimeCodec + '"'); |
||||||
|
_this.mseSourceBuffer.mode = "segments" |
||||||
|
_this.mseSourceBuffer.addEventListener("updateend", _this.pushPacket); |
||||||
|
|
||||||
|
} else { |
||||||
|
_this.readPacket(event.data); |
||||||
|
} |
||||||
|
}; |
||||||
|
}, false); |
||||||
|
|
||||||
|
}, |
||||||
|
readPacket:function(packet){ |
||||||
|
if (!this.mseStreamingStarted) { |
||||||
|
this.mseSourceBuffer.appendBuffer(packet); |
||||||
|
this.mseStreamingStarted = true; |
||||||
|
return; |
||||||
|
} |
||||||
|
this.mseQueue.push(packet); |
||||||
|
|
||||||
|
if (!this.mseSourceBuffer.updating) { |
||||||
|
this.pushPacket(); |
||||||
|
} |
||||||
|
}, |
||||||
|
pushPacket:function(){ |
||||||
|
var _this=rtspPlayer; |
||||||
|
if (!_this.mseSourceBuffer.updating) { |
||||||
|
if (_this.mseQueue.length > 0) { |
||||||
|
packet = _this.mseQueue.shift(); |
||||||
|
var view = new Uint8Array(packet); |
||||||
|
_this.mseSourceBuffer.appendBuffer(packet); |
||||||
|
} else { |
||||||
|
_this.mseStreamingStarted = false; |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
streamPlayUrl:function(type){ |
||||||
|
switch (type) { |
||||||
|
case 'hls': |
||||||
|
return '/stream/' + this.uuid + '/hls/live/index.m3u8'; |
||||||
|
break; |
||||||
|
case 'mse': |
||||||
|
var potocol = 'ws'; |
||||||
|
if (location.protocol == 'https:') { |
||||||
|
potocol = 'wss'; |
||||||
|
} |
||||||
|
return potocol+'://'+location.host+'/stream/' + this.uuid +'/mse?uuid='+this.uuid; |
||||||
|
//return 'ws://sr4.ipeye.ru/ws/mp4/live?name=d4ee855e40874ef7b7149357a42f18f0';
|
||||||
|
break; |
||||||
|
case 'webrtc': |
||||||
|
return "/stream/"+this.uuid+"/webrtc?uuid=" + this.uuid; |
||||||
|
break; |
||||||
|
default: |
||||||
|
return ''; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,531 @@ |
|||||||
|
$(document).ready(() => { |
||||||
|
localImages(); |
||||||
|
if (localStorage.getItem('defaultPlayer') != null) { |
||||||
|
$('input[name=defaultPlayer]').val([localStorage.getItem('defaultPlayer')]); |
||||||
|
} |
||||||
|
}) |
||||||
|
$('input[name=defaultPlayer]').on('change', function() { |
||||||
|
localStorage.setItem('defaultPlayer', $(this).val()); |
||||||
|
}) |
||||||
|
|
||||||
|
var activeStream = null; |
||||||
|
|
||||||
|
function showAddStream(streamName, streamUrl) { |
||||||
|
streamName = streamName || ''; |
||||||
|
streamUrl = streamUrl || ''; |
||||||
|
Swal.fire({ |
||||||
|
title: 'Add stream', |
||||||
|
html: '<form class="text-left"> ' + |
||||||
|
'<div class="form-group">' + |
||||||
|
'<label>Name</label>' + |
||||||
|
'<input type="text" class="form-control" id="stream-name">' + |
||||||
|
'<small class="form-text text-muted"></small>' + |
||||||
|
'</div>' + |
||||||
|
'<div class="form-group">' + |
||||||
|
' <label>URL</label>' + |
||||||
|
' <input type="text" class="form-control" id="stream-url">' + |
||||||
|
' </div>' + |
||||||
|
'<div class="form-group form-check">' + |
||||||
|
'<input type="checkbox" class="form-check-input" id="stream-ondemand">' + |
||||||
|
'<label class="form-check-label">ondemand</label>' + |
||||||
|
'</div>' + |
||||||
|
'</form>', |
||||||
|
focusConfirm: true, |
||||||
|
showCancelButton: true, |
||||||
|
preConfirm: () => { |
||||||
|
var uuid = randomUuid(), |
||||||
|
name = $('#stream-name').val(), |
||||||
|
url = $('#stream-url').val(), |
||||||
|
ondemand = $('#stream-ondemand').val(); |
||||||
|
if (!validURL(url)) { |
||||||
|
Swal.fire({ |
||||||
|
icon: 'error', |
||||||
|
title: 'Oops...', |
||||||
|
text: 'wrong url', |
||||||
|
confirmButtonText: 'return back', |
||||||
|
preConfirm: () => { |
||||||
|
showAddStream(name, url) |
||||||
|
} |
||||||
|
}) |
||||||
|
} else { |
||||||
|
goRequest('add', uuid, { |
||||||
|
name: name, |
||||||
|
url: url, |
||||||
|
ondemand: ondemand |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
function showEditStream(uuid) { |
||||||
|
console.log(streams[uuid]); |
||||||
|
} |
||||||
|
|
||||||
|
function deleteStream(uuid) { |
||||||
|
activeStream = uuid; |
||||||
|
Swal.fire({ |
||||||
|
title: 'Are you sure?', |
||||||
|
text: "Do you want delete stream " + streams[uuid].name + " ?", |
||||||
|
icon: 'warning', |
||||||
|
showCancelButton: true, |
||||||
|
confirmButtonColor: '#3085d6', |
||||||
|
cancelButtonColor: '#d33', |
||||||
|
confirmButtonText: 'Yes, delete it!' |
||||||
|
}).then((result) => { |
||||||
|
if (result.value) { |
||||||
|
goRequest('delete', uuid) |
||||||
|
|
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
function renewStreamlist() { |
||||||
|
goRequest('streams'); |
||||||
|
} |
||||||
|
|
||||||
|
function goRequest(method, uuid, data) { |
||||||
|
data = data || null; |
||||||
|
uuid = uuid || null; |
||||||
|
var path = ''; |
||||||
|
var type = 'GET'; |
||||||
|
switch (method) { |
||||||
|
case 'add': |
||||||
|
path = '/stream/' + uuid + '/add'; |
||||||
|
type = 'POST'; |
||||||
|
break; |
||||||
|
case 'edit': |
||||||
|
path = '/stream/' + uuid + '/edit'; |
||||||
|
type = 'POST'; |
||||||
|
break; |
||||||
|
case 'delete': |
||||||
|
path = '/stream/' + uuid + '/delete'; |
||||||
|
break; |
||||||
|
case 'reload': |
||||||
|
path = '/stream/' + uuid + '/reload'; |
||||||
|
break; |
||||||
|
case 'info': |
||||||
|
path = '/stream/' + uuid + '/info'; |
||||||
|
break; |
||||||
|
case 'streams': |
||||||
|
path = '/streams'; |
||||||
|
break; |
||||||
|
default: |
||||||
|
path = ''; |
||||||
|
type = 'GET'; |
||||||
|
} |
||||||
|
if (path == '') { |
||||||
|
Swal.fire({ |
||||||
|
icon: 'error', |
||||||
|
title: 'Oops...', |
||||||
|
text: 'It`s goRequest function mistake', |
||||||
|
confirmButtonText: 'Close', |
||||||
|
|
||||||
|
}) |
||||||
|
return; |
||||||
|
} |
||||||
|
var ajaxParam = { |
||||||
|
url: path, |
||||||
|
type: type, |
||||||
|
dataType: 'json', |
||||||
|
beforeSend: function(xhr) { |
||||||
|
xhr.setRequestHeader("Authorization", "Basic " + btoa("demo:demo")); |
||||||
|
}, |
||||||
|
success: function(response) { |
||||||
|
goRequestHandle(method, response, uuid); |
||||||
|
}, |
||||||
|
error: function(e) { |
||||||
|
console.log(e); |
||||||
|
} |
||||||
|
}; |
||||||
|
if (data != null) { |
||||||
|
ajaxParam.data = JSON.stringify(data); |
||||||
|
} |
||||||
|
$.ajax(ajaxParam); |
||||||
|
} |
||||||
|
|
||||||
|
function goRequestHandle(method, response, uuid) { |
||||||
|
switch (method) { |
||||||
|
case 'add': |
||||||
|
|
||||||
|
if (response.status == 1) { |
||||||
|
renewStreamlist(); |
||||||
|
Swal.fire( |
||||||
|
'Added!', |
||||||
|
'Your stream has been Added.', |
||||||
|
'success' |
||||||
|
); |
||||||
|
|
||||||
|
} else { |
||||||
|
Swal.fire({ |
||||||
|
icon: 'error', |
||||||
|
title: 'Oops...', |
||||||
|
text: 'Same mistake issset', |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
break; |
||||||
|
case 'edit': |
||||||
|
if (response.status == 1) { |
||||||
|
renewStreamlist(); |
||||||
|
Swal.fire( |
||||||
|
'Success!', |
||||||
|
'Your stream has been modified.', |
||||||
|
'success' |
||||||
|
); |
||||||
|
} else { |
||||||
|
Swal.fire({ |
||||||
|
icon: 'error', |
||||||
|
title: 'Oops...', |
||||||
|
text: 'Same mistake issset', |
||||||
|
}) |
||||||
|
} |
||||||
|
break; |
||||||
|
case 'delete': |
||||||
|
|
||||||
|
if (response.status == 1) { |
||||||
|
$('#' + uuid).remove(); |
||||||
|
delete(streams[uuid]); |
||||||
|
$('#stream-counter').html(Object.keys(streams).length); |
||||||
|
Swal.fire( |
||||||
|
'Deleted!', |
||||||
|
'Your stream has been deleted.', |
||||||
|
'success' |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
break; |
||||||
|
case 'reload': |
||||||
|
|
||||||
|
break; |
||||||
|
case 'info': |
||||||
|
|
||||||
|
break; |
||||||
|
case 'streams': |
||||||
|
if (response.status == 1) { |
||||||
|
streams = response.payload; |
||||||
|
$('#stream-counter').html(Object.keys(streams).length); |
||||||
|
if (Object.keys(streams).length > 0) { |
||||||
|
|
||||||
|
$.each(streams, function(uuid, param) { |
||||||
|
if ($('#' + uuid).length == 0) { |
||||||
|
$('.streams').append(streamHtmlTemplate(uuid, param.name)); |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
break; |
||||||
|
default: |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
function getImageBase64(videoEl){ |
||||||
|
const canvas = document.createElement("canvas"); |
||||||
|
canvas.width = videoEl.videoWidth; |
||||||
|
canvas.height = videoEl.videoHeight; |
||||||
|
canvas.getContext('2d').drawImage(videoEl, 0, 0, canvas.width, canvas.height); |
||||||
|
const dataURL = canvas.toDataURL(); |
||||||
|
canvas.remove(); |
||||||
|
return dataURL; |
||||||
|
} |
||||||
|
|
||||||
|
function downloadBase64Image(base64Data){ |
||||||
|
const a = document.createElement("a"); |
||||||
|
a.href = base64Data; |
||||||
|
a.download = "screenshot.png"; |
||||||
|
a.click(); |
||||||
|
a.remove(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
function makePic(video_element, uuid, chan) { |
||||||
|
if (typeof(video_element) === "undefined") { |
||||||
|
video_element = $("#videoPlayer")[0]; |
||||||
|
} |
||||||
|
ratio = video_element.videoWidth / video_element.videoHeight; |
||||||
|
w = 400; |
||||||
|
h = parseInt(w / ratio, 10); |
||||||
|
$('#canvas')[0].width = w; |
||||||
|
$('#canvas')[0].height = h; |
||||||
|
$('#canvas')[0].getContext('2d').fillRect(0, 0, w, h); |
||||||
|
$('#canvas')[0].getContext('2d').drawImage(video_element, 0, 0, w, h); |
||||||
|
var imageData = $('#canvas')[0].toDataURL(); |
||||||
|
var images = localStorage.getItem('imagesNew'); |
||||||
|
if (images != null) { |
||||||
|
images = JSON.parse(images); |
||||||
|
} else { |
||||||
|
images = {}; |
||||||
|
} |
||||||
|
var uid = $('#uuid').val(); |
||||||
|
if (!!uuid) { |
||||||
|
uid = uuid; |
||||||
|
} |
||||||
|
|
||||||
|
var channel = $('#channel').val() || chan || 0; |
||||||
|
if (typeof(images[uid]) === "undefined") { |
||||||
|
images[uid] = {}; |
||||||
|
} |
||||||
|
images[uid][channel] = imageData; |
||||||
|
localStorage.setItem('imagesNew', JSON.stringify(images)); |
||||||
|
$('#' + uid).find('.stream-img[channel="' + channel + '"]').attr('src', imageData); |
||||||
|
} |
||||||
|
|
||||||
|
function localImages() { |
||||||
|
var images = localStorage.getItem('imagesNew'); |
||||||
|
if (images != null) { |
||||||
|
images = JSON.parse(images); |
||||||
|
$.each(images, function(k, v) { |
||||||
|
$.each(v, function(channel, img) { |
||||||
|
$('#' + k).find('.stream-img[channel="' + channel + '"]').attr('src', img); |
||||||
|
}) |
||||||
|
|
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function clearLocalImg() { |
||||||
|
localStorage.setItem('imagesNew', '{}'); |
||||||
|
} |
||||||
|
|
||||||
|
function streamHtmlTemplate(uuid, name) { |
||||||
|
return '<div class="item" id="' + uuid + '">' + |
||||||
|
'<div class="stream">' + |
||||||
|
'<div class="thumbs" onclick="rtspPlayer.livePlayer(0, \'' + uuid + '\')">' + |
||||||
|
'<img src="../static/img/noimage.svg" alt="" class="stream-img">' + |
||||||
|
'</div>' + |
||||||
|
'<div class="text">' + |
||||||
|
'<h5>' + name + '</h5>' + |
||||||
|
'<p>property</p>' + |
||||||
|
'<div class="input-group-prepend dropleft text-muted">' + |
||||||
|
'<a class="btn" data-toggle="dropdown" >' + |
||||||
|
'<i class="fas fa-ellipsis-v"></i>' + |
||||||
|
'</a>' + |
||||||
|
'<div class="dropdown-menu">' + |
||||||
|
'<a class="dropdown-item" onclick="rtspPlayer.livePlayer(\'hls\', \'' + uuid + '\')" href="#">Play HLS</a>' + |
||||||
|
'<a class="dropdown-item" onclick="rtspPlayer.livePlayer(\'mse\', \'' + uuid + '\')" href="#">Play MSE</a>' + |
||||||
|
'<a class="dropdown-item" onclick="rtspPlayer.livePlayer(\'webrtc\', \'' + uuid + '\')" href="#">Play WebRTC</a>' + |
||||||
|
'<div class="dropdown-divider"></div>' + |
||||||
|
'<a class="dropdown-item" onclick="showEditStream(\'' + uuid + '\')" href="#">Edit</a>' + |
||||||
|
'<a class="dropdown-item" onclick="deleteStream(\'' + uuid + '\')" href="#">Delete</a>' + |
||||||
|
'</div>' + |
||||||
|
'</div>' + |
||||||
|
'</div>' + |
||||||
|
'</div>' + |
||||||
|
'</div>'; |
||||||
|
} |
||||||
|
|
||||||
|
function randomUuid() { |
||||||
|
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => |
||||||
|
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
function validURL(url) { |
||||||
|
//TODO: fix it
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
function Utf8ArrayToStr(array) { |
||||||
|
var out, i, len, c; |
||||||
|
var char2, char3; |
||||||
|
out = ""; |
||||||
|
len = array.length; |
||||||
|
i = 0; |
||||||
|
while (i < len) { |
||||||
|
c = array[i++]; |
||||||
|
switch (c >> 4) { |
||||||
|
case 7: |
||||||
|
out += String.fromCharCode(c); |
||||||
|
break; |
||||||
|
case 13: |
||||||
|
char2 = array[i++]; |
||||||
|
out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F)); |
||||||
|
break; |
||||||
|
case 14: |
||||||
|
char2 = array[i++]; |
||||||
|
char3 = array[i++]; |
||||||
|
out += String.fromCharCode(((c & 0x0F) << 12) | |
||||||
|
((char2 & 0x3F) << 6) | |
||||||
|
((char3 & 0x3F) << 0)); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
return out; |
||||||
|
} |
||||||
|
|
||||||
|
function browserDetector() { |
||||||
|
var Browser; |
||||||
|
var ua = self.navigator.userAgent.toLowerCase(); |
||||||
|
var match = |
||||||
|
/(edge)\/([\w.]+)/.exec(ua) || |
||||||
|
/(opr)[\/]([\w.]+)/.exec(ua) || |
||||||
|
/(chrome)[ \/]([\w.]+)/.exec(ua) || |
||||||
|
/(iemobile)[\/]([\w.]+)/.exec(ua) || |
||||||
|
/(version)(applewebkit)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec(ua) || |
||||||
|
/(webkit)[ \/]([\w.]+).*(version)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec( |
||||||
|
ua |
||||||
|
) || |
||||||
|
/(webkit)[ \/]([\w.]+)/.exec(ua) || |
||||||
|
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || |
||||||
|
/(msie) ([\w.]+)/.exec(ua) || |
||||||
|
(ua.indexOf("trident") >= 0 && /(rv)(?::| )([\w.]+)/.exec(ua)) || |
||||||
|
(ua.indexOf("compatible") < 0 && /(firefox)[ \/]([\w.]+)/.exec(ua)) || []; |
||||||
|
var platform_match = |
||||||
|
/(ipad)/.exec(ua) || |
||||||
|
/(ipod)/.exec(ua) || |
||||||
|
/(windows phone)/.exec(ua) || |
||||||
|
/(iphone)/.exec(ua) || |
||||||
|
/(kindle)/.exec(ua) || |
||||||
|
/(android)/.exec(ua) || |
||||||
|
/(windows)/.exec(ua) || |
||||||
|
/(mac)/.exec(ua) || |
||||||
|
/(linux)/.exec(ua) || |
||||||
|
/(cros)/.exec(ua) || []; |
||||||
|
var matched = { |
||||||
|
browser: match[5] || match[3] || match[1] || "", |
||||||
|
version: match[2] || match[4] || "0", |
||||||
|
majorVersion: match[4] || match[2] || "0", |
||||||
|
platform: platform_match[0] || "" |
||||||
|
}; |
||||||
|
var browser = {}; |
||||||
|
|
||||||
|
if (matched.browser) { |
||||||
|
browser[matched.browser] = true; |
||||||
|
var versionArray = matched.majorVersion.split("."); |
||||||
|
browser.version = { |
||||||
|
major: parseInt(matched.majorVersion, 10), |
||||||
|
string: matched.version |
||||||
|
}; |
||||||
|
|
||||||
|
if (versionArray.length > 1) { |
||||||
|
browser.version.minor = parseInt(versionArray[1], 10); |
||||||
|
} |
||||||
|
|
||||||
|
if (versionArray.length > 2) { |
||||||
|
browser.version.build = parseInt(versionArray[2], 10); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (matched.platform) { |
||||||
|
browser[matched.platform] = true; |
||||||
|
} |
||||||
|
|
||||||
|
if (browser.chrome || browser.opr || browser.safari) { |
||||||
|
browser.webkit = true; |
||||||
|
} // MSIE. IE11 has 'rv' identifer
|
||||||
|
|
||||||
|
if (browser.rv || browser.iemobile) { |
||||||
|
if (browser.rv) { |
||||||
|
delete browser.rv; |
||||||
|
} |
||||||
|
|
||||||
|
var msie = "msie"; |
||||||
|
matched.browser = msie; |
||||||
|
browser[msie] = true; |
||||||
|
} // Microsoft Edge
|
||||||
|
|
||||||
|
if (browser.edge) { |
||||||
|
delete browser.edge; |
||||||
|
var msedge = "msedge"; |
||||||
|
matched.browser = msedge; |
||||||
|
browser[msedge] = true; |
||||||
|
} // Opera 15+
|
||||||
|
|
||||||
|
if (browser.opr) { |
||||||
|
var opera = "opera"; |
||||||
|
matched.browser = opera; |
||||||
|
browser[opera] = true; |
||||||
|
} // Stock android browsers are marked as Safari
|
||||||
|
|
||||||
|
if (browser.safari && browser.android) { |
||||||
|
var android = "android"; |
||||||
|
matched.browser = android; |
||||||
|
browser[android] = true; |
||||||
|
} |
||||||
|
|
||||||
|
browser.name = matched.browser; |
||||||
|
browser.platform = matched.platform; |
||||||
|
|
||||||
|
|
||||||
|
return browser; |
||||||
|
} |
||||||
|
|
||||||
|
function addChannel() { |
||||||
|
$('#streams-form-wrapper').append(chanellTemplate()); |
||||||
|
} |
||||||
|
|
||||||
|
function chanellTemplate() { |
||||||
|
let random = Math.ceil(Math.random() * 1000); |
||||||
|
let html = ` |
||||||
|
<div class="col-12"> |
||||||
|
<div class="card card-secondary"> |
||||||
|
<div class="card-header"> |
||||||
|
<h3 class="card-title">Sub channel<small> parameters</small></h3> |
||||||
|
<div class="card-tools"> |
||||||
|
<button type="button" class="btn btn-tool" onclick="removeChannelDiv(this)"><i class="fas fa-times"></i></button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="card-body"> |
||||||
|
<form class="stream-form"> |
||||||
|
<div class="form-group"> |
||||||
|
<label for="exampleInputPassword1">Substream url</label> |
||||||
|
<input type="text" name="stream-url" class="form-control" placeholder="Enter stream url" > |
||||||
|
<small class="form-text text-muted">Enter rtsp address as instructed by your camera. Look like <code>rtsp://<ip>:<port>/path </code> </small>
|
||||||
|
</div> |
||||||
|
<div class="form-group"> |
||||||
|
<label for="inputStatus">Substream type</label> |
||||||
|
<select class="form-control custom-select" name="stream-ondemand" > |
||||||
|
<option selected disabled><small>Select One</small></option> |
||||||
|
<option value="1">On demand only</option> |
||||||
|
<option value="0">Persistent connection</option> |
||||||
|
</select> |
||||||
|
<small class="form-text text-muted">On persistent connection, the server get data from the camera continuously. On demand, the server get data from the camera only when you click play button </small> |
||||||
|
</div> |
||||||
|
<div class="form-group"> |
||||||
|
<div class="custom-control custom-switch"> |
||||||
|
<input type="checkbox" class="custom-control-input" name="debug" id="substream-debug-switch-` + random + `" > |
||||||
|
<label class="custom-control-label" for="substream-debug-switch-` + random + `">Enable debug</label> |
||||||
|
</div> |
||||||
|
<small class="form-text text-muted">Select this options if you want get more data about the stream </small> |
||||||
|
</div> |
||||||
|
</form> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div>`; |
||||||
|
return html; |
||||||
|
} |
||||||
|
|
||||||
|
function removeChannelDiv(element) { |
||||||
|
$(element).closest('.col-12').remove(); |
||||||
|
} |
||||||
|
|
||||||
|
function logger() { |
||||||
|
if (!colordebug) { |
||||||
|
return; |
||||||
|
} |
||||||
|
let colors = { |
||||||
|
"0": "color:green", |
||||||
|
"1": "color:#66CDAA", |
||||||
|
"2": "color:blue", |
||||||
|
"3": "color:#FF1493", |
||||||
|
"4": "color:#40E0D0", |
||||||
|
"5": "color:red", |
||||||
|
"6": "color:red", |
||||||
|
"7": "color:red", |
||||||
|
"8": "color:red", |
||||||
|
"9": "color:red", |
||||||
|
"10": "color:red", |
||||||
|
"11": "color:red", |
||||||
|
"12": "color:red", |
||||||
|
"13": "color:red", |
||||||
|
"14": "color:red", |
||||||
|
"15": "color:red", |
||||||
|
} |
||||||
|
console.log('%c%s', colors[arguments[0]], new Date().toLocaleString() + " " + [].slice.call(arguments).join('|')) |
||||||
|
} |
||||||
@ -0,0 +1,325 @@ |
|||||||
|
/*! |
||||||
|
* Bootstrap Reboot v4.5.1 (https://getbootstrap.com/) |
||||||
|
* Copyright 2011-2020 The Bootstrap Authors |
||||||
|
* Copyright 2011-2020 Twitter, Inc. |
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) |
||||||
|
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) |
||||||
|
*/ |
||||||
|
*, |
||||||
|
*::before, |
||||||
|
*::after { |
||||||
|
box-sizing: border-box; |
||||||
|
} |
||||||
|
|
||||||
|
html { |
||||||
|
font-family: sans-serif; |
||||||
|
line-height: 1.15; |
||||||
|
-webkit-text-size-adjust: 100%; |
||||||
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0); |
||||||
|
} |
||||||
|
|
||||||
|
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section { |
||||||
|
display: block; |
||||||
|
} |
||||||
|
|
||||||
|
body { |
||||||
|
margin: 0; |
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; |
||||||
|
font-size: 1rem; |
||||||
|
font-weight: 400; |
||||||
|
line-height: 1.5; |
||||||
|
color: #212529; |
||||||
|
text-align: left; |
||||||
|
background-color: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
[tabindex="-1"]:focus:not(:focus-visible) { |
||||||
|
outline: 0 !important; |
||||||
|
} |
||||||
|
|
||||||
|
hr { |
||||||
|
box-sizing: content-box; |
||||||
|
height: 0; |
||||||
|
overflow: visible; |
||||||
|
} |
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 { |
||||||
|
margin-top: 0; |
||||||
|
margin-bottom: 0.5rem; |
||||||
|
} |
||||||
|
|
||||||
|
p { |
||||||
|
margin-top: 0; |
||||||
|
margin-bottom: 1rem; |
||||||
|
} |
||||||
|
|
||||||
|
abbr[title], |
||||||
|
abbr[data-original-title] { |
||||||
|
text-decoration: underline; |
||||||
|
-webkit-text-decoration: underline dotted; |
||||||
|
text-decoration: underline dotted; |
||||||
|
cursor: help; |
||||||
|
border-bottom: 0; |
||||||
|
-webkit-text-decoration-skip-ink: none; |
||||||
|
text-decoration-skip-ink: none; |
||||||
|
} |
||||||
|
|
||||||
|
address { |
||||||
|
margin-bottom: 1rem; |
||||||
|
font-style: normal; |
||||||
|
line-height: inherit; |
||||||
|
} |
||||||
|
|
||||||
|
ol, |
||||||
|
ul, |
||||||
|
dl { |
||||||
|
margin-top: 0; |
||||||
|
margin-bottom: 1rem; |
||||||
|
} |
||||||
|
|
||||||
|
ol ol, |
||||||
|
ul ul, |
||||||
|
ol ul, |
||||||
|
ul ol { |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
|
||||||
|
dt { |
||||||
|
font-weight: 700; |
||||||
|
} |
||||||
|
|
||||||
|
dd { |
||||||
|
margin-bottom: .5rem; |
||||||
|
margin-left: 0; |
||||||
|
} |
||||||
|
|
||||||
|
blockquote { |
||||||
|
margin: 0 0 1rem; |
||||||
|
} |
||||||
|
|
||||||
|
b, |
||||||
|
strong { |
||||||
|
font-weight: bolder; |
||||||
|
} |
||||||
|
|
||||||
|
small { |
||||||
|
font-size: 80%; |
||||||
|
} |
||||||
|
|
||||||
|
sub, |
||||||
|
sup { |
||||||
|
position: relative; |
||||||
|
font-size: 75%; |
||||||
|
line-height: 0; |
||||||
|
vertical-align: baseline; |
||||||
|
} |
||||||
|
|
||||||
|
sub { |
||||||
|
bottom: -.25em; |
||||||
|
} |
||||||
|
|
||||||
|
sup { |
||||||
|
top: -.5em; |
||||||
|
} |
||||||
|
|
||||||
|
a { |
||||||
|
color: #007bff; |
||||||
|
text-decoration: none; |
||||||
|
background-color: transparent; |
||||||
|
} |
||||||
|
|
||||||
|
a:hover { |
||||||
|
color: #0056b3; |
||||||
|
text-decoration: underline; |
||||||
|
} |
||||||
|
|
||||||
|
a:not([href]):not([class]) { |
||||||
|
color: inherit; |
||||||
|
text-decoration: none; |
||||||
|
} |
||||||
|
|
||||||
|
a:not([href]):not([class]):hover { |
||||||
|
color: inherit; |
||||||
|
text-decoration: none; |
||||||
|
} |
||||||
|
|
||||||
|
pre, |
||||||
|
code, |
||||||
|
kbd, |
||||||
|
samp { |
||||||
|
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; |
||||||
|
font-size: 1em; |
||||||
|
} |
||||||
|
|
||||||
|
pre { |
||||||
|
margin-top: 0; |
||||||
|
margin-bottom: 1rem; |
||||||
|
overflow: auto; |
||||||
|
-ms-overflow-style: scrollbar; |
||||||
|
} |
||||||
|
|
||||||
|
figure { |
||||||
|
margin: 0 0 1rem; |
||||||
|
} |
||||||
|
|
||||||
|
img { |
||||||
|
vertical-align: middle; |
||||||
|
border-style: none; |
||||||
|
} |
||||||
|
|
||||||
|
svg { |
||||||
|
overflow: hidden; |
||||||
|
vertical-align: middle; |
||||||
|
} |
||||||
|
|
||||||
|
table { |
||||||
|
border-collapse: collapse; |
||||||
|
} |
||||||
|
|
||||||
|
caption { |
||||||
|
padding-top: 0.75rem; |
||||||
|
padding-bottom: 0.75rem; |
||||||
|
color: #6c757d; |
||||||
|
text-align: left; |
||||||
|
caption-side: bottom; |
||||||
|
} |
||||||
|
|
||||||
|
th { |
||||||
|
text-align: inherit; |
||||||
|
} |
||||||
|
|
||||||
|
label { |
||||||
|
display: inline-block; |
||||||
|
margin-bottom: 0.5rem; |
||||||
|
} |
||||||
|
|
||||||
|
button { |
||||||
|
border-radius: 0; |
||||||
|
} |
||||||
|
|
||||||
|
button:focus { |
||||||
|
outline: 1px dotted; |
||||||
|
outline: 5px auto -webkit-focus-ring-color; |
||||||
|
} |
||||||
|
|
||||||
|
input, |
||||||
|
button, |
||||||
|
select, |
||||||
|
optgroup, |
||||||
|
textarea { |
||||||
|
margin: 0; |
||||||
|
font-family: inherit; |
||||||
|
font-size: inherit; |
||||||
|
line-height: inherit; |
||||||
|
} |
||||||
|
|
||||||
|
button, |
||||||
|
input { |
||||||
|
overflow: visible; |
||||||
|
} |
||||||
|
|
||||||
|
button, |
||||||
|
select { |
||||||
|
text-transform: none; |
||||||
|
} |
||||||
|
|
||||||
|
[role="button"] { |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
|
||||||
|
select { |
||||||
|
word-wrap: normal; |
||||||
|
} |
||||||
|
|
||||||
|
button, |
||||||
|
[type="button"], |
||||||
|
[type="reset"], |
||||||
|
[type="submit"] { |
||||||
|
-webkit-appearance: button; |
||||||
|
} |
||||||
|
|
||||||
|
button:not(:disabled), |
||||||
|
[type="button"]:not(:disabled), |
||||||
|
[type="reset"]:not(:disabled), |
||||||
|
[type="submit"]:not(:disabled) { |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
|
||||||
|
button::-moz-focus-inner, |
||||||
|
[type="button"]::-moz-focus-inner, |
||||||
|
[type="reset"]::-moz-focus-inner, |
||||||
|
[type="submit"]::-moz-focus-inner { |
||||||
|
padding: 0; |
||||||
|
border-style: none; |
||||||
|
} |
||||||
|
|
||||||
|
input[type="radio"], |
||||||
|
input[type="checkbox"] { |
||||||
|
box-sizing: border-box; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
textarea { |
||||||
|
overflow: auto; |
||||||
|
resize: vertical; |
||||||
|
} |
||||||
|
|
||||||
|
fieldset { |
||||||
|
min-width: 0; |
||||||
|
padding: 0; |
||||||
|
margin: 0; |
||||||
|
border: 0; |
||||||
|
} |
||||||
|
|
||||||
|
legend { |
||||||
|
display: block; |
||||||
|
width: 100%; |
||||||
|
max-width: 100%; |
||||||
|
padding: 0; |
||||||
|
margin-bottom: .5rem; |
||||||
|
font-size: 1.5rem; |
||||||
|
line-height: inherit; |
||||||
|
color: inherit; |
||||||
|
white-space: normal; |
||||||
|
} |
||||||
|
|
||||||
|
progress { |
||||||
|
vertical-align: baseline; |
||||||
|
} |
||||||
|
|
||||||
|
[type="number"]::-webkit-inner-spin-button, |
||||||
|
[type="number"]::-webkit-outer-spin-button { |
||||||
|
height: auto; |
||||||
|
} |
||||||
|
|
||||||
|
[type="search"] { |
||||||
|
outline-offset: -2px; |
||||||
|
-webkit-appearance: none; |
||||||
|
} |
||||||
|
|
||||||
|
[type="search"]::-webkit-search-decoration { |
||||||
|
-webkit-appearance: none; |
||||||
|
} |
||||||
|
|
||||||
|
::-webkit-file-upload-button { |
||||||
|
font: inherit; |
||||||
|
-webkit-appearance: button; |
||||||
|
} |
||||||
|
|
||||||
|
output { |
||||||
|
display: inline-block; |
||||||
|
} |
||||||
|
|
||||||
|
summary { |
||||||
|
display: list-item; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
|
||||||
|
template { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
[hidden] { |
||||||
|
display: none !important; |
||||||
|
} |
||||||
|
/*# sourceMappingURL=bootstrap-reboot.css.map */ |
||||||
@ -0,0 +1,8 @@ |
|||||||
|
/*! |
||||||
|
* Bootstrap Reboot v4.5.1 (https://getbootstrap.com/) |
||||||
|
* Copyright 2011-2020 The Bootstrap Authors |
||||||
|
* Copyright 2011-2020 Twitter, Inc. |
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) |
||||||
|
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) |
||||||
|
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important} |
||||||
|
/*# sourceMappingURL=bootstrap-reboot.min.css.map */ |
||||||
@ -0,0 +1,15 @@ |
|||||||
|
/*! |
||||||
|
* Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com |
||||||
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) |
||||||
|
*/ |
||||||
|
@font-face { |
||||||
|
font-family: 'Font Awesome 5 Brands'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 400; |
||||||
|
font-display: block; |
||||||
|
src: url("../webfonts/fa-brands-400.eot"); |
||||||
|
src: url("../webfonts/fa-brands-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.woff") format("woff"), url("../webfonts/fa-brands-400.ttf") format("truetype"), url("../webfonts/fa-brands-400.svg#fontawesome") format("svg"); } |
||||||
|
|
||||||
|
.fab { |
||||||
|
font-family: 'Font Awesome 5 Brands'; |
||||||
|
font-weight: 400; } |
||||||
@ -0,0 +1,5 @@ |
|||||||
|
/*! |
||||||
|
* Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com |
||||||
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) |
||||||
|
*/ |
||||||
|
@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:"Font Awesome 5 Brands";font-weight:400} |
||||||
@ -0,0 +1,15 @@ |
|||||||
|
/*! |
||||||
|
* Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com |
||||||
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) |
||||||
|
*/ |
||||||
|
@font-face { |
||||||
|
font-family: 'Font Awesome 5 Free'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 400; |
||||||
|
font-display: block; |
||||||
|
src: url("../webfonts/fa-regular-400.eot"); |
||||||
|
src: url("../webfonts/fa-regular-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.woff") format("woff"), url("../webfonts/fa-regular-400.ttf") format("truetype"), url("../webfonts/fa-regular-400.svg#fontawesome") format("svg"); } |
||||||
|
|
||||||
|
.far { |
||||||
|
font-family: 'Font Awesome 5 Free'; |
||||||
|
font-weight: 400; } |
||||||
@ -0,0 +1,5 @@ |
|||||||
|
/*! |
||||||
|
* Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com |
||||||
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) |
||||||
|
*/ |
||||||
|
@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.far{font-family:"Font Awesome 5 Free";font-weight:400} |
||||||
@ -0,0 +1,16 @@ |
|||||||
|
/*! |
||||||
|
* Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com |
||||||
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) |
||||||
|
*/ |
||||||
|
@font-face { |
||||||
|
font-family: 'Font Awesome 5 Free'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 900; |
||||||
|
font-display: block; |
||||||
|
src: url("../webfonts/fa-solid-900.eot"); |
||||||
|
src: url("../webfonts/fa-solid-900.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.woff") format("woff"), url("../webfonts/fa-solid-900.ttf") format("truetype"), url("../webfonts/fa-solid-900.svg#fontawesome") format("svg"); } |
||||||
|
|
||||||
|
.fa, |
||||||
|
.fas { |
||||||
|
font-family: 'Font Awesome 5 Free'; |
||||||
|
font-weight: 900; } |
||||||
@ -0,0 +1,5 @@ |
|||||||
|
/*! |
||||||
|
* Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com |
||||||
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) |
||||||
|
*/ |
||||||
|
@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.fas{font-family:"Font Awesome 5 Free";font-weight:900} |
||||||
@ -0,0 +1,371 @@ |
|||||||
|
/*! |
||||||
|
* Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com |
||||||
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) |
||||||
|
*/ |
||||||
|
svg:not(:root).svg-inline--fa { |
||||||
|
overflow: visible; } |
||||||
|
|
||||||
|
.svg-inline--fa { |
||||||
|
display: inline-block; |
||||||
|
font-size: inherit; |
||||||
|
height: 1em; |
||||||
|
overflow: visible; |
||||||
|
vertical-align: -.125em; } |
||||||
|
.svg-inline--fa.fa-lg { |
||||||
|
vertical-align: -.225em; } |
||||||
|
.svg-inline--fa.fa-w-1 { |
||||||
|
width: 0.0625em; } |
||||||
|
.svg-inline--fa.fa-w-2 { |
||||||
|
width: 0.125em; } |
||||||
|
.svg-inline--fa.fa-w-3 { |
||||||
|
width: 0.1875em; } |
||||||
|
.svg-inline--fa.fa-w-4 { |
||||||
|
width: 0.25em; } |
||||||
|
.svg-inline--fa.fa-w-5 { |
||||||
|
width: 0.3125em; } |
||||||
|
.svg-inline--fa.fa-w-6 { |
||||||
|
width: 0.375em; } |
||||||
|
.svg-inline--fa.fa-w-7 { |
||||||
|
width: 0.4375em; } |
||||||
|
.svg-inline--fa.fa-w-8 { |
||||||
|
width: 0.5em; } |
||||||
|
.svg-inline--fa.fa-w-9 { |
||||||
|
width: 0.5625em; } |
||||||
|
.svg-inline--fa.fa-w-10 { |
||||||
|
width: 0.625em; } |
||||||
|
.svg-inline--fa.fa-w-11 { |
||||||
|
width: 0.6875em; } |
||||||
|
.svg-inline--fa.fa-w-12 { |
||||||
|
width: 0.75em; } |
||||||
|
.svg-inline--fa.fa-w-13 { |
||||||
|
width: 0.8125em; } |
||||||
|
.svg-inline--fa.fa-w-14 { |
||||||
|
width: 0.875em; } |
||||||
|
.svg-inline--fa.fa-w-15 { |
||||||
|
width: 0.9375em; } |
||||||
|
.svg-inline--fa.fa-w-16 { |
||||||
|
width: 1em; } |
||||||
|
.svg-inline--fa.fa-w-17 { |
||||||
|
width: 1.0625em; } |
||||||
|
.svg-inline--fa.fa-w-18 { |
||||||
|
width: 1.125em; } |
||||||
|
.svg-inline--fa.fa-w-19 { |
||||||
|
width: 1.1875em; } |
||||||
|
.svg-inline--fa.fa-w-20 { |
||||||
|
width: 1.25em; } |
||||||
|
.svg-inline--fa.fa-pull-left { |
||||||
|
margin-right: .3em; |
||||||
|
width: auto; } |
||||||
|
.svg-inline--fa.fa-pull-right { |
||||||
|
margin-left: .3em; |
||||||
|
width: auto; } |
||||||
|
.svg-inline--fa.fa-border { |
||||||
|
height: 1.5em; } |
||||||
|
.svg-inline--fa.fa-li { |
||||||
|
width: 2em; } |
||||||
|
.svg-inline--fa.fa-fw { |
||||||
|
width: 1.25em; } |
||||||
|
|
||||||
|
.fa-layers svg.svg-inline--fa { |
||||||
|
bottom: 0; |
||||||
|
left: 0; |
||||||
|
margin: auto; |
||||||
|
position: absolute; |
||||||
|
right: 0; |
||||||
|
top: 0; } |
||||||
|
|
||||||
|
.fa-layers { |
||||||
|
display: inline-block; |
||||||
|
height: 1em; |
||||||
|
position: relative; |
||||||
|
text-align: center; |
||||||
|
vertical-align: -.125em; |
||||||
|
width: 1em; } |
||||||
|
.fa-layers svg.svg-inline--fa { |
||||||
|
-webkit-transform-origin: center center; |
||||||
|
transform-origin: center center; } |
||||||
|
|
||||||
|
.fa-layers-text, .fa-layers-counter { |
||||||
|
display: inline-block; |
||||||
|
position: absolute; |
||||||
|
text-align: center; } |
||||||
|
|
||||||
|
.fa-layers-text { |
||||||
|
left: 50%; |
||||||
|
top: 50%; |
||||||
|
-webkit-transform: translate(-50%, -50%); |
||||||
|
transform: translate(-50%, -50%); |
||||||
|
-webkit-transform-origin: center center; |
||||||
|
transform-origin: center center; } |
||||||
|
|
||||||
|
.fa-layers-counter { |
||||||
|
background-color: #ff253a; |
||||||
|
border-radius: 1em; |
||||||
|
-webkit-box-sizing: border-box; |
||||||
|
box-sizing: border-box; |
||||||
|
color: #fff; |
||||||
|
height: 1.5em; |
||||||
|
line-height: 1; |
||||||
|
max-width: 5em; |
||||||
|
min-width: 1.5em; |
||||||
|
overflow: hidden; |
||||||
|
padding: .25em; |
||||||
|
right: 0; |
||||||
|
text-overflow: ellipsis; |
||||||
|
top: 0; |
||||||
|
-webkit-transform: scale(0.25); |
||||||
|
transform: scale(0.25); |
||||||
|
-webkit-transform-origin: top right; |
||||||
|
transform-origin: top right; } |
||||||
|
|
||||||
|
.fa-layers-bottom-right { |
||||||
|
bottom: 0; |
||||||
|
right: 0; |
||||||
|
top: auto; |
||||||
|
-webkit-transform: scale(0.25); |
||||||
|
transform: scale(0.25); |
||||||
|
-webkit-transform-origin: bottom right; |
||||||
|
transform-origin: bottom right; } |
||||||
|
|
||||||
|
.fa-layers-bottom-left { |
||||||
|
bottom: 0; |
||||||
|
left: 0; |
||||||
|
right: auto; |
||||||
|
top: auto; |
||||||
|
-webkit-transform: scale(0.25); |
||||||
|
transform: scale(0.25); |
||||||
|
-webkit-transform-origin: bottom left; |
||||||
|
transform-origin: bottom left; } |
||||||
|
|
||||||
|
.fa-layers-top-right { |
||||||
|
right: 0; |
||||||
|
top: 0; |
||||||
|
-webkit-transform: scale(0.25); |
||||||
|
transform: scale(0.25); |
||||||
|
-webkit-transform-origin: top right; |
||||||
|
transform-origin: top right; } |
||||||
|
|
||||||
|
.fa-layers-top-left { |
||||||
|
left: 0; |
||||||
|
right: auto; |
||||||
|
top: 0; |
||||||
|
-webkit-transform: scale(0.25); |
||||||
|
transform: scale(0.25); |
||||||
|
-webkit-transform-origin: top left; |
||||||
|
transform-origin: top left; } |
||||||
|
|
||||||
|
.fa-lg { |
||||||
|
font-size: 1.33333em; |
||||||
|
line-height: 0.75em; |
||||||
|
vertical-align: -.0667em; } |
||||||
|
|
||||||
|
.fa-xs { |
||||||
|
font-size: .75em; } |
||||||
|
|
||||||
|
.fa-sm { |
||||||
|
font-size: .875em; } |
||||||
|
|
||||||
|
.fa-1x { |
||||||
|
font-size: 1em; } |
||||||
|
|
||||||
|
.fa-2x { |
||||||
|
font-size: 2em; } |
||||||
|
|
||||||
|
.fa-3x { |
||||||
|
font-size: 3em; } |
||||||
|
|
||||||
|
.fa-4x { |
||||||
|
font-size: 4em; } |
||||||
|
|
||||||
|
.fa-5x { |
||||||
|
font-size: 5em; } |
||||||
|
|
||||||
|
.fa-6x { |
||||||
|
font-size: 6em; } |
||||||
|
|
||||||
|
.fa-7x { |
||||||
|
font-size: 7em; } |
||||||
|
|
||||||
|
.fa-8x { |
||||||
|
font-size: 8em; } |
||||||
|
|
||||||
|
.fa-9x { |
||||||
|
font-size: 9em; } |
||||||
|
|
||||||
|
.fa-10x { |
||||||
|
font-size: 10em; } |
||||||
|
|
||||||
|
.fa-fw { |
||||||
|
text-align: center; |
||||||
|
width: 1.25em; } |
||||||
|
|
||||||
|
.fa-ul { |
||||||
|
list-style-type: none; |
||||||
|
margin-left: 2.5em; |
||||||
|
padding-left: 0; } |
||||||
|
.fa-ul > li { |
||||||
|
position: relative; } |
||||||
|
|
||||||
|
.fa-li { |
||||||
|
left: -2em; |
||||||
|
position: absolute; |
||||||
|
text-align: center; |
||||||
|
width: 2em; |
||||||
|
line-height: inherit; } |
||||||
|
|
||||||
|
.fa-border { |
||||||
|
border: solid 0.08em #eee; |
||||||
|
border-radius: .1em; |
||||||
|
padding: .2em .25em .15em; } |
||||||
|
|
||||||
|
.fa-pull-left { |
||||||
|
float: left; } |
||||||
|
|
||||||
|
.fa-pull-right { |
||||||
|
float: right; } |
||||||
|
|
||||||
|
.fa.fa-pull-left, |
||||||
|
.fas.fa-pull-left, |
||||||
|
.far.fa-pull-left, |
||||||
|
.fal.fa-pull-left, |
||||||
|
.fab.fa-pull-left { |
||||||
|
margin-right: .3em; } |
||||||
|
|
||||||
|
.fa.fa-pull-right, |
||||||
|
.fas.fa-pull-right, |
||||||
|
.far.fa-pull-right, |
||||||
|
.fal.fa-pull-right, |
||||||
|
.fab.fa-pull-right { |
||||||
|
margin-left: .3em; } |
||||||
|
|
||||||
|
.fa-spin { |
||||||
|
-webkit-animation: fa-spin 2s infinite linear; |
||||||
|
animation: fa-spin 2s infinite linear; } |
||||||
|
|
||||||
|
.fa-pulse { |
||||||
|
-webkit-animation: fa-spin 1s infinite steps(8); |
||||||
|
animation: fa-spin 1s infinite steps(8); } |
||||||
|
|
||||||
|
@-webkit-keyframes fa-spin { |
||||||
|
0% { |
||||||
|
-webkit-transform: rotate(0deg); |
||||||
|
transform: rotate(0deg); } |
||||||
|
100% { |
||||||
|
-webkit-transform: rotate(360deg); |
||||||
|
transform: rotate(360deg); } } |
||||||
|
|
||||||
|
@keyframes fa-spin { |
||||||
|
0% { |
||||||
|
-webkit-transform: rotate(0deg); |
||||||
|
transform: rotate(0deg); } |
||||||
|
100% { |
||||||
|
-webkit-transform: rotate(360deg); |
||||||
|
transform: rotate(360deg); } } |
||||||
|
|
||||||
|
.fa-rotate-90 { |
||||||
|
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; |
||||||
|
-webkit-transform: rotate(90deg); |
||||||
|
transform: rotate(90deg); } |
||||||
|
|
||||||
|
.fa-rotate-180 { |
||||||
|
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; |
||||||
|
-webkit-transform: rotate(180deg); |
||||||
|
transform: rotate(180deg); } |
||||||
|
|
||||||
|
.fa-rotate-270 { |
||||||
|
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; |
||||||
|
-webkit-transform: rotate(270deg); |
||||||
|
transform: rotate(270deg); } |
||||||
|
|
||||||
|
.fa-flip-horizontal { |
||||||
|
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; |
||||||
|
-webkit-transform: scale(-1, 1); |
||||||
|
transform: scale(-1, 1); } |
||||||
|
|
||||||
|
.fa-flip-vertical { |
||||||
|
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; |
||||||
|
-webkit-transform: scale(1, -1); |
||||||
|
transform: scale(1, -1); } |
||||||
|
|
||||||
|
.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical { |
||||||
|
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; |
||||||
|
-webkit-transform: scale(-1, -1); |
||||||
|
transform: scale(-1, -1); } |
||||||
|
|
||||||
|
:root .fa-rotate-90, |
||||||
|
:root .fa-rotate-180, |
||||||
|
:root .fa-rotate-270, |
||||||
|
:root .fa-flip-horizontal, |
||||||
|
:root .fa-flip-vertical, |
||||||
|
:root .fa-flip-both { |
||||||
|
-webkit-filter: none; |
||||||
|
filter: none; } |
||||||
|
|
||||||
|
.fa-stack { |
||||||
|
display: inline-block; |
||||||
|
height: 2em; |
||||||
|
position: relative; |
||||||
|
width: 2.5em; } |
||||||
|
|
||||||
|
.fa-stack-1x, |
||||||
|
.fa-stack-2x { |
||||||
|
bottom: 0; |
||||||
|
left: 0; |
||||||
|
margin: auto; |
||||||
|
position: absolute; |
||||||
|
right: 0; |
||||||
|
top: 0; } |
||||||
|
|
||||||
|
.svg-inline--fa.fa-stack-1x { |
||||||
|
height: 1em; |
||||||
|
width: 1.25em; } |
||||||
|
|
||||||
|
.svg-inline--fa.fa-stack-2x { |
||||||
|
height: 2em; |
||||||
|
width: 2.5em; } |
||||||
|
|
||||||
|
.fa-inverse { |
||||||
|
color: #fff; } |
||||||
|
|
||||||
|
.sr-only { |
||||||
|
border: 0; |
||||||
|
clip: rect(0, 0, 0, 0); |
||||||
|
height: 1px; |
||||||
|
margin: -1px; |
||||||
|
overflow: hidden; |
||||||
|
padding: 0; |
||||||
|
position: absolute; |
||||||
|
width: 1px; } |
||||||
|
|
||||||
|
.sr-only-focusable:active, .sr-only-focusable:focus { |
||||||
|
clip: auto; |
||||||
|
height: auto; |
||||||
|
margin: 0; |
||||||
|
overflow: visible; |
||||||
|
position: static; |
||||||
|
width: auto; } |
||||||
|
|
||||||
|
.svg-inline--fa .fa-primary { |
||||||
|
fill: var(--fa-primary-color, currentColor); |
||||||
|
opacity: 1; |
||||||
|
opacity: var(--fa-primary-opacity, 1); } |
||||||
|
|
||||||
|
.svg-inline--fa .fa-secondary { |
||||||
|
fill: var(--fa-secondary-color, currentColor); |
||||||
|
opacity: 0.4; |
||||||
|
opacity: var(--fa-secondary-opacity, 0.4); } |
||||||
|
|
||||||
|
.svg-inline--fa.fa-swap-opacity .fa-primary { |
||||||
|
opacity: 0.4; |
||||||
|
opacity: var(--fa-secondary-opacity, 0.4); } |
||||||
|
|
||||||
|
.svg-inline--fa.fa-swap-opacity .fa-secondary { |
||||||
|
opacity: 1; |
||||||
|
opacity: var(--fa-primary-opacity, 1); } |
||||||
|
|
||||||
|
.svg-inline--fa mask .fa-primary, |
||||||
|
.svg-inline--fa mask .fa-secondary { |
||||||
|
fill: black; } |
||||||
|
|
||||||
|
.fad.fa-inverse { |
||||||
|
color: #fff; } |
||||||
|
After Width: | Height: | Size: 699 KiB |