mirror of
https://github.com/Zaarrg/stremio-community-v5.git
synced 2026-01-11 12:00:40 +00:00
WebView2 letss gooo
- Big Massive init
This commit is contained in:
parent
207fbd3343
commit
16d1bce51c
45 changed files with 5911 additions and 1 deletions
4
.gitmodules
vendored
Normal file
4
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
[submodule "deps/libmpv"]
|
||||
path = deps/libmpv
|
||||
url = https://github.com/Zaarrg/libmpv
|
||||
branch = master
|
||||
60
CMakeLists.txt
Normal file
60
CMakeLists.txt
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(stremio VERSION "5.0.7")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
|
||||
# Locate MPV
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
# 64-bit architecture
|
||||
set(MPV_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/deps/libmpv/x86_64/include")
|
||||
set(MPV_LIBRARY "${CMAKE_CURRENT_SOURCE_DIR}/deps/libmpv/x86_64/mpv.lib")
|
||||
set(MPV_DLL "${CMAKE_CURRENT_SOURCE_DIR}/deps/libmpv/x86_64/libmpv-2.dll")
|
||||
else()
|
||||
# 32-bit architecture
|
||||
set(MPV_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/deps/libmpv/i686/include")
|
||||
set(MPV_LIBRARY "${CMAKE_CURRENT_SOURCE_DIR}/deps/libmpv/i686/mpv.lib")
|
||||
set(MPV_DLL "${CMAKE_CURRENT_SOURCE_DIR}/deps/libmpv/i686/libmpv-2.dll")
|
||||
endif()
|
||||
|
||||
|
||||
include_directories(${MPV_INCLUDE_DIR})
|
||||
|
||||
find_package(OpenSSL REQUIRED)
|
||||
find_package(CURL REQUIRED)
|
||||
find_package(nlohmann_json CONFIG REQUIRED)
|
||||
find_package(unofficial-webview2 CONFIG REQUIRED)
|
||||
|
||||
set(SOURCES
|
||||
src/main.cpp
|
||||
stremio.rc
|
||||
src/resource.h
|
||||
)
|
||||
|
||||
add_executable(${PROJECT_NAME} WIN32 ${SOURCES})
|
||||
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
user32.lib
|
||||
gdi32.lib
|
||||
ole32.lib
|
||||
oleaut32.lib
|
||||
shell32.lib
|
||||
advapi32.lib
|
||||
nlohmann_json::nlohmann_json
|
||||
unofficial::webview2::webview2
|
||||
OpenSSL::SSL
|
||||
OpenSSL::Crypto
|
||||
CURL::libcurl
|
||||
${MPV_LIBRARY}
|
||||
)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<CONFIG:Debug>:DEBUG_BUILD>)
|
||||
|
||||
# Copy MPV DLL
|
||||
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${MPV_DLL}"
|
||||
$<TARGET_FILE_DIR:${PROJECT_NAME}>
|
||||
)
|
||||
595
LICENSE.md
Normal file
595
LICENSE.md
Normal file
|
|
@ -0,0 +1,595 @@
|
|||
GNU General Public License
|
||||
==========================
|
||||
|
||||
_Version 3, 29 June 2007_
|
||||
_Copyright © 2007 Free Software Foundation, Inc. <<http://fsf.org/>>_
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this license
|
||||
document, but changing it is not allowed.
|
||||
|
||||
## Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for software and other
|
||||
kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed to take away
|
||||
your freedom to share and change the works. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change all versions of a
|
||||
program--to make sure it remains free software for all its users. We, the Free
|
||||
Software Foundation, use the GNU General Public License for most of our software; it
|
||||
applies also to any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not price. Our General
|
||||
Public Licenses are designed to make sure that you have the freedom to distribute
|
||||
copies of free software (and charge for them if you wish), that you receive source
|
||||
code or can get it if you want it, that you can change the software or use pieces of
|
||||
it in new free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you these rights or
|
||||
asking you to surrender the rights. Therefore, you have certain responsibilities if
|
||||
you distribute copies of the software, or if you modify it: responsibilities to
|
||||
respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether gratis or for a fee,
|
||||
you must pass on to the recipients the same freedoms that you received. You must make
|
||||
sure that they, too, receive or can get the source code. And you must show them these
|
||||
terms so they know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps: **(1)** assert
|
||||
copyright on the software, and **(2)** offer you this License giving you legal permission
|
||||
to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains that there is
|
||||
no warranty for this free software. For both users' and authors' sake, the GPL
|
||||
requires that modified versions be marked as changed, so that their problems will not
|
||||
be attributed erroneously to authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run modified versions of
|
||||
the software inside them, although the manufacturer can do so. This is fundamentally
|
||||
incompatible with the aim of protecting users' freedom to change the software. The
|
||||
systematic pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we have designed
|
||||
this version of the GPL to prohibit the practice for those products. If such problems
|
||||
arise substantially in other domains, we stand ready to extend this provision to
|
||||
those domains in future versions of the GPL, as needed to protect the freedom of
|
||||
users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents. States should
|
||||
not allow patents to restrict development and use of software on general-purpose
|
||||
computers, but in those that do, we wish to avoid the special danger that patents
|
||||
applied to a free program could make it effectively proprietary. To prevent this, the
|
||||
GPL assures that patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and modification follow.
|
||||
|
||||
## TERMS AND CONDITIONS
|
||||
|
||||
### 0. Definitions
|
||||
|
||||
“This License” refers to version 3 of the GNU General Public License.
|
||||
|
||||
“Copyright” also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
“The Program” refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as “you”. “Licensees” and
|
||||
“recipients” may be individuals or organizations.
|
||||
|
||||
To “modify” a work means to copy from or adapt all or part of the work in
|
||||
a fashion requiring copyright permission, other than the making of an exact copy. The
|
||||
resulting work is called a “modified version” of the earlier work or a
|
||||
work “based on” the earlier work.
|
||||
|
||||
A “covered work” means either the unmodified Program or a work based on
|
||||
the Program.
|
||||
|
||||
To “propagate” a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for infringement under
|
||||
applicable copyright law, except executing it on a computer or modifying a private
|
||||
copy. Propagation includes copying, distribution (with or without modification),
|
||||
making available to the public, and in some countries other activities as well.
|
||||
|
||||
To “convey” a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through a computer
|
||||
network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays “Appropriate Legal Notices” to the
|
||||
extent that it includes a convenient and prominently visible feature that **(1)**
|
||||
displays an appropriate copyright notice, and **(2)** tells the user that there is no
|
||||
warranty for the work (except to the extent that warranties are provided), that
|
||||
licensees may convey the work under this License, and how to view a copy of this
|
||||
License. If the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
### 1. Source Code
|
||||
|
||||
The “source code” for a work means the preferred form of the work for
|
||||
making modifications to it. “Object code” means any non-source form of a
|
||||
work.
|
||||
|
||||
A “Standard Interface” means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of interfaces
|
||||
specified for a particular programming language, one that is widely used among
|
||||
developers working in that language.
|
||||
|
||||
The “System Libraries” of an executable work include anything, other than
|
||||
the work as a whole, that **(a)** is included in the normal form of packaging a Major
|
||||
Component, but which is not part of that Major Component, and **(b)** serves only to
|
||||
enable use of the work with that Major Component, or to implement a Standard
|
||||
Interface for which an implementation is available to the public in source code form.
|
||||
A “Major Component”, in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system (if any) on which
|
||||
the executable work runs, or a compiler used to produce the work, or an object code
|
||||
interpreter used to run it.
|
||||
|
||||
The “Corresponding Source” for a work in object code form means all the
|
||||
source code needed to generate, install, and (for an executable work) run the object
|
||||
code and to modify the work, including scripts to control those activities. However,
|
||||
it does not include the work's System Libraries, or general-purpose tools or
|
||||
generally available free programs which are used unmodified in performing those
|
||||
activities but which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for the work, and
|
||||
the source code for shared libraries and dynamically linked subprograms that the work
|
||||
is specifically designed to require, such as by intimate data communication or
|
||||
control flow between those subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users can regenerate
|
||||
automatically from other parts of the Corresponding Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that same work.
|
||||
|
||||
### 2. Basic Permissions
|
||||
|
||||
All rights granted under this License are granted for the term of copyright on the
|
||||
Program, and are irrevocable provided the stated conditions are met. This License
|
||||
explicitly affirms your unlimited permission to run the unmodified Program. The
|
||||
output from running a covered work is covered by this License only if the output,
|
||||
given its content, constitutes a covered work. This License acknowledges your rights
|
||||
of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not convey, without
|
||||
conditions so long as your license otherwise remains in force. You may convey covered
|
||||
works to others for the sole purpose of having them make modifications exclusively
|
||||
for you, or provide you with facilities for running those works, provided that you
|
||||
comply with the terms of this License in conveying all material for which you do not
|
||||
control copyright. Those thus making or running the covered works for you must do so
|
||||
exclusively on your behalf, under your direction and control, on terms that prohibit
|
||||
them from making any copies of your copyrighted material outside their relationship
|
||||
with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under the conditions
|
||||
stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
|
||||
|
||||
### 3. Protecting Users' Legal Rights From Anti-Circumvention Law
|
||||
|
||||
No covered work shall be deemed part of an effective technological measure under any
|
||||
applicable law fulfilling obligations under article 11 of the WIPO copyright treaty
|
||||
adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention
|
||||
of such measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid circumvention of
|
||||
technological measures to the extent such circumvention is effected by exercising
|
||||
rights under this License with respect to the covered work, and you disclaim any
|
||||
intention to limit operation or modification of the work as a means of enforcing,
|
||||
against the work's users, your or third parties' legal rights to forbid circumvention
|
||||
of technological measures.
|
||||
|
||||
### 4. Conveying Verbatim Copies
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you receive it, in any
|
||||
medium, provided that you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice; keep intact all notices stating that this License and
|
||||
any non-permissive terms added in accord with section 7 apply to the code; keep
|
||||
intact all notices of the absence of any warranty; and give all recipients a copy of
|
||||
this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey, and you may offer
|
||||
support or warranty protection for a fee.
|
||||
|
||||
### 5. Conveying Modified Source Versions
|
||||
|
||||
You may convey a work based on the Program, or the modifications to produce it from
|
||||
the Program, in the form of source code under the terms of section 4, provided that
|
||||
you also meet all of these conditions:
|
||||
|
||||
* **a)** The work must carry prominent notices stating that you modified it, and giving a
|
||||
relevant date.
|
||||
* **b)** The work must carry prominent notices stating that it is released under this
|
||||
License and any conditions added under section 7. This requirement modifies the
|
||||
requirement in section 4 to “keep intact all notices”.
|
||||
* **c)** You must license the entire work, as a whole, under this License to anyone who
|
||||
comes into possession of a copy. This License will therefore apply, along with any
|
||||
applicable section 7 additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no permission to license the
|
||||
work in any other way, but it does not invalidate such permission if you have
|
||||
separately received it.
|
||||
* **d)** If the work has interactive user interfaces, each must display Appropriate Legal
|
||||
Notices; however, if the Program has interactive interfaces that do not display
|
||||
Appropriate Legal Notices, your work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent works, which are
|
||||
not by their nature extensions of the covered work, and which are not combined with
|
||||
it such as to form a larger program, in or on a volume of a storage or distribution
|
||||
medium, is called an “aggregate” if the compilation and its resulting
|
||||
copyright are not used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work in an aggregate
|
||||
does not cause this License to apply to the other parts of the aggregate.
|
||||
|
||||
### 6. Conveying Non-Source Forms
|
||||
|
||||
You may convey a covered work in object code form under the terms of sections 4 and
|
||||
5, provided that you also convey the machine-readable Corresponding Source under the
|
||||
terms of this License, in one of these ways:
|
||||
|
||||
* **a)** Convey the object code in, or embodied in, a physical product (including a
|
||||
physical distribution medium), accompanied by the Corresponding Source fixed on a
|
||||
durable physical medium customarily used for software interchange.
|
||||
* **b)** Convey the object code in, or embodied in, a physical product (including a
|
||||
physical distribution medium), accompanied by a written offer, valid for at least
|
||||
three years and valid for as long as you offer spare parts or customer support for
|
||||
that product model, to give anyone who possesses the object code either **(1)** a copy of
|
||||
the Corresponding Source for all the software in the product that is covered by this
|
||||
License, on a durable physical medium customarily used for software interchange, for
|
||||
a price no more than your reasonable cost of physically performing this conveying of
|
||||
source, or **(2)** access to copy the Corresponding Source from a network server at no
|
||||
charge.
|
||||
* **c)** Convey individual copies of the object code with a copy of the written offer to
|
||||
provide the Corresponding Source. This alternative is allowed only occasionally and
|
||||
noncommercially, and only if you received the object code with such an offer, in
|
||||
accord with subsection 6b.
|
||||
* **d)** Convey the object code by offering access from a designated place (gratis or for
|
||||
a charge), and offer equivalent access to the Corresponding Source in the same way
|
||||
through the same place at no further charge. You need not require recipients to copy
|
||||
the Corresponding Source along with the object code. If the place to copy the object
|
||||
code is a network server, the Corresponding Source may be on a different server
|
||||
(operated by you or a third party) that supports equivalent copying facilities,
|
||||
provided you maintain clear directions next to the object code saying where to find
|
||||
the Corresponding Source. Regardless of what server hosts the Corresponding Source,
|
||||
you remain obligated to ensure that it is available for as long as needed to satisfy
|
||||
these requirements.
|
||||
* **e)** Convey the object code using peer-to-peer transmission, provided you inform
|
||||
other peers where the object code and Corresponding Source of the work are being
|
||||
offered to the general public at no charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded from the
|
||||
Corresponding Source as a System Library, need not be included in conveying the
|
||||
object code work.
|
||||
|
||||
A “User Product” is either **(1)** a “consumer product”, which
|
||||
means any tangible personal property which is normally used for personal, family, or
|
||||
household purposes, or **(2)** anything designed or sold for incorporation into a
|
||||
dwelling. In determining whether a product is a consumer product, doubtful cases
|
||||
shall be resolved in favor of coverage. For a particular product received by a
|
||||
particular user, “normally used” refers to a typical or common use of
|
||||
that class of product, regardless of the status of the particular user or of the way
|
||||
in which the particular user actually uses, or expects or is expected to use, the
|
||||
product. A product is a consumer product regardless of whether the product has
|
||||
substantial commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
“Installation Information” for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install and execute
|
||||
modified versions of a covered work in that User Product from a modified version of
|
||||
its Corresponding Source. The information must suffice to ensure that the continued
|
||||
functioning of the modified object code is in no case prevented or interfered with
|
||||
solely because modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or specifically for
|
||||
use in, a User Product, and the conveying occurs as part of a transaction in which
|
||||
the right of possession and use of the User Product is transferred to the recipient
|
||||
in perpetuity or for a fixed term (regardless of how the transaction is
|
||||
characterized), the Corresponding Source conveyed under this section must be
|
||||
accompanied by the Installation Information. But this requirement does not apply if
|
||||
neither you nor any third party retains the ability to install modified object code
|
||||
on the User Product (for example, the work has been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a requirement to
|
||||
continue to provide support service, warranty, or updates for a work that has been
|
||||
modified or installed by the recipient, or for the User Product in which it has been
|
||||
modified or installed. Access to a network may be denied when the modification itself
|
||||
materially and adversely affects the operation of the network or violates the rules
|
||||
and protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided, in accord with
|
||||
this section must be in a format that is publicly documented (and with an
|
||||
implementation available to the public in source code form), and must require no
|
||||
special password or key for unpacking, reading or copying.
|
||||
|
||||
### 7. Additional Terms
|
||||
|
||||
“Additional permissions” are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions. Additional
|
||||
permissions that are applicable to the entire Program shall be treated as though they
|
||||
were included in this License, to the extent that they are valid under applicable
|
||||
law. If additional permissions apply only to part of the Program, that part may be
|
||||
used separately under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option remove any
|
||||
additional permissions from that copy, or from any part of it. (Additional
|
||||
permissions may be written to require their own removal in certain cases when you
|
||||
modify the work.) You may place additional permissions on material, added by you to a
|
||||
covered work, for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you add to a
|
||||
covered work, you may (if authorized by the copyright holders of that material)
|
||||
supplement the terms of this License with terms:
|
||||
|
||||
* **a)** Disclaiming warranty or limiting liability differently from the terms of
|
||||
sections 15 and 16 of this License; or
|
||||
* **b)** Requiring preservation of specified reasonable legal notices or author
|
||||
attributions in that material or in the Appropriate Legal Notices displayed by works
|
||||
containing it; or
|
||||
* **c)** Prohibiting misrepresentation of the origin of that material, or requiring that
|
||||
modified versions of such material be marked in reasonable ways as different from the
|
||||
original version; or
|
||||
* **d)** Limiting the use for publicity purposes of names of licensors or authors of the
|
||||
material; or
|
||||
* **e)** Declining to grant rights under trademark law for use of some trade names,
|
||||
trademarks, or service marks; or
|
||||
* **f)** Requiring indemnification of licensors and authors of that material by anyone
|
||||
who conveys the material (or modified versions of it) with contractual assumptions of
|
||||
liability to the recipient, for any liability that these contractual assumptions
|
||||
directly impose on those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered “further
|
||||
restrictions” within the meaning of section 10. If the Program as you received
|
||||
it, or any part of it, contains a notice stating that it is governed by this License
|
||||
along with a term that is a further restriction, you may remove that term. If a
|
||||
license document contains a further restriction but permits relicensing or conveying
|
||||
under this License, you may add to a covered work material governed by the terms of
|
||||
that license document, provided that the further restriction does not survive such
|
||||
relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you must place, in
|
||||
the relevant source files, a statement of the additional terms that apply to those
|
||||
files, or a notice indicating where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the form of a
|
||||
separately written license, or stated as exceptions; the above requirements apply
|
||||
either way.
|
||||
|
||||
### 8. Termination
|
||||
|
||||
You may not propagate or modify a covered work except as expressly provided under
|
||||
this License. Any attempt otherwise to propagate or modify it is void, and will
|
||||
automatically terminate your rights under this License (including any patent licenses
|
||||
granted under the third paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your license from a
|
||||
particular copyright holder is reinstated **(a)** provisionally, unless and until the
|
||||
copyright holder explicitly and finally terminates your license, and **(b)** permanently,
|
||||
if the copyright holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is reinstated permanently
|
||||
if the copyright holder notifies you of the violation by some reasonable means, this
|
||||
is the first time you have received notice of violation of this License (for any
|
||||
work) from that copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the licenses of
|
||||
parties who have received copies or rights from you under this License. If your
|
||||
rights have been terminated and not permanently reinstated, you do not qualify to
|
||||
receive new licenses for the same material under section 10.
|
||||
|
||||
### 9. Acceptance Not Required for Having Copies
|
||||
|
||||
You are not required to accept this License in order to receive or run a copy of the
|
||||
Program. Ancillary propagation of a covered work occurring solely as a consequence of
|
||||
using peer-to-peer transmission to receive a copy likewise does not require
|
||||
acceptance. However, nothing other than this License grants you permission to
|
||||
propagate or modify any covered work. These actions infringe copyright if you do not
|
||||
accept this License. Therefore, by modifying or propagating a covered work, you
|
||||
indicate your acceptance of this License to do so.
|
||||
|
||||
### 10. Automatic Licensing of Downstream Recipients
|
||||
|
||||
Each time you convey a covered work, the recipient automatically receives a license
|
||||
from the original licensors, to run, modify and propagate that work, subject to this
|
||||
License. You are not responsible for enforcing compliance by third parties with this
|
||||
License.
|
||||
|
||||
An “entity transaction” is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an organization, or
|
||||
merging organizations. If propagation of a covered work results from an entity
|
||||
transaction, each party to that transaction who receives a copy of the work also
|
||||
receives whatever licenses to the work the party's predecessor in interest had or
|
||||
could give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if the predecessor
|
||||
has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the rights granted or
|
||||
affirmed under this License. For example, you may not impose a license fee, royalty,
|
||||
or other charge for exercise of rights granted under this License, and you may not
|
||||
initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that any patent claim is infringed by making, using, selling, offering for sale, or
|
||||
importing the Program or any portion of it.
|
||||
|
||||
### 11. Patents
|
||||
|
||||
A “contributor” is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The work thus
|
||||
licensed is called the contributor's “contributor version”.
|
||||
|
||||
A contributor's “essential patent claims” are all patent claims owned or
|
||||
controlled by the contributor, whether already acquired or hereafter acquired, that
|
||||
would be infringed by some manner, permitted by this License, of making, using, or
|
||||
selling its contributor version, but do not include claims that would be infringed
|
||||
only as a consequence of further modification of the contributor version. For
|
||||
purposes of this definition, “control” includes the right to grant patent
|
||||
sublicenses in a manner consistent with the requirements of this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free patent license
|
||||
under the contributor's essential patent claims, to make, use, sell, offer for sale,
|
||||
import and otherwise run, modify and propagate the contents of its contributor
|
||||
version.
|
||||
|
||||
In the following three paragraphs, a “patent license” is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent (such as an
|
||||
express permission to practice a patent or covenant not to sue for patent
|
||||
infringement). To “grant” such a patent license to a party means to make
|
||||
such an agreement or commitment not to enforce a patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license, and the
|
||||
Corresponding Source of the work is not available for anyone to copy, free of charge
|
||||
and under the terms of this License, through a publicly available network server or
|
||||
other readily accessible means, then you must either **(1)** cause the Corresponding
|
||||
Source to be so available, or **(2)** arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or **(3)** arrange, in a manner consistent with
|
||||
the requirements of this License, to extend the patent license to downstream
|
||||
recipients. “Knowingly relying” means you have actual knowledge that, but
|
||||
for the patent license, your conveying the covered work in a country, or your
|
||||
recipient's use of the covered work in a country, would infringe one or more
|
||||
identifiable patents in that country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or arrangement, you
|
||||
convey, or propagate by procuring conveyance of, a covered work, and grant a patent
|
||||
license to some of the parties receiving the covered work authorizing them to use,
|
||||
propagate, modify or convey a specific copy of the covered work, then the patent
|
||||
license you grant is automatically extended to all recipients of the covered work and
|
||||
works based on it.
|
||||
|
||||
A patent license is “discriminatory” if it does not include within the
|
||||
scope of its coverage, prohibits the exercise of, or is conditioned on the
|
||||
non-exercise of one or more of the rights that are specifically granted under this
|
||||
License. You may not convey a covered work if you are a party to an arrangement with
|
||||
a third party that is in the business of distributing software, under which you make
|
||||
payment to the third party based on the extent of your activity of conveying the
|
||||
work, and under which the third party grants, to any of the parties who would receive
|
||||
the covered work from you, a discriminatory patent license **(a)** in connection with
|
||||
copies of the covered work conveyed by you (or copies made from those copies), or **(b)**
|
||||
primarily for and in connection with specific products or compilations that contain
|
||||
the covered work, unless you entered into that arrangement, or that patent license
|
||||
was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting any implied
|
||||
license or other defenses to infringement that may otherwise be available to you
|
||||
under applicable patent law.
|
||||
|
||||
### 12. No Surrender of Others' Freedom
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or otherwise)
|
||||
that contradict the conditions of this License, they do not excuse you from the
|
||||
conditions of this License. If you cannot convey a covered work so as to satisfy
|
||||
simultaneously your obligations under this License and any other pertinent
|
||||
obligations, then as a consequence you may not convey it at all. For example, if you
|
||||
agree to terms that obligate you to collect a royalty for further conveying from
|
||||
those to whom you convey the Program, the only way you could satisfy both those terms
|
||||
and this License would be to refrain entirely from conveying the Program.
|
||||
|
||||
### 13. Use with the GNU Affero General Public License
|
||||
|
||||
Notwithstanding any other provision of this License, you have permission to link or
|
||||
combine any covered work with a work licensed under version 3 of the GNU Affero
|
||||
General Public License into a single combined work, and to convey the resulting work.
|
||||
The terms of this License will continue to apply to the part which is the covered
|
||||
work, but the special requirements of the GNU Affero General Public License, section
|
||||
13, concerning interaction through a network will apply to the combination as such.
|
||||
|
||||
### 14. Revised Versions of this License
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of the GNU
|
||||
General Public License from time to time. Such new versions will be similar in spirit
|
||||
to the present version, but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program specifies that
|
||||
a certain numbered version of the GNU General Public License “or any later
|
||||
version” applies to it, you have the option of following the terms and
|
||||
conditions either of that numbered version or of any later version published by the
|
||||
Free Software Foundation. If the Program does not specify a version number of the GNU
|
||||
General Public License, you may choose any version ever published by the Free
|
||||
Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future versions of the GNU
|
||||
General Public License can be used, that proxy's public statement of acceptance of a
|
||||
version permanently authorizes you to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different permissions. However, no
|
||||
additional obligations are imposed on any author or copyright holder as a result of
|
||||
your choosing to follow a later version.
|
||||
|
||||
### 15. Disclaimer of Warranty
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE
|
||||
QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
|
||||
DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
### 16. Limitation of Liability
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY
|
||||
COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS
|
||||
PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
|
||||
INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE
|
||||
OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE
|
||||
WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
### 17. Interpretation of Sections 15 and 16
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided above cannot be
|
||||
given local legal effect according to their terms, reviewing courts shall apply local
|
||||
law that most closely approximates an absolute waiver of all civil liability in
|
||||
connection with the Program, unless a warranty or assumption of liability accompanies
|
||||
a copy of the Program in return for a fee.
|
||||
|
||||
_END OF TERMS AND CONDITIONS_
|
||||
|
||||
## How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest possible use to
|
||||
the public, the best way to achieve this is to make it free software which everyone
|
||||
can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest to attach them
|
||||
to the start of each source file to most effectively state the exclusion of warranty;
|
||||
and each file should have at least the “copyright” line and a pointer to
|
||||
where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type 'show c' for details.
|
||||
|
||||
The hypothetical commands `show w` and `show c` should show the appropriate parts of
|
||||
the General Public License. Of course, your program's commands might be different;
|
||||
for a GUI interface, you would use an “about box”.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school, if any, to
|
||||
sign a “copyright disclaimer” for the program, if necessary. For more
|
||||
information on this, and how to apply and follow the GNU GPL, see
|
||||
<<http://www.gnu.org/licenses/>>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may consider it
|
||||
more useful to permit linking proprietary applications with the library. If this is
|
||||
what you want to do, use the GNU Lesser General Public License instead of this
|
||||
License. But first, please read
|
||||
<<http://www.gnu.org/philosophy/why-not-lgpl.html>>.
|
||||
183
README.md
183
README.md
|
|
@ -1 +1,182 @@
|
|||
"# New Branch"
|
||||
<p align="center">
|
||||
<img src="https://www.stremio.com/website/stremio-logo-small.png" alt="Stremio Web Desktop Logo" width="200" />
|
||||
</p>
|
||||
<div align="center">
|
||||
<h1>🌌 Stremio Desktop<br/><span style="font-size: 0.6em; font-weight: normal;">Community</span></h1>
|
||||
</div>
|
||||
|
||||
<p align="center">Stremio Desktop app with the latest Stremio web UI v5, built with Qt6</p>
|
||||
<p align="center">
|
||||
<!-- C++ badge -->
|
||||
<img src="https://img.shields.io/badge/C++-00599C?style=for-the-badge&logo=c%2B%2B&logoColor=white" alt="C++" />
|
||||
<!-- WebView2 badge -->
|
||||
<img src="https://img.shields.io/badge/WebView2-0078D6?style=for-the-badge&logo=microsoftedge&logoColor=white" alt="WebView2" />
|
||||
<!-- MPV badge -->
|
||||
<img src="https://img.shields.io/badge/MPV-663399?style=for-the-badge&logo=mpv&logoColor=white" alt="MPV" />
|
||||
<!-- Win32 badge -->
|
||||
<img src="https://img.shields.io/badge/Win32-0078D6?style=for-the-badge&logo=windows&logoColor=white" alt="Win32" />
|
||||
<!-- Scoop badge -->
|
||||
<img src="https://img.shields.io/badge/Scoop-80C342?style=for-the-badge&logo=scoop&logoColor=white" alt="Scoop" />
|
||||
<!-- Chocolatey badge -->
|
||||
<img src="https://img.shields.io/badge/Chocolatey-3C69E7?style=for-the-badge&logo=chocolatey&logoColor=white" alt="Chocolatey" />
|
||||
<!-- Streaming badge -->
|
||||
<img src="https://img.shields.io/badge/Streaming-E34F26?style=for-the-badge&logo=netflix&logoColor=white" alt="Streaming" />
|
||||
<!-- Torrents badge -->
|
||||
<img src="https://img.shields.io/badge/Torrents-000000?style=for-the-badge&logo=thepiratebay&logoColor=white" alt="Torrents" />
|
||||
</p>
|
||||
|
||||
## 🌟 **Features**
|
||||
- 🚀 **Latest Technology**: Built with WebView2 to provide the newest features and best performance
|
||||
- 🌐 **Latest Web Ui**: Always up-to-date with Stremio Web v5
|
||||
- 🎞️ **Native Playback**: Integrated Player for native 4K playback, hardware decoding, and fastest video performance
|
||||
- 🔍 **Video Upscaling**: Upscaling support for anything mpv supports
|
||||
- 🎥 **Full MPV Support**: Full MPV support use any hwdec, gpu-api or gpu-context like d3d, opengl and vulkan or `target-colorspace-hint=yes` for DV content
|
||||
- 🌈 **HDR Support**: Full HDR Support thanks to fully supported mpv and any other mpv feature
|
||||
- 🔊 **Dolby Atmos Support**: Support for all mpv advanced audio features.
|
||||
- 🖼️ **Picture in Picture**: Picture in Picture Mode Support
|
||||
- 🌑 **Dark Mode**: Windows Dark mode support
|
||||
- 🖼️ **Thumbnail Preview**: ThumbFast support to allow for preview thumbnails when seeking
|
||||
- 📁 **Local File Playback**: Play any local file that MPV and ffmpeg supports, just use open with 'stremio' or drag and drop
|
||||
- 🌀 **Torrent Support**: Play any local .torrent file or any magnet: link
|
||||
- 📺 **Chromecast Support**: Cast Videos to your Chromecast
|
||||
- ➕ **Easy Addon Install**: Just use the install Button like stremio v4, no need to copy paste urls
|
||||
- 💼 **Portable Version**: Fully portable version including WebView2.
|
||||
- ⚙️ **App Settings**: Customize App behavior like CloseOnExit, PauseOnMinimize or PauseOnLostFocus and more via stremio-settings.ini.
|
||||
|
||||
|
||||
|
||||
<p align="center">
|
||||
<img src="https://i.imgur.com/xvM5lp8.png" alt="Stremio Web Desktop Screenshot" width="600" />
|
||||
</p>
|
||||
|
||||
## 🔧 Installation
|
||||
|
||||
1. 🪟 **Windows x64 and x86**
|
||||
1. 📥 **Installer**
|
||||
- **Install using the** `Installer`. Download `stremio-5.0.0-x64.exe` or `stremio-5.0.0-x86.exe` and run it.
|
||||
2. 💼 **Portable Version**
|
||||
- **Install using the** `Archive`. Download `stremio-5.0.0-x64.7z` or `stremio-5.0.0-x86.7z` extract it and run `stremio.exe`
|
||||
3. 🥄 **Scoop.sh**
|
||||
- Coming Soon!
|
||||
4. 🍫 **Chocolatey**
|
||||
- Coming Soon!
|
||||
|
||||
> **⏳ Note:** If you have stremio-desktop v4.x.x installed make sure to uninstall it first. Otherwise there might be issues.
|
||||
|
||||
2. 🚀 **Linux, macOS**
|
||||
- Coming soon!
|
||||
|
||||
> **⏳ Note:** Linux and Mac release will take considerable time as they need their own build with os specific technology's
|
||||
|
||||
## 🔍 **Mpv Upscalers**
|
||||
|
||||
- 🎥 **[Anime4k](https://github.com/bloc97/Anime4K)**
|
||||
- ✅ Included by default.
|
||||
- 🔢 Use `CTRL+1` - `CTRL+6` to enable shaders.
|
||||
- ❌ Use `CTRL+0` to disable.
|
||||
|
||||
- 🎨 **[AnimeJaNai](https://github.com/the-database/mpv-upscale-2x_animejanai)**
|
||||
- ❌ Not included by default.
|
||||
- 📥 Download from the **Stremio-Desktop-v5** [release tab](https://github.com/Zaarrg/stremio-desktop-v5) the `stremio-animejanai-3.x.x.7z` for Stremio and drop the content of the 7z into `%localAppData%\Programs\LNV\Stremio-5\` and `replace all`
|
||||
- 🛠️ **Changes made:**
|
||||
- Removed `mpvnet.exe` as Stremio is used as the player.
|
||||
- Adjusted `mpv.conf` to work with Stremio.
|
||||
- Adjusted `input.conf` to work with Stremio.
|
||||
- ⌨️ **Possible Keybindings**
|
||||
- 🎬 `CTRL+J` Show Upscaler Status
|
||||
- 🛠️ `CTRL+E` Open AnimeJaNai ConfEditor
|
||||
- ❌ `CTRL+0` Disable Upscaling
|
||||
- 🔢 `SHIFT+1` - `SHIFT+3` Select Quality, Balanced or Performance Profiles
|
||||
- ⚙️ `CTRL+1` - `CTRL+9` Switch between Custom Profiles
|
||||
- 🔗 For more, check [AnimeJaNai](https://github.com/the-database/mpv-upscale-2x_animejanai)
|
||||
|
||||
> **⏳ Note:** When using AnimeJaNai on first playback Stremio will be unresponsive and a console will open to build the model via e.g. TensorRT. You will need to wait until the console closes for playback to start. This happens only once per model.
|
||||
|
||||
|
||||
- 🚀 **Nvidia RTX and Intel VSR Scaling**
|
||||
- ✅ Supported by using `mpv.conf`.
|
||||
- ✍️ Modify in `%localAppData%\Programs\LNV\Stremio-5\` the ``portable_config/mpv.conf`` and add the line ``vf=d3d11vpp=scale=2:scaling-mode=nvidia`` more details [here](https://www.reddit.com/r/nvidia/comments/1foyl4n/mpv_player_v0390_adds_rtx_video_super_resolution/)
|
||||
|
||||
## 🔍 **Mpv Addons**
|
||||
|
||||
- 🎥 **[ThumbFast](https://github.com/po5/thumbfast)**
|
||||
- 🔧 Go in the `Stremio-Dekstop-v5` Repo to ``utils/mpv/thumbfast`` or ``direct-link`` and download ``thumbfast.7z``. Drag and Drop the archive contents into ``%localAppData%\Programs\LNV\Stremio-5\``
|
||||
- 📁 Works best with local files as there is no **network bottleneck**. U can `Drag and Drop` any local file into **Stremio** or right click ``Open With > Stremio``
|
||||
|
||||
|
||||
## ✨ **Stremio App**
|
||||
|
||||
- 📁 **Local Files**
|
||||
- Play any **local file** or **torrent** by `drag and dropping` or ``Open With > Stremio`` that mpv and ffmpeg support
|
||||
- Play any **magnet** by `opening it via the browser` in Stremio or `copy pasting` it into the **Search Bar**
|
||||
|
||||
- 🧩 **Browser Extensions**
|
||||
- Add any Browser Extension to Stremio by dropping the ``unpacked`` Extension into ``portable_config/extensions``
|
||||
- On Start Extensions from ``portable_config/extensions`` are loaded.
|
||||
- 👉 **To install extension:**
|
||||
1. Get the ``unpacked`` Extensions from``%localAppData%\Microsoft\Edge SxS\User Data\Default\Extensions``.
|
||||
2. Here look for the `mainfest.json` for example ublock `{string-id}/1.62.0_0/manifest.json` as all the content beside is the extension
|
||||
3. Now we can copy the contents of ``{string-id}/1.62.0_0`` to ``%localAppData%\Programs\LNV\Stremio-5\portable_config\extensions\ublock``
|
||||
4. Important is that the ``mainfest.json`` is located directly in ``portable_config\extensions\ublock``
|
||||
5. Done. Restart app and addon will be loaded. If loading fails check ``portable_config\errors-{date}.txt``
|
||||
|
||||
- ⚙️ **App Settings**
|
||||
- All App Settings can be adjusted with ``portable_config\stremio-settings.ini``
|
||||
- Some options can be set by `right-clicking` on the **tray icon** as well.
|
||||
- ⌨️ **Possible Settings**
|
||||
- ❌ ``CloseOnExit`` Close app on exit instead of minimized to tray
|
||||
- 🌓 ``UseDarkTheme`` Toggle dark theme
|
||||
- 📏 ``ThumbFastHeight`` Enable thumbfast and set the thumbfast image height. This adjust the offset of the top left corner of the thumb. Meaning `100` will move the top left corner 100px up. `0` disables thumbfast
|
||||
- 😴 ``PauseOnMinimize`` Pause playback on window minimize
|
||||
- 👀 ``PauseOnLostFocus`` Pause playback on window loses focus
|
||||
- 🔍 ``AllowZoom`` Allow zoom via `pinch action` or ``CTRL+Scroll``
|
||||
|
||||
## 🎛️ **Mpv Configuration**
|
||||
|
||||
Enhance your Stremio experience by customizing the MPV player settings. Below are the key configuration files and guidelines to help you get started:
|
||||
|
||||
- 📁 **`mpv.conf` Location**
|
||||
- The ``mpv.conf`` file can be found in the following location:
|
||||
- **Installation Path:** ``%localAppData%\Programs\LNV\Stremio-5\portable_config\mpv.conf``
|
||||
- **Shaders Folder:** Located within the installation directory ``..\Stremio-5\portable_config\shaders``.
|
||||
|
||||
> **⏳ Note:** Any other configuration files can be just dropped into ``%localAppData%\Programs\LNV\Stremio-5\portable_config`` as this is the mpv ``config-dir`` like ``input.conf``. ``scripts`` or ``scripts-conf``
|
||||
|
||||
- **🎹 Usage example in `input.conf` using [Anime4k](https://github.com/bloc97/Anime4K):**
|
||||
```shell
|
||||
# Optimized shaders for higher-end GPU
|
||||
CTRL+1 no-osd change-list glsl-shaders set "~~/shaders/Anime4K_Clamp_Highlights.glsl;~~/shaders/Anime4K_Restore_CNN_VL.glsl;~~/shaders/Anime4K_Upscale_CNN_x2_VL.glsl;~~/shaders/Anime4K_AutoDownscalePre_x2.glsl;~~/shaders/Anime4K_AutoDownscalePre_x4.glsl;~~/shaders/Anime4K_Upscale_CNN_x2_M.glsl"; show-text "Anime4K: Mode A (HQ)"
|
||||
CTRL+2 no-osd change-list glsl-shaders set "~~/shaders/Anime4K_Clamp_Highlights.glsl;~~/shaders/Anime4K_Restore_CNN_Soft_VL.glsl;~~/shaders/Anime4K_Upscale_CNN_x2_VL.glsl;~~/shaders/Anime4K_AutoDownscalePre_x2.glsl;~~/shaders/Anime4K_AutoDownscalePre_x4.glsl;~~/shaders/Anime4K_Upscale_CNN_x2_M.glsl"; show-text "Anime4K: Mode B (HQ)"
|
||||
CTRL+3 no-osd change-list glsl-shaders set "~~/shaders/Anime4K_Clamp_Highlights.glsl;~~/shaders/Anime4K_Upscale_Denoise_CNN_x2_VL.glsl;~~/shaders/Anime4K_AutoDownscalePre_x2.glsl;~~/shaders/Anime4K_AutoDownscalePre_x4.glsl;~~/shaders/Anime4K_Upscale_CNN_x2_M.glsl"; show-text "Anime4K: Mode C (HQ)"
|
||||
CTRL+4 no-osd change-list glsl-shaders set "~~/shaders/Anime4K_Clamp_Highlights.glsl;~~/shaders/Anime4K_Restore_CNN_VL.glsl;~~/shaders/Anime4K_Upscale_CNN_x2_VL.glsl;~~/shaders/Anime4K_Restore_CNN_M.glsl;~~/shaders/Anime4K_AutoDownscalePre_x2.glsl;~~/shaders/Anime4K_AutoDownscalePre_x4.glsl;~~/shaders/Anime4K_Upscale_CNN_x2_M.glsl"; show-text "Anime4K: Mode A+A (HQ)"
|
||||
CTRL+5 no-osd change-list glsl-shaders set "~~/shaders/Anime4K_Clamp_Highlights.glsl;~~/shaders/Anime4K_Restore_CNN_Soft_VL.glsl;~~/shaders/Anime4K_Upscale_CNN_x2_VL.glsl;~~/shaders/Anime4K_AutoDownscalePre_x2.glsl;~~/shaders/Anime4K_AutoDownscalePre_x4.glsl;~~/shaders/Anime4K_Restore_CNN_Soft_M.glsl;~~/shaders/Anime4K_Upscale_CNN_x2_M.glsl"; show-text "Anime4K: Mode B+B (HQ)"
|
||||
CTRL+6 no-osd change-list glsl-shaders set "~~/shaders/Anime4K_Clamp_Highlights.glsl;~~/shaders/Anime4K_Upscale_Denoise_CNN_x2_VL.glsl;~~/shaders/Anime4K_AutoDownscalePre_x2.glsl;~~/shaders/Anime4K_AutoDownscalePre_x4.glsl;~~/shaders/Anime4K_Restore_CNN_M.glsl;~~/shaders/Anime4K_Upscale_CNN_x2_M.glsl"; show-text "Anime4K: Mode C+A (HQ)"
|
||||
|
||||
CTRL+0 no-osd change-list glsl-shaders clr ""; show-text "GLSL shaders cleared"
|
||||
```
|
||||
> **⏳ Note:** Some keys might not work as key presses are converted from js event.codes to literal values for mpv
|
||||
|
||||
## ⚙️ **Start Arguments**
|
||||
Use these extra arguments when launching the application:
|
||||
|
||||
| Argument | Example | Description |
|
||||
|-----------------------------|-------------------------------------------------------|-----------------------------------------------------------------------------------------------------------|
|
||||
| --webui-url= | --webui-url=https://web.stremio.com/ | Loads web ui from `https://web.stremio.com/` |
|
||||
| --streaming-server-disabled | | Disable auto start of `streamio-server`, Default behaviour in prod
|
||||
| --autoupdater-force-full | | Forces Autoupdate to always do a `full-update` rather than `partial` |
|
||||
| --autoupdater-endpoint= | --autoupdater-endpoint==https://verison.mydomain.com/ | Overrides default checking endpoint for the autoupdater |
|
||||
|
||||
> **⏳ Note:** By default will use as ``webui-url`` the [stremio-web-shell](https://github.com/Zaarrg/stremio-web-shell-fixes) web-ui hosted [here](https://zaarrg.github.io/stremio-web-shell-fixes/#/) which includes fixes to run smoothly with qt6
|
||||
|
||||
## 📚 **Guide / Docs**
|
||||
If you want to build this app yourself, check the “[docs](https://github.com/Zaarrg/stremio-desktop-v5/tree/master/docs)” folder in this repository for setup instructions and additional information.
|
||||
|
||||
## ⚠️ **Disclaimer**
|
||||
This project is not affiliated with **Stremio** in any way.
|
||||
|
||||
## 🤝 **Support Development**
|
||||
If you enjoy this project and want to support further development, consider [buying me a coffee](https://ko-fi.com/zaarrg). Your support means a lot! ☕
|
||||
|
||||
<p align="center">
|
||||
<strong>⭐ Made with ❤️ by <a href="https://github.com/Zaarrg">Zaarrg</a> ⭐</strong>
|
||||
</p>
|
||||
229
build/build_anime4k.js
Normal file
229
build/build_anime4k.js
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* build_anime4k.js
|
||||
*
|
||||
* This script performs the following: (Needed for deploy_windows to include Anime4k in installer)
|
||||
* 1. Determines the latest Anime4K version from bloc97/Anime4K releases.
|
||||
* 2. Downloads the corresponding GLSL_Windows_High-end.zip from Tama47/Anime4K.
|
||||
* 3. Auto-detects 7z.exe on the system.
|
||||
* 4. Saves the downloaded zip as anime4k-High-end.zip in utils/mpv.
|
||||
* 5. Extracts the zip into the anime4k folder.
|
||||
* 6. Cleans up temporary files.
|
||||
*
|
||||
* Usage:
|
||||
* node build_anime4k.js
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const https = require('https');
|
||||
const { execSync } = require('child_process');
|
||||
const os = require('os');
|
||||
|
||||
// Configuration
|
||||
const BLOC97_API_URL = 'https://api.github.com/repos/bloc97/Anime4K/releases/latest';
|
||||
const TEMP_DIR = path.join(os.tmpdir(), 'anime4k_build_temp');
|
||||
const OUTPUT_DIR = path.resolve(__dirname, '..', 'utils', 'mpv', 'anime4k');
|
||||
const OUTPUT_ZIP_NAME = 'anime4k-High-end.zip';
|
||||
const EXTRACTION_DIR = path.join(OUTPUT_DIR, 'portable_config');
|
||||
|
||||
// Common 7z.exe installation paths on Windows
|
||||
const COMMON_7Z_PATHS = [
|
||||
path.join(process.env.PROGRAMFILES || 'C:\\Program Files', '7-Zip', '7z.exe'),
|
||||
path.join(process.env['PROGRAMFILES(X86)'] || 'C:\\Program Files (x86)', '7-Zip', '7z.exe'),
|
||||
path.join(process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local'), '7-Zip', '7z.exe')
|
||||
];
|
||||
|
||||
// Maximum number of redirects to follow
|
||||
const MAX_REDIRECTS = 5;
|
||||
|
||||
// Helper Functions
|
||||
|
||||
function httpsGet(url, headers = {}, redirectCount = 0) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (redirectCount > MAX_REDIRECTS) return reject(new Error('Too many redirects'));
|
||||
|
||||
const options = {
|
||||
headers: {
|
||||
'User-Agent': 'Node.js Script',
|
||||
...headers
|
||||
}
|
||||
};
|
||||
https.get(url, options, (res) => {
|
||||
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
||||
return resolve(httpsGet(res.headers.location, headers, redirectCount + 1));
|
||||
}
|
||||
if (res.statusCode !== 200) {
|
||||
res.resume();
|
||||
return reject(new Error(`Request Failed. Status Code: ${res.statusCode}`));
|
||||
}
|
||||
let data = '';
|
||||
res.setEncoding('utf8');
|
||||
res.on('data', chunk => data += chunk);
|
||||
res.on('end', () => resolve(data));
|
||||
}).on('error', e => reject(e));
|
||||
});
|
||||
}
|
||||
|
||||
function downloadFile(url, dest, headers = {}, redirectCount = 0) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (redirectCount > MAX_REDIRECTS) return reject(new Error('Too many redirects'));
|
||||
|
||||
const options = {
|
||||
headers: {
|
||||
'User-Agent': 'Node.js Script',
|
||||
...headers
|
||||
}
|
||||
};
|
||||
|
||||
https.get(url, options, (res) => {
|
||||
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
||||
console.log(`Redirecting to ${res.headers.location}`);
|
||||
return resolve(downloadFile(res.headers.location, dest, headers, redirectCount + 1));
|
||||
}
|
||||
if (res.statusCode !== 200) {
|
||||
res.resume();
|
||||
return reject(new Error(`Failed to get '${url}' (${res.statusCode})`));
|
||||
}
|
||||
|
||||
const totalSize = parseInt(res.headers['content-length'], 10);
|
||||
let downloadedSize = 0;
|
||||
const file = fs.createWriteStream(dest);
|
||||
res.pipe(file);
|
||||
|
||||
res.on('data', chunk => {
|
||||
downloadedSize += chunk.length;
|
||||
if (totalSize) {
|
||||
const percent = ((downloadedSize / totalSize) * 100).toFixed(2);
|
||||
process.stdout.write(`Downloading... ${percent}%\r`);
|
||||
} else {
|
||||
process.stdout.write(`Downloading... ${downloadedSize} bytes\r`);
|
||||
}
|
||||
});
|
||||
|
||||
file.on('finish', () => {
|
||||
file.close(() => {
|
||||
process.stdout.write('\n');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
file.on('error', err => {
|
||||
fs.unlink(dest, () => reject(err));
|
||||
});
|
||||
}).on('error', err => reject(err));
|
||||
});
|
||||
}
|
||||
|
||||
function execCommand(command, cwd = process.cwd()) {
|
||||
try {
|
||||
execSync(command, { stdio: 'inherit', cwd });
|
||||
} catch (error) {
|
||||
throw new Error(`Command failed: ${command}\n${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
function commandExists(command) {
|
||||
try {
|
||||
execSync(`where ${command}`, { stdio: 'ignore' });
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function find7zExecutable() {
|
||||
if (commandExists('7z')) {
|
||||
console.log('Found 7z.exe in PATH.');
|
||||
return '7z';
|
||||
}
|
||||
for (const potentialPath of COMMON_7Z_PATHS) {
|
||||
if (fs.existsSync(potentialPath)) {
|
||||
console.log(`Found 7z.exe at: ${potentialPath}`);
|
||||
return `"${potentialPath}"`;
|
||||
}
|
||||
}
|
||||
throw new Error('7z.exe not found. Please install 7-Zip.');
|
||||
}
|
||||
|
||||
// Main Build Function
|
||||
(async function buildAnime4K() {
|
||||
try {
|
||||
console.log('=== Build Anime4K Script Started ===');
|
||||
|
||||
const sevenZipPath = find7zExecutable();
|
||||
|
||||
if (fs.existsSync(TEMP_DIR)) fs.rmSync(TEMP_DIR, { recursive: true, force: true });
|
||||
fs.mkdirSync(TEMP_DIR, { recursive: true });
|
||||
console.log(`Created temporary directory at ${TEMP_DIR}`);
|
||||
|
||||
console.log('Fetching latest Anime4K version information...');
|
||||
const releaseData = await httpsGet(BLOC97_API_URL);
|
||||
const releaseJson = JSON.parse(releaseData);
|
||||
const version = releaseJson.tag_name;
|
||||
console.log(`Latest version: ${version}`);
|
||||
|
||||
const downloadUrl = `https://github.com/Tama47/Anime4K/releases/download/${version}/GLSL_Windows_High-end.zip`;
|
||||
const downloadedFilePath = path.join(TEMP_DIR, 'GLSL_Windows_High-end.zip');
|
||||
|
||||
console.log(`Downloading GLSL_Windows_High-end.zip for version ${version}...`);
|
||||
await downloadFile(downloadUrl, downloadedFilePath);
|
||||
console.log(`Downloaded to ${downloadedFilePath}`);
|
||||
|
||||
// Ensure output directory exists
|
||||
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
|
||||
|
||||
const outputZipPath = path.join(OUTPUT_DIR, OUTPUT_ZIP_NAME);
|
||||
fs.copyFileSync(downloadedFilePath, outputZipPath);
|
||||
console.log(`Saved zip as ${outputZipPath}`);
|
||||
|
||||
// Extract the zip to the anime4k folder
|
||||
fs.mkdirSync(EXTRACTION_DIR, { recursive: true });
|
||||
console.log(`Extracting ${outputZipPath} to ${EXTRACTION_DIR}...`);
|
||||
execCommand(`${sevenZipPath} x "${outputZipPath}" -o"${EXTRACTION_DIR}" -y`);
|
||||
console.log('Extraction complete.');
|
||||
|
||||
// Path to the mpv.conf file inside the extraction directory
|
||||
const mpvConfPath = path.join(EXTRACTION_DIR, 'mpv.conf');
|
||||
|
||||
// Check if mpv.conf exists before attempting to modify it
|
||||
if (fs.existsSync(mpvConfPath)) {
|
||||
console.log(`Modifying ${mpvConfPath} to comment out glsl-shaders lines...`);
|
||||
// Read the existing content of mpv.conf
|
||||
let confData = fs.readFileSync(mpvConfPath, 'utf8');
|
||||
// Split the file into lines
|
||||
const lines = confData.split(/\r?\n/);
|
||||
// Map over lines to comment out ones that start with 'glsl-shaders='
|
||||
const modifiedLines = lines.map(line => {
|
||||
// Trim whitespace at beginning of line for accurate check
|
||||
const trimmedLine = line.trim();
|
||||
if (trimmedLine.startsWith('glsl-shaders=')) {
|
||||
// If not already commented out, add a comment marker
|
||||
if (!trimmedLine.startsWith('#')) {
|
||||
return `# ${line}`;
|
||||
}
|
||||
}
|
||||
return line;
|
||||
});
|
||||
// Join the modified lines back together
|
||||
confData = modifiedLines.join(os.EOL);
|
||||
// Write the changes back to mpv.conf
|
||||
fs.writeFileSync(mpvConfPath, confData, 'utf8');
|
||||
console.log('Modification complete.');
|
||||
} else {
|
||||
console.log(`Warning: ${mpvConfPath} not found. Skipping modification.`);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
console.log(`Cleaning up temporary files at ${TEMP_DIR}...`);
|
||||
fs.rmSync(TEMP_DIR, { recursive: true, force: true });
|
||||
console.log('Cleanup complete.');
|
||||
|
||||
console.log('=== Build Anime4K Script Completed Successfully ===');
|
||||
process.exit(1);
|
||||
} catch (error) {
|
||||
console.error('Error during build:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
})();
|
||||
354
build/build_animejanai.js
Normal file
354
build/build_animejanai.js
Normal file
|
|
@ -0,0 +1,354 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* build_animejanai.js
|
||||
*
|
||||
* This script performs the following:
|
||||
* 1. Downloads the latest 'full-package' .7z release from Animejanai GitHub.
|
||||
* 2. Extracts the archive.
|
||||
* 3. Deletes specified files and folders.
|
||||
* 4. Modifies configuration files as per stremio requirements.
|
||||
* 5. Repackages the modified files into a new .7z archive with maximum compression.
|
||||
* 6. Places the final archive in utils/mpv.
|
||||
* 7. Cleans up temporary files.
|
||||
*
|
||||
* Usage:
|
||||
* node build_animejanai.js
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const https = require('https');
|
||||
const { execSync } = require('child_process');
|
||||
const os = require('os');
|
||||
|
||||
// Configuration
|
||||
const GITHUB_API_URL = 'https://api.github.com/repos/the-database/mpv-upscale-2x_animejanai/releases/latest';
|
||||
const TEMP_DIR = path.join(os.tmpdir(), 'animejanai_build_temp');
|
||||
const OUTPUT_DIR = path.resolve(__dirname, '..', 'utils', 'mpv', 'stremio-animejanai');
|
||||
const OUTPUT_FILENAME_TEMPLATE = 'stremio-animejanai-{version}.7z';
|
||||
|
||||
// Files and directories to delete
|
||||
const FILES_TO_DELETE = [
|
||||
'libmpv-2.dll',
|
||||
'libmpvnet.pdb',
|
||||
'MediaInfo.dll',
|
||||
'mpvnet.com',
|
||||
'mpvnet.dll.config',
|
||||
'mpvnet.exe',
|
||||
'mpvnet.pdb',
|
||||
'NGettext.Wpf.pdb'
|
||||
];
|
||||
|
||||
const FOLDERS_TO_DELETE = [
|
||||
'Locale'
|
||||
];
|
||||
|
||||
// Configuration for input.conf replacement
|
||||
const NEW_INPUT_CONF_CONTENT = `
|
||||
Ctrl+E show-text "Launching AnimeJaNaiConfEditor..."; run "~~\\..\\animejanai\\AnimeJaNaiConfEditor.exe" #menu: AnimeJaNai > Launch AnimeJaNaiConfEditor
|
||||
Ctrl+J script-binding "show_animejanai_stats" #menu: AnimeJaNai > Toggle AnimeJaNai Stats
|
||||
|
||||
) show-text "2x_AnimeJaNai_V3 Off"; apply-profile upscale-off;
|
||||
Ctrl+0 show-text "2x_AnimeJaNai_V3 Off"; apply-profile upscale-off;
|
||||
SHIFT+1 show-text "2x_AnimeJaNai_V3 Quality"; apply-profile upscale-on-quality;
|
||||
SHIFT+2 show-text "2x_AnimeJaNai_V3 Balanced"; apply-profile upscale-on-balanced;
|
||||
SHIFT+3 show-text "2x_AnimeJaNai_V3 Performance"; apply-profile upscale-on-performance;
|
||||
Ctrl+1 show-text "2x_AnimeJaNai_V3 Custom Profile 1"; apply-profile upscale-on-1;
|
||||
Ctrl+2 show-text "2x_AnimeJaNai_V3 Custom Profile 2"; apply-profile upscale-on-2;
|
||||
Ctrl+3 show-text "2x_AnimeJaNai_V3 Custom Profile 3"; apply-profile upscale-on-3;
|
||||
Ctrl+4 show-text "2x_AnimeJaNai_V3 Custom Profile 4"; apply-profile upscale-on-4;
|
||||
Ctrl+5 show-text "2x_AnimeJaNai_V3 Custom Profile 5"; apply-profile upscale-on-5;
|
||||
Ctrl+6 show-text "2x_AnimeJaNai_V3 Custom Profile 6"; apply-profile upscale-on-6;
|
||||
Ctrl+7 show-text "2x_AnimeJaNai_V3 Custom Profile 7"; apply-profile upscale-on-7;
|
||||
Ctrl+8 show-text "2x_AnimeJaNai_V3 Custom Profile 8"; apply-profile upscale-on-8;
|
||||
Ctrl+9 show-text "2x_AnimeJaNai_V3 Custom Profile 9"; apply-profile upscale-on-9;
|
||||
`;
|
||||
|
||||
// Lines to delete from mpv.conf
|
||||
const LINES_TO_DELETE_IN_MPV_CONF = [
|
||||
'save-position-on-quit=yes',
|
||||
'watch-later-options=start',
|
||||
'reset-on-next-file=pause'
|
||||
];
|
||||
|
||||
// Common 7z.exe installation paths on Windows
|
||||
const COMMON_7Z_PATHS = [
|
||||
path.join(process.env.PROGRAMFILES || 'C:\\Program Files', '7-Zip', '7z.exe'),
|
||||
path.join(process.env['PROGRAMFILES(X86)'] || 'C:\\Program Files (x86)', '7-Zip', '7z.exe'),
|
||||
path.join(process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local'), '7-Zip', '7z.exe')
|
||||
];
|
||||
|
||||
// Maximum number of redirects to follow
|
||||
const MAX_REDIRECTS = 5;
|
||||
|
||||
// Function to make HTTPS GET requests with GitHub API headers
|
||||
function httpsGet(url, headers = {}, redirectCount = 0) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (redirectCount > MAX_REDIRECTS) {
|
||||
return reject(new Error('Too many redirects'));
|
||||
}
|
||||
|
||||
const options = {
|
||||
headers: {
|
||||
'User-Agent': 'Node.js Script',
|
||||
...headers
|
||||
}
|
||||
};
|
||||
https.get(url, options, (res) => {
|
||||
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
||||
// Handle redirects
|
||||
resolve(httpsGet(res.headers.location, headers, redirectCount + 1));
|
||||
return;
|
||||
}
|
||||
if (res.statusCode !== 200) {
|
||||
reject(new Error(`Request Failed. Status Code: ${res.statusCode}`));
|
||||
res.resume(); // Consume response data to free up memory
|
||||
return;
|
||||
}
|
||||
let data = '';
|
||||
res.setEncoding('utf8');
|
||||
res.on('data', (chunk) => data += chunk);
|
||||
res.on('end', () => resolve(data));
|
||||
}).on('error', (e) => reject(e));
|
||||
});
|
||||
}
|
||||
|
||||
// Function to download a file from a URL, handling redirects and showing progress
|
||||
function downloadFile(url, dest, headers = {}, redirectCount = 0) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (redirectCount > MAX_REDIRECTS) {
|
||||
return reject(new Error('Too many redirects'));
|
||||
}
|
||||
|
||||
const options = {
|
||||
headers: {
|
||||
'User-Agent': 'Node.js Script',
|
||||
...headers
|
||||
}
|
||||
};
|
||||
|
||||
https.get(url, options, (res) => {
|
||||
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
||||
// Handle redirects
|
||||
console.log(`Redirecting to ${res.headers.location}`);
|
||||
downloadFile(res.headers.location, dest, headers, redirectCount + 1).then(resolve).catch(reject);
|
||||
return;
|
||||
}
|
||||
|
||||
if (res.statusCode !== 200) {
|
||||
reject(new Error(`Failed to get '${url}' (${res.statusCode})`));
|
||||
res.resume();
|
||||
return;
|
||||
}
|
||||
|
||||
const totalSize = parseInt(res.headers['content-length'], 10);
|
||||
let downloadedSize = 0;
|
||||
|
||||
const file = fs.createWriteStream(dest);
|
||||
res.pipe(file);
|
||||
|
||||
res.on('data', (chunk) => {
|
||||
downloadedSize += chunk.length;
|
||||
if (totalSize) {
|
||||
const percent = ((downloadedSize / totalSize) * 100).toFixed(2);
|
||||
process.stdout.write(`Downloading... ${percent}%\r`);
|
||||
} else {
|
||||
process.stdout.write(`Downloading... ${downloadedSize} bytes\r`);
|
||||
}
|
||||
});
|
||||
|
||||
file.on('finish', () => {
|
||||
file.close(() => {
|
||||
process.stdout.write('\n');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
file.on('error', (err) => {
|
||||
fs.unlink(dest, () => reject(err));
|
||||
});
|
||||
}).on('error', (err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Function to execute a shell command synchronously
|
||||
function execCommand(command, cwd = process.cwd()) {
|
||||
try {
|
||||
execSync(command, { stdio: 'inherit', cwd });
|
||||
} catch (error) {
|
||||
throw new Error(`Command failed: ${command}\n${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Function to check if a command exists
|
||||
function commandExists(command) {
|
||||
try {
|
||||
execSync(`where ${command}`, { stdio: 'ignore' });
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Function to find 7z.exe in common installation paths
|
||||
function find7zExecutable() {
|
||||
// First, check if 7z is in PATH
|
||||
if (commandExists('7z')) {
|
||||
console.log('Found 7z.exe in PATH.');
|
||||
return '7z';
|
||||
}
|
||||
|
||||
// Search in common installation directories
|
||||
for (const potentialPath of COMMON_7Z_PATHS) {
|
||||
if (fs.existsSync(potentialPath)) {
|
||||
console.log(`Found 7z.exe at: ${potentialPath}`);
|
||||
return `"${potentialPath}"`; // Quote the path in case it contains spaces
|
||||
}
|
||||
}
|
||||
|
||||
// If not found, throw an error
|
||||
throw new Error('7z.exe not found. Please install 7-Zip and ensure 7z.exe is in your PATH or installed in a common directory.');
|
||||
}
|
||||
|
||||
// Main Build Function
|
||||
(async function buildAnimeJanai() {
|
||||
try {
|
||||
console.log('=== Build AnimeJaNai Script Started ===');
|
||||
|
||||
// Locate 7z.exe
|
||||
const sevenZipPath = find7zExecutable();
|
||||
|
||||
// Create temporary directory
|
||||
if (fs.existsSync(TEMP_DIR)) {
|
||||
fs.rmSync(TEMP_DIR, { recursive: true, force: true });
|
||||
}
|
||||
fs.mkdirSync(TEMP_DIR, { recursive: true });
|
||||
console.log(`Created temporary directory at ${TEMP_DIR}`);
|
||||
|
||||
// Step 1: Fetch latest release info from GitHub
|
||||
console.log('Fetching latest release information from GitHub...');
|
||||
const releaseData = await httpsGet(GITHUB_API_URL);
|
||||
const releaseJson = JSON.parse(releaseData);
|
||||
const version = releaseJson.tag_name || 'latest';
|
||||
console.log(`Latest version: ${version}`);
|
||||
|
||||
// Step 2: Find the 'full-package' .7z asset
|
||||
const assets = releaseJson.assets;
|
||||
const fullPackageAsset = assets.find(asset => asset.name.includes('full-package') && asset.name.endsWith('.7z'));
|
||||
|
||||
if (!fullPackageAsset) {
|
||||
throw new Error("No 'full-package' .7z asset found in the latest release.");
|
||||
}
|
||||
|
||||
const downloadUrl = fullPackageAsset.browser_download_url;
|
||||
const assetName = fullPackageAsset.name;
|
||||
const downloadedFilePath = path.join(TEMP_DIR, assetName);
|
||||
|
||||
console.log(`Downloading asset: ${assetName}`);
|
||||
await downloadFile(downloadUrl, downloadedFilePath);
|
||||
console.log(`Downloaded to ${downloadedFilePath}`);
|
||||
|
||||
// Step 3: Extract the .7z archive
|
||||
const extractDir = path.join(TEMP_DIR, 'extracted');
|
||||
fs.mkdirSync(extractDir, { recursive: true });
|
||||
console.log(`Extracting ${downloadedFilePath} to ${extractDir}...`);
|
||||
execCommand(`${sevenZipPath} x "${downloadedFilePath}" -o"${extractDir}" -y`, TEMP_DIR);
|
||||
console.log('Extraction complete.');
|
||||
|
||||
// Step 4: Identify the root directory inside the extracted folder
|
||||
const extractedItems = fs.readdirSync(extractDir);
|
||||
let rootDir = extractDir;
|
||||
|
||||
if (extractedItems.length === 1 && fs.lstatSync(path.join(extractDir, extractedItems[0])).isDirectory()) {
|
||||
rootDir = path.join(extractDir, extractedItems[0]);
|
||||
console.log(`Detected root directory: ${rootDir}`);
|
||||
} else {
|
||||
console.log('No single root directory detected. Proceeding with extracted contents.');
|
||||
}
|
||||
|
||||
// Step 5: Delete specified files
|
||||
console.log('Deleting specified files...');
|
||||
FILES_TO_DELETE.forEach(file => {
|
||||
const filePath = path.join(rootDir, file);
|
||||
if (fs.existsSync(filePath)) {
|
||||
fs.unlinkSync(filePath);
|
||||
console.log(`Deleted file: ${filePath}`);
|
||||
} else {
|
||||
console.log(`File not found (skipped): ${filePath}`);
|
||||
}
|
||||
});
|
||||
|
||||
// Step 6: Delete specified folders
|
||||
console.log('Deleting specified folders...');
|
||||
FOLDERS_TO_DELETE.forEach(folder => {
|
||||
const folderPath = path.join(rootDir, folder);
|
||||
if (fs.existsSync(folderPath)) {
|
||||
fs.rmSync(folderPath, { recursive: true, force: true });
|
||||
console.log(`Deleted folder: ${folderPath}`);
|
||||
} else {
|
||||
console.log(`Folder not found (skipped): ${folderPath}`);
|
||||
}
|
||||
});
|
||||
|
||||
// Step 7: Modify portable_config/input.conf
|
||||
const portableConfigDir = path.join(rootDir, 'portable_config');
|
||||
const inputConfPath = path.join(portableConfigDir, 'input.conf');
|
||||
|
||||
if (fs.existsSync(inputConfPath)) {
|
||||
fs.writeFileSync(inputConfPath, NEW_INPUT_CONF_CONTENT, 'utf8');
|
||||
console.log(`Modified input.conf at ${inputConfPath}`);
|
||||
} else {
|
||||
console.warn(`input.conf not found at ${inputConfPath}. Skipping modification.`);
|
||||
}
|
||||
|
||||
// Step 8: Modify mpv.conf
|
||||
const mpvConfPath = path.join(portableConfigDir, 'mpv.conf'); // Corrected path
|
||||
|
||||
if (fs.existsSync(mpvConfPath)) {
|
||||
let mpvConfContent = fs.readFileSync(mpvConfPath, 'utf8');
|
||||
|
||||
// Replace vo={something} with vo=libmpv
|
||||
mpvConfContent = mpvConfContent.replace(/^vo=.*/m, 'vo=libmpv');
|
||||
|
||||
// Remove specified lines
|
||||
LINES_TO_DELETE_IN_MPV_CONF.forEach(line => {
|
||||
const regex = new RegExp(`^${line}$`, 'm');
|
||||
mpvConfContent = mpvConfContent.replace(regex, '');
|
||||
});
|
||||
|
||||
// Write the modified content back
|
||||
fs.writeFileSync(mpvConfPath, mpvConfContent, 'utf8');
|
||||
console.log(`Modified mpv.conf at ${mpvConfPath}`);
|
||||
} else {
|
||||
console.warn(`mpv.conf not found at ${mpvConfPath}. Skipping modification.`);
|
||||
}
|
||||
|
||||
// Step 9: Repack the modified files into a new .7z archive
|
||||
const outputVersion = version.startsWith('v') ? version.slice(1) : version;
|
||||
const outputFilename = OUTPUT_FILENAME_TEMPLATE.replace('{version}', outputVersion);
|
||||
const outputFilePath = path.join(OUTPUT_DIR, outputFilename);
|
||||
|
||||
// Ensure output directory exists
|
||||
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
|
||||
|
||||
console.log(`Packing modified files into ${outputFilePath} with maximum compression...`);
|
||||
|
||||
// Change working directory to rootDir to ensure files are added directly
|
||||
execCommand(`${sevenZipPath} a -t7z "${outputFilePath}" * -mx=9`, rootDir);
|
||||
console.log(`Packaged archive created at ${outputFilePath}`);
|
||||
|
||||
// Step 10: Cleanup temporary directory
|
||||
console.log(`Cleaning up temporary files at ${TEMP_DIR}...`);
|
||||
fs.rmSync(TEMP_DIR, { recursive: true, force: true });
|
||||
console.log('Cleanup complete.');
|
||||
|
||||
console.log('=== Build AnimeJaNai Script Completed Successfully ===');
|
||||
process.exit(1);
|
||||
} catch (error) {
|
||||
console.error('Error during build:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
})();
|
||||
381
build/build_checksums.js
Normal file
381
build/build_checksums.js
Normal file
|
|
@ -0,0 +1,381 @@
|
|||
/****************************************************
|
||||
* build_checksums.js
|
||||
*
|
||||
* Usage:
|
||||
* node build_checksums.js "<OpenSSLBinPath>" "<GitTag>" "<ShellVersion>" "<ServerVersion>"
|
||||
*
|
||||
* Example:
|
||||
* node build_checksums.js "C:\\Program Files\\OpenSSL-Win64\\bin" "5.0.0-beta.7" "5.0.7" "4.20.11"
|
||||
*
|
||||
* This script:
|
||||
* 1) Validates CLI args: OPENSSL_BIN, GIT_TAG, SHELL_VERSION, SERVER_VERSION
|
||||
* 2) Locates and verifies openssl.exe
|
||||
* 3) Computes sha256 checksums for Stremio.<ShellVersion>-x64.exe, -x86.exe, and server.js
|
||||
* 4) Updates version-details.json and version.json for the built-in auto-updater.
|
||||
* 5) Signs version-details.json, base64-encodes the signature, injects signature into version.json.
|
||||
* 6) Cleans up ephemeral signature files.
|
||||
* 7) Also updates:
|
||||
* - utils/chocolatey/stremio.nuspec (the <version> tag)
|
||||
* - utils/chocolatey/tools/chocolateyinstall.ps1 (the download URL(s))
|
||||
* - utils/scoop/stremio-desktop-v5.json (the "version", "url", and "hash" fields for x86/x64)
|
||||
* 8) Generates .sha256 files for the x86/x64 executables (so Scoop autoupdate can consume them).
|
||||
*
|
||||
****************************************************/
|
||||
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const { execFileSync } = require("child_process");
|
||||
|
||||
// Parse CLI arguments
|
||||
const [,, OPENSSL_BIN, GIT_TAG, SHELL_VERSION, SERVER_VERSION] = process.argv;
|
||||
|
||||
(async function main() {
|
||||
// 1) Validate args
|
||||
if (!OPENSSL_BIN || !GIT_TAG || !SHELL_VERSION || !SERVER_VERSION) {
|
||||
console.error("Usage: node build_checksums.js <OpenSSLBinPath> <GitTag> <ShellVersion> <ServerVersion>");
|
||||
console.error('Example: node build_checksums.js "C:\\Program Files\\OpenSSL-Win64\\bin" "5.0.0-beta.7" "5.0.7" 4.20.11');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// 2) Verify openssl.exe
|
||||
const opensslExe = path.join(OPENSSL_BIN, "openssl.exe");
|
||||
if (!fs.existsSync(opensslExe)) {
|
||||
console.error("ERROR: Cannot find openssl.exe in:", opensslExe);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log("Using OpenSSL at:", OPENSSL_BIN);
|
||||
console.log("Git Tag:", GIT_TAG);
|
||||
console.log("Shell Version:", SHELL_VERSION);
|
||||
console.log("server.js Version:", SERVER_VERSION);
|
||||
console.log();
|
||||
|
||||
// 3) Build paths
|
||||
const scriptDir = path.dirname(__filename);
|
||||
const projectRoot = path.resolve(scriptDir, "..");
|
||||
|
||||
// The local EXE file names; adapt if your naming convention differs
|
||||
const exeNameX64 = `Stremio ${SHELL_VERSION}-x64.exe`;
|
||||
const exeNameX86 = `Stremio ${SHELL_VERSION}-x86.exe`;
|
||||
|
||||
const EXE_PATH_x64 = path.join(projectRoot, "utils", exeNameX64);
|
||||
const EXE_PATH_x86 = path.join(projectRoot, "utils", exeNameX86);
|
||||
|
||||
// Where is server.js? Adjust if needed
|
||||
const SERVERJS_PATH = path.join(projectRoot, "utils", "windows", "server.js");
|
||||
|
||||
// version details
|
||||
const VERSION_DETAILS_PATH = path.join(projectRoot, "version", "version-details.json");
|
||||
const VERSION_JSON_PATH = path.join(projectRoot, "version", "version.json");
|
||||
const PRIVATE_KEY = path.join(projectRoot, "private_key.pem");
|
||||
|
||||
// Paths to your choco and scoop files:
|
||||
const CHOCO_NUSPEC_PATH = path.join(projectRoot, "utils", "chocolatey", "stremio.nuspec");
|
||||
const CHOCO_INSTALL_PS1_PATH = path.join(projectRoot, "utils", "chocolatey", "tools", "chocolateyinstall.ps1");
|
||||
const SCOOP_MANIFEST_PATH = path.join(projectRoot, "utils", "scoop", "stremio-desktop-v5.json");
|
||||
|
||||
// 4) Generate SHA-256 for the .exe and server.js
|
||||
checkFileExists(EXE_PATH_x64, "Stremio x64 .exe");
|
||||
checkFileExists(EXE_PATH_x86, "Stremio x86 .exe");
|
||||
const exeHash_x64 = computeSha256(opensslExe, EXE_PATH_x64);
|
||||
const exeHash_x86 = computeSha256(opensslExe, EXE_PATH_x86);
|
||||
|
||||
checkFileExists(SERVERJS_PATH, "server.js");
|
||||
const serverHash = computeSha256(opensslExe, SERVERJS_PATH);
|
||||
|
||||
console.log("EXE sha256 x64 =", exeHash_x64);
|
||||
console.log("EXE sha256 x86 =", exeHash_x86);
|
||||
console.log("server.js sha256 =", serverHash);
|
||||
console.log();
|
||||
|
||||
// 5) Update version-details.json
|
||||
checkFileExists(VERSION_DETAILS_PATH, "version-details.json");
|
||||
let versionDetails;
|
||||
try {
|
||||
versionDetails = JSON.parse(fs.readFileSync(VERSION_DETAILS_PATH, "utf8"));
|
||||
} catch (err) {
|
||||
console.error("ERROR: Unable to parse version-details.json:", err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Ensure structure
|
||||
if (!versionDetails.files) {
|
||||
console.error("ERROR: version-details.json missing property 'files'");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Update version-details.json
|
||||
versionDetails.shellVersion = SHELL_VERSION;
|
||||
|
||||
// windows-x64
|
||||
if (!versionDetails.files["windows-x64"]) versionDetails.files["windows-x64"] = {};
|
||||
versionDetails.files["windows-x64"].url = `https://github.com/Zaarrg/stremio-desktop-v5/releases/download/${GIT_TAG}/Stremio.${SHELL_VERSION}-x64.exe`;
|
||||
versionDetails.files["windows-x64"].checksum = exeHash_x64;
|
||||
|
||||
// windows-x86
|
||||
if (!versionDetails.files["windows-x86"]) versionDetails.files["windows-x86"] = {};
|
||||
versionDetails.files["windows-x86"].url = `https://github.com/Zaarrg/stremio-desktop-v5/releases/download/${GIT_TAG}/Stremio.${SHELL_VERSION}-x86.exe`;
|
||||
versionDetails.files["windows-x86"].checksum = exeHash_x86;
|
||||
|
||||
// server.js
|
||||
if (!versionDetails.files["server.js"]) versionDetails.files["server.js"] = {};
|
||||
versionDetails.files["server.js"].url = `https://dl.strem.io/server/${SERVER_VERSION}/desktop/server.js`;
|
||||
versionDetails.files["server.js"].checksum = serverHash;
|
||||
|
||||
// Save updated version-details.json
|
||||
try {
|
||||
fs.writeFileSync(VERSION_DETAILS_PATH, JSON.stringify(versionDetails, null, 2), "utf8");
|
||||
} catch (e) {
|
||||
console.error("ERROR: Failed writing version-details.json:", e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// 6) Sign version-details.json & base64-encode
|
||||
checkFileExists(PRIVATE_KEY, "private_key.pem");
|
||||
process.chdir(path.join(projectRoot, "version"));
|
||||
|
||||
const sigFile = path.join(process.cwd(), "version-details.json.sig");
|
||||
const sigB64 = path.join(process.cwd(), "version-details.json.sig.b64");
|
||||
if (fs.existsSync(sigFile)) fs.unlinkSync(sigFile);
|
||||
if (fs.existsSync(sigB64)) fs.unlinkSync(sigB64);
|
||||
|
||||
console.log(`Signing version-details.json with ${PRIVATE_KEY}...`);
|
||||
try {
|
||||
execFileSync(opensslExe, [
|
||||
"dgst",
|
||||
"-sha256",
|
||||
"-sign",
|
||||
PRIVATE_KEY,
|
||||
"-out",
|
||||
"version-details.json.sig",
|
||||
"version-details.json"
|
||||
], { stdio: "inherit" });
|
||||
} catch (err) {
|
||||
console.error("ERROR: Signing failed:", err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
execFileSync(opensslExe, [
|
||||
"base64",
|
||||
"-in",
|
||||
"version-details.json.sig",
|
||||
"-out",
|
||||
"version-details.json.sig.b64"
|
||||
], { stdio: "inherit" });
|
||||
} catch (err) {
|
||||
console.error("ERROR: Base64 encoding failed:", err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (!fs.existsSync(sigB64)) {
|
||||
console.error("ERROR: Could not create signature file:", sigB64);
|
||||
process.exit(1);
|
||||
}
|
||||
process.chdir(projectRoot);
|
||||
|
||||
// 7) Insert signature into version.json
|
||||
checkFileExists(VERSION_JSON_PATH, "version.json");
|
||||
console.log(`Updating signature in "${VERSION_JSON_PATH}"...`);
|
||||
let signatureB64;
|
||||
try {
|
||||
signatureB64 = fs.readFileSync(sigB64, "utf8").replace(/\r?\n/g, "");
|
||||
} catch (err) {
|
||||
console.error("ERROR: Unable to read version-details.json.sig.b64:", err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
let versionJson;
|
||||
try {
|
||||
versionJson = JSON.parse(fs.readFileSync(VERSION_JSON_PATH, "utf8"));
|
||||
} catch (err) {
|
||||
console.error("ERROR: Unable to parse version.json:", err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
versionJson.signature = signatureB64;
|
||||
try {
|
||||
fs.writeFileSync(VERSION_JSON_PATH, JSON.stringify(versionJson, null, 2), "utf8");
|
||||
} catch (err) {
|
||||
console.error("ERROR: Unable to write version.json:", err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Cleanup ephemeral signature files
|
||||
try {
|
||||
if (fs.existsSync(sigFile)) fs.unlinkSync(sigFile);
|
||||
if (fs.existsSync(sigB64)) fs.unlinkSync(sigB64);
|
||||
} catch (cleanupErr) {
|
||||
console.error("WARNING: Could not remove signature files:", cleanupErr.message);
|
||||
}
|
||||
|
||||
console.log("\nSuccess! Checksums and signature updated. Now updating Scoop & Chocolatey files...\n");
|
||||
|
||||
// 8) Update stremio.nuspec <version>
|
||||
updateStremioNuspec(CHOCO_NUSPEC_PATH, SHELL_VERSION);
|
||||
|
||||
// 9) Update chocolateyinstall.ps1 URLs
|
||||
updateChocolateyInstall(CHOCO_INSTALL_PS1_PATH, GIT_TAG, SHELL_VERSION);
|
||||
|
||||
// 10) Update the Scoop manifest (stremio-desktop-v5.json)
|
||||
updateScoopManifest(SCOOP_MANIFEST_PATH, GIT_TAG, SHELL_VERSION, exeHash_x64, exeHash_x86);
|
||||
|
||||
// 11) Generate .sha256 files for each EXE in /utils.
|
||||
// This is required if you keep "hash.url" in your Scoop "autoupdate" section.
|
||||
generateSha256FilesForScoop(
|
||||
projectRoot,
|
||||
GIT_TAG,
|
||||
SHELL_VERSION,
|
||||
{ x64: exeHash_x64, x86: exeHash_x86 }
|
||||
);
|
||||
|
||||
console.log("\nAll updates complete. You may now commit/push these changes and attach the .exe and .sha256 files to your release.\n");
|
||||
process.exit(0);
|
||||
|
||||
})().catch(err => {
|
||||
console.error("Unexpected error:", err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
|
||||
/************************************************************
|
||||
* Helper Functions
|
||||
************************************************************/
|
||||
|
||||
function checkFileExists(filePath, label) {
|
||||
if (!fs.existsSync(filePath)) {
|
||||
console.error(`ERROR: ${label} file not found at: ${filePath}`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// runs "openssl dgst -sha256 <file>" and returns the hex string
|
||||
function computeSha256(opensslExe, filePath) {
|
||||
try {
|
||||
const output = execFileSync(opensslExe, ["dgst", "-sha256", filePath], { encoding: "utf8" });
|
||||
// Typically "SHA256(file)= <hexhash>"
|
||||
const match = output.match(/=.\s*([0-9a-fA-F]+)/);
|
||||
if (!match) {
|
||||
console.error("ERROR: Unexpected openssl dgst output for", filePath, "-", output);
|
||||
process.exit(1);
|
||||
}
|
||||
return match[1].toLowerCase();
|
||||
} catch (err) {
|
||||
console.error(`ERROR: openssl dgst failed for ${filePath}:`, err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// 8) Update the stremio.nuspec with the new <version>
|
||||
function updateStremioNuspec(nuspecPath, newVersion) {
|
||||
checkFileExists(nuspecPath, "stremio.nuspec");
|
||||
let content = fs.readFileSync(nuspecPath, "utf8");
|
||||
|
||||
// Replace the <version>...</version> with newVersion
|
||||
content = content.replace(
|
||||
/<version>[^<]+<\/version>/,
|
||||
`<version>${newVersion}</version>`
|
||||
);
|
||||
|
||||
fs.writeFileSync(nuspecPath, content, "utf8");
|
||||
console.log(`Updated stremio.nuspec <version> to ${newVersion}`);
|
||||
}
|
||||
|
||||
// 9) Update chocolateyinstall.ps1 with new GIT_TAG + SHELL_VERSION in the URLs
|
||||
function updateChocolateyInstall(ps1Path, gitTag, newVersion) {
|
||||
checkFileExists(ps1Path, "chocolateyinstall.ps1");
|
||||
let content = fs.readFileSync(ps1Path, "utf8");
|
||||
|
||||
// For 64-bit:
|
||||
// if ([Environment]::Is64BitOperatingSystem) {
|
||||
// $packageArgs['url'] = 'https://github.com/Zaarrg/stremio-desktop-v5/releases/download/<GIT_TAG>/Stremio.<SHELL_VERSION>-x64.exe'
|
||||
// }
|
||||
const new64Url = `if ([Environment]::Is64BitOperatingSystem) {\n $packageArgs['url'] = 'https://github.com/Zaarrg/stremio-desktop-v5/releases/download/${gitTag}/Stremio.${newVersion}-x64.exe'`;
|
||||
content = content.replace(
|
||||
/if\s*\(\[Environment\]::Is64BitOperatingSystem\)\s*\{\s*\$packageArgs\['url'\]\s*=\s*'[^']+/m,
|
||||
new64Url
|
||||
);
|
||||
|
||||
// For 32-bit:
|
||||
// } else {
|
||||
// $packageArgs['url'] = 'https://github.com/Zaarrg/stremio-desktop-v5/releases/download/<GIT_TAG>/Stremio.<SHELL_VERSION>-x86.exe'
|
||||
// }
|
||||
const new86Url = `} else {\n $packageArgs['url'] = 'https://github.com/Zaarrg/stremio-desktop-v5/releases/download/${gitTag}/Stremio.${newVersion}-x86.exe'`;
|
||||
content = content.replace(
|
||||
/}\s*else\s*\{\s*\$packageArgs\['url'\]\s*=\s*'[^']+/m,
|
||||
new86Url
|
||||
);
|
||||
|
||||
fs.writeFileSync(ps1Path, content, "utf8");
|
||||
console.log(`Updated chocolateyinstall.ps1 URLs to version ${newVersion}`);
|
||||
}
|
||||
|
||||
// 10) Update the Scoop manifest stremio-desktop-v5.json
|
||||
function updateScoopManifest(scoopPath, gitTag, newVersion, hash64, hash86) {
|
||||
checkFileExists(scoopPath, "stremio-desktop-v5.json");
|
||||
let scoopJson;
|
||||
|
||||
try {
|
||||
const raw = fs.readFileSync(scoopPath, "utf8");
|
||||
scoopJson = JSON.parse(raw);
|
||||
} catch (err) {
|
||||
console.error("ERROR: Unable to parse scoop manifest JSON:", err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// "version": "5.0.7"
|
||||
scoopJson.version = newVersion;
|
||||
|
||||
if (!scoopJson.architecture || !scoopJson.architecture["64bit"] || !scoopJson.architecture["32bit"]) {
|
||||
console.error("ERROR: scoop manifest missing architecture stanzas");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Update 64bit url + hash
|
||||
scoopJson.architecture["64bit"].url = `https://github.com/Zaarrg/stremio-desktop-v5/releases/download/${gitTag}/Stremio.${newVersion}-x64.exe`;
|
||||
scoopJson.architecture["64bit"].hash = hash64;
|
||||
|
||||
// Update 32bit url + hash
|
||||
scoopJson.architecture["32bit"].url = `https://github.com/Zaarrg/stremio-desktop-v5/releases/download/${gitTag}/Stremio.${newVersion}-x86.exe`;
|
||||
scoopJson.architecture["32bit"].hash = hash86;
|
||||
|
||||
// If you want to rely on .sha256 files for autoupdate, keep the `hash.url` lines in "autoupdate".
|
||||
// If you prefer not to upload .sha256 files, remove or modify that.
|
||||
// Just note that removing them will break the default Scoop auto-updater checks.
|
||||
|
||||
// Save updates
|
||||
try {
|
||||
fs.writeFileSync(scoopPath, JSON.stringify(scoopJson, null, 2), "utf8");
|
||||
} catch (err) {
|
||||
console.error("ERROR: Failed writing scoop manifest:", err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`Updated Scoop manifest with version=${newVersion}, x64Hash=${hash64}, x86Hash=${hash86}`);
|
||||
}
|
||||
|
||||
// 11) Create .sha256 files for each EXE in /utils so Scoop "autoupdate" can fetch them
|
||||
function generateSha256FilesForScoop(projectRoot, gitTag, shellVersion, hashes) {
|
||||
// We'll create: Stremio.<shellVersion>-x64.exe.sha256 and Stremio.<shellVersion>-x86.exe.sha256
|
||||
// in /utils, each containing the hex digest plus a newline.
|
||||
|
||||
const outDir = path.join(projectRoot, "utils");
|
||||
if (!fs.existsSync(outDir)) {
|
||||
fs.mkdirSync(outDir, { recursive: true });
|
||||
}
|
||||
|
||||
// x64
|
||||
const x64filename = `Stremio.${shellVersion}-x64.exe.sha256`;
|
||||
const x64path = path.join(outDir, x64filename);
|
||||
fs.writeFileSync(x64path, hashes.x64 + "\n", "utf8");
|
||||
|
||||
// x86
|
||||
const x86filename = `Stremio.${shellVersion}-x86.exe.sha256`;
|
||||
const x86path = path.join(outDir, x86filename);
|
||||
fs.writeFileSync(x86path, hashes.x86 + "\n", "utf8");
|
||||
|
||||
console.log(
|
||||
`\nGenerated .sha256 files:\n ${x64filename} -> ${hashes.x64}\n ${x86filename} -> ${hashes.x86}\n\n` +
|
||||
"Remember to upload these *.sha256 files alongside your EXEs in the GitHub release if you want Scoop autoupdate to work."
|
||||
);
|
||||
}
|
||||
301
build/deploy_windows.js
Normal file
301
build/deploy_windows.js
Normal file
|
|
@ -0,0 +1,301 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/****************************************************************************
|
||||
* deploy_windows.js
|
||||
*
|
||||
* Builds windows distributable folder dist/win.
|
||||
* Pass --installer to also build the windows installer
|
||||
* Make sure to have set up utils/windows and the environment correctly by following windows.md
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Project/Layout Configuration
|
||||
// ---------------------------------------------------------------------
|
||||
const ARCH = process.argv.includes('--x86') ? 'x86' : 'x64';
|
||||
const SOURCE_DIR = path.resolve(__dirname, '..');
|
||||
const BUILD_DIR = path.join(SOURCE_DIR, `cmake-build-release-${ARCH}`);
|
||||
const DIST_DIR = path.join(SOURCE_DIR, 'dist', `win-${ARCH}`);
|
||||
const CONFIG_DIR = path.join(SOURCE_DIR, 'dist', `win-${ARCH}`, 'portable_config');
|
||||
const PROJECT_NAME = 'stremio';
|
||||
|
||||
// Paths to Additional Dependencies
|
||||
const MPV_DLL = ARCH === 'x86'
|
||||
? path.join(SOURCE_DIR, 'deps', 'libmpv', 'i686', 'libmpv-2.dll')
|
||||
: path.join(SOURCE_DIR, 'deps', 'libmpv', 'x86_64', 'libmpv-2.dll');
|
||||
const SERVER_JS = path.join(SOURCE_DIR, 'utils', 'windows', 'server.js');
|
||||
const STREMIO_RUNTIME_EXE = path.join(SOURCE_DIR, 'utils', 'windows', 'stremio-runtime.exe');
|
||||
const FFMPEG_FOLDER = path.join(SOURCE_DIR, 'utils', 'windows', 'ffmpeg');
|
||||
const MPV_FOLDER = path.join(SOURCE_DIR, 'utils', 'mpv', 'anime4k');
|
||||
const DEFAULT_SETTINGS_FOLDER = path.join(SOURCE_DIR, 'utils', 'stremio');
|
||||
|
||||
// Default Paths
|
||||
const DEFAULT_NSIS = 'C:\\Program Files (x86)\\NSIS\\makensis.exe';
|
||||
//VCPKG
|
||||
const VCPKG_TRIPLET = ARCH === 'x86' ? 'x86-windows-static' : 'x64-windows-static';
|
||||
const VCPKG_CMAKE = 'C:/bin/vcpkg/scripts/buildsystems/vcpkg.cmake';
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Main
|
||||
// ---------------------------------------------------------------------
|
||||
(async function main() {
|
||||
try {
|
||||
console.log(`\n=== Building for ${ARCH.toUpperCase()} ===`);
|
||||
const args = process.argv.slice(2);
|
||||
const buildInstaller = args.includes('--installer');
|
||||
const buildPortable = args.includes('--portable');
|
||||
|
||||
// 3) Run CMake + Ninja in ../cmake-build-release (64-bit)
|
||||
if (!fs.existsSync(BUILD_DIR)) {
|
||||
fs.mkdirSync(BUILD_DIR, { recursive: true });
|
||||
}
|
||||
|
||||
console.log('\n=== Running CMake in cmake-build-release ===');
|
||||
process.chdir(BUILD_DIR);
|
||||
execSync(
|
||||
`cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=${VCPKG_CMAKE} -DVCPKG_TARGET_TRIPLET=${VCPKG_TRIPLET} ..`,
|
||||
{ stdio: 'inherit' }
|
||||
);
|
||||
console.log('=== Running Ninja in cmake-build-release ===');
|
||||
execSync('ninja', { stdio: 'inherit' });
|
||||
|
||||
// Return to script directory
|
||||
process.chdir(__dirname);
|
||||
|
||||
// 4) Prepare dist\win
|
||||
console.log(`\n=== Cleaning and creating ${DIST_DIR} ===`);
|
||||
safeRemove(DIST_DIR);
|
||||
fs.mkdirSync(DIST_DIR, { recursive: true });
|
||||
|
||||
// 5) Copy main .exe
|
||||
const builtExe = path.join(BUILD_DIR, `${PROJECT_NAME}.exe`);
|
||||
const distExe = path.join(DIST_DIR, `${PROJECT_NAME}.exe`);
|
||||
copyFile(builtExe, distExe);
|
||||
|
||||
// 6) Copy mpv DLL, server.js, node.exe
|
||||
copyFile(MPV_DLL, path.join(DIST_DIR, path.basename(MPV_DLL)));
|
||||
copyFile(SERVER_JS, path.join(DIST_DIR, path.basename(SERVER_JS)));
|
||||
|
||||
|
||||
|
||||
|
||||
// 8) Flatten stremio-runtime, ffmpeg
|
||||
console.log('Flattening DS folder, stremio-runtime, ffmpeg...');
|
||||
copyFile(STREMIO_RUNTIME_EXE, path.join(DIST_DIR, 'stremio-runtime.exe'));
|
||||
copyFolderContents(FFMPEG_FOLDER, DIST_DIR);
|
||||
copyFolderContentsPreservingStructure(MPV_FOLDER, DIST_DIR);
|
||||
copyFolderContentsPreservingStructure(DEFAULT_SETTINGS_FOLDER, CONFIG_DIR);
|
||||
|
||||
console.log('\n=== dist\\win preparation complete. ===');
|
||||
|
||||
// 10) If --installer, parse version and build NSIS
|
||||
if (buildInstaller) {
|
||||
console.log('\n--installer detected: building NSIS installer...');
|
||||
// Extract the version first so we can set process.env before calling NSIS
|
||||
const version = getPackageVersionFromCMake();
|
||||
process.env.package_version = version;
|
||||
console.log(`Set package_version to: ${version}`);
|
||||
buildNsisInstaller();
|
||||
} else if (buildPortable) {
|
||||
console.log('\n--portable detected: building Portable...');
|
||||
buildPortableZip();
|
||||
}
|
||||
|
||||
|
||||
console.log('\nAll done!');
|
||||
} catch (err) {
|
||||
console.error('Error in deploy_windows.js:', err);
|
||||
process.exit(1);
|
||||
}
|
||||
})();
|
||||
|
||||
/****************************************************************************
|
||||
* Helper Functions
|
||||
****************************************************************************/
|
||||
|
||||
function safeRemove(dirPath) {
|
||||
if (fs.existsSync(dirPath)) {
|
||||
fs.rmSync(dirPath, { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
|
||||
function copyFile(src, dest) {
|
||||
if (!fs.existsSync(src)) {
|
||||
console.warn(`Warning: missing file: ${src}`);
|
||||
return;
|
||||
}
|
||||
fs.copyFileSync(src, dest);
|
||||
console.log(`Copied: ${src} -> ${dest}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively copies only the contents of "src" into "dest" (flattened).
|
||||
* If src has files/folders, they go directly into dest, rather than
|
||||
* creating a subfolder named src.
|
||||
*/
|
||||
function copyFolderContents(src, dest) {
|
||||
if (!fs.existsSync(src)) {
|
||||
console.warn(`Warning: missing folder: ${src}`);
|
||||
return;
|
||||
}
|
||||
const stats = fs.statSync(src);
|
||||
if (!stats.isDirectory()) {
|
||||
console.warn(`Warning: not a directory: ${src}`);
|
||||
return;
|
||||
}
|
||||
for (const item of fs.readdirSync(src)) {
|
||||
const srcItem = path.join(src, item);
|
||||
const itemStats = fs.statSync(srcItem);
|
||||
const destItem = path.join(dest, item);
|
||||
if (itemStats.isDirectory()) {
|
||||
copyFolderContents(srcItem, dest);
|
||||
} else {
|
||||
copyFile(srcItem, destItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the contents of `src` into `dest` without flattening.
|
||||
* Subdirectories in `src` will be recreated in `dest`.
|
||||
*/
|
||||
function copyFolderContentsPreservingStructure(src, dest) {
|
||||
if (!fs.existsSync(src)) {
|
||||
console.warn(`Warning: missing folder: ${src}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const stats = fs.statSync(src);
|
||||
if (!stats.isDirectory()) {
|
||||
console.warn(`Warning: not a directory: ${src}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure destination directory exists
|
||||
if (!fs.existsSync(dest)) {
|
||||
fs.mkdirSync(dest, { recursive: true });
|
||||
}
|
||||
|
||||
const items = fs.readdirSync(src);
|
||||
|
||||
for (const item of items) {
|
||||
const srcItem = path.join(src, item);
|
||||
const destItem = path.join(dest, item);
|
||||
const itemStats = fs.statSync(srcItem);
|
||||
|
||||
if (itemStats.isDirectory()) {
|
||||
// Recursively copy subdirectories
|
||||
copyFolderContentsPreservingStructure(srcItem, destItem);
|
||||
} else {
|
||||
if (!srcItem.endsWith('zip') && !srcItem.endsWith('7z')) {
|
||||
// Copy files
|
||||
copyFile(srcItem, destItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves version from CMakeLists.txt (handles quotes):
|
||||
* project(stremio VERSION "5.0.2")
|
||||
*/
|
||||
function getPackageVersionFromCMake() {
|
||||
const cmakeFile = path.join(SOURCE_DIR, 'CMakeLists.txt');
|
||||
let version = '0.0.0';
|
||||
if (fs.existsSync(cmakeFile)) {
|
||||
const content = fs.readFileSync(cmakeFile, 'utf8');
|
||||
// Accept either quoted or unquoted numerical version
|
||||
const match = content.match(/project\s*\(\s*stremio\s+VERSION\s+"?([\d.]+)"?\)/i);
|
||||
if (match) {
|
||||
version = match[1];
|
||||
}
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
function buildNsisInstaller() {
|
||||
if (!fs.existsSync(DEFAULT_NSIS)) {
|
||||
console.warn(`NSIS not found at default path: ${DEFAULT_NSIS}. Skipping installer.`);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const arch = process.argv.includes('--x86') ? 'x86' : 'x64'; // Determine architecture
|
||||
const distSubfolder = `win-${arch}`;
|
||||
|
||||
const distFolder = path.join(SOURCE_DIR, 'dist', distSubfolder);
|
||||
if (!fs.existsSync(distFolder)) {
|
||||
console.error(`Error: Distribution folder does not exist: ${distFolder}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
||||
const nsiScript = path.join(SOURCE_DIR, 'utils', 'windows', 'installer', 'windows-installer.nsi');
|
||||
console.log(`Running makensis.exe with version: ${process.env.package_version} ...`);
|
||||
process.env.arch = arch;
|
||||
execSync(`"${DEFAULT_NSIS}" "${nsiScript}"`, { stdio: 'inherit' });
|
||||
console.log(`\nInstaller created: "Stremio ${process.env.package_version}.exe"`);
|
||||
} catch (err) {
|
||||
console.error('Failed to run NSIS (makensis.exe):', err);
|
||||
}
|
||||
}
|
||||
|
||||
function buildPortableZip() {
|
||||
const version = getPackageVersionFromCMake();
|
||||
const portableOutput = path.join(SOURCE_DIR, 'utils', `Stremio ${version}-${ARCH}.7z`);
|
||||
const fixedEdgeWebView = path.join(SOURCE_DIR, 'utils', 'windows', 'WebviewRuntime', ARCH);
|
||||
const portable_config = path.join(DIST_DIR, 'portable_config');
|
||||
const distContents = DIST_DIR; // Path to dist directory contents
|
||||
|
||||
console.log(`\nCreating Portable ZIP: ${portableOutput}`);
|
||||
|
||||
// Common 7-Zip paths
|
||||
const common7zPaths = [
|
||||
'C:\\Program Files\\7-Zip\\7z.exe',
|
||||
'C:\\Program Files (x86)\\7-Zip\\7z.exe'
|
||||
];
|
||||
|
||||
// Find 7-Zip executable
|
||||
const sevenZipPath = common7zPaths.find(fs.existsSync);
|
||||
if (!sevenZipPath) {
|
||||
console.error('Error: 7-Zip executable not found in common paths.');
|
||||
console.error('Please install 7-Zip and ensure it is in one of the following paths:');
|
||||
console.error(common7zPaths.join('\n'));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`Using 7-Zip at: ${sevenZipPath}`);
|
||||
|
||||
// Ensure the DIST_DIR exists
|
||||
if (!fs.existsSync(DIST_DIR)) {
|
||||
console.error(`Error: DIST_DIR does not exist: ${DIST_DIR}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
copyFolderContentsPreservingStructure(fixedEdgeWebView, portable_config);
|
||||
|
||||
// Command to create the 7z archive
|
||||
const zipCommand = `"${sevenZipPath}" a -t7z -mx=9 "${portableOutput}" "${distContents}\\*"`;
|
||||
|
||||
try {
|
||||
// Run the 7-Zip command
|
||||
console.log(`Running: ${zipCommand}`);
|
||||
execSync(zipCommand, { stdio: 'inherit' });
|
||||
console.log(`\nPortable ZIP created: ${portableOutput}`);
|
||||
//Clean UP
|
||||
const portableConfigWebView = path.join(DIST_DIR, 'portable_config', 'EdgeWebView');
|
||||
if (fs.existsSync(portableConfigWebView)) {
|
||||
console.log(`\nCleaning up: ${portableConfigWebView}`);
|
||||
fs.rmSync(portableConfigWebView, { recursive: true, force: true });
|
||||
console.log(`Removed: ${portableConfigWebView}`);
|
||||
} else {
|
||||
console.log(`\nNo cleanup needed: ${portableConfigWebView} does not exist.`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error creating the Portable ZIP:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
24
docs/RELEASE.md
Normal file
24
docs/RELEASE.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# Releasing New Version
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Quick Overview
|
||||
|
||||
1. Bump version in ``cmakelists``
|
||||
2. Build new ``runtime`` and `installer`
|
||||
3. Make sure `installer` is in `/utils` and `server.js` in `/utils/windows`
|
||||
4. Run ``build/build_checksums.js`` this will generate `version.json` and `version-details.json` needed for the auto updater
|
||||
```
|
||||
node build_checksums.js <OpenSSL_Bin> <Git_Tag> <Shell_Version> <Server.js_Version>
|
||||
```
|
||||
```
|
||||
node build_checksums.js "C:\Program Files\OpenSSL-Win64\bin" "5.0.0-beta.1" "5.0.0" v4.20.8
|
||||
```
|
||||
|
||||
> **⏳Note:** Only Windows at the moment
|
||||
|
||||
5. Commit Changes
|
||||
6. Make new release with the Git tag used when running ``build_checksums.js``
|
||||
|
||||
> **⏳Note:** Alternatively u can separate the version bump commit. Instead:
|
||||
> Commit - Release - Build Checksums - Commit Built Checksums
|
||||
141
docs/WINDOWS.md
Normal file
141
docs/WINDOWS.md
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
|
||||
# Building on Windows
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Quick Overview
|
||||
|
||||
This guide walks you through the process of building Stremio on Windows. Follow the steps carefully to set up the environment, build dependencies, and compile the project.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Requirements
|
||||
|
||||
Ensure the following are installed on your system:
|
||||
|
||||
- **Operating System**: Windows 7 or newer
|
||||
- **Utilities**: [7zip](https://www.7-zip.org/) or similar
|
||||
- **Tools**:
|
||||
- [Git](https://git-scm.com/download/win)
|
||||
- [Microsoft Visual Studio](https://visualstudio.microsoft.com/)
|
||||
- [CMake](https://cmake.org/)
|
||||
- [WebView2](https://developer.microsoft.com/de-de/microsoft-edge/webview2/?ch=1&form=MA13LH)
|
||||
- [OpenSSL](https://slproweb.com/products/Win32OpenSSL.html)
|
||||
- [Node.js](https://nodejs.org/)
|
||||
- [FFmpeg](https://ffmpeg.org/download.html)
|
||||
- [MPV](https://sourceforge.net/projects/mpv-player-windows/)
|
||||
|
||||
---
|
||||
|
||||
## 📂 Setup Guide
|
||||
|
||||
### 1️⃣ **Install Essential Tools**
|
||||
- **Git**: [Download](https://git-scm.com/download/win) and install.
|
||||
- **Visual Studio**: [Download Community 2022](https://visualstudio.microsoft.com/de/downloads/).
|
||||
- **Node.js**: Get version [v8.17.0](https://nodejs.org/dist/v8.17.0/win-x86/node.exe).
|
||||
- **FFmpeg**: [Download](https://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-3.3.4-win32-static.zip).
|
||||
*(Other versions may also work)*.
|
||||
|
||||
---
|
||||
|
||||
### 2️⃣ **Install dependency**
|
||||
|
||||
|
||||
1. Download vcpkg [here](https://github.com/microsoft/vcpkg).
|
||||
|
||||
2. Install using vcpkg ``openssl:x64-windows-static`` and ``nlohmann-json:x64-windows-static``
|
||||
|
||||
---
|
||||
|
||||
### 3️⃣ **Prepare the MPV Library**
|
||||
|
||||
- Download the MPV library: [MPV libmpv](https://sourceforge.net/projects/mpv-player-windows/files/libmpv/).
|
||||
- Use the `mpv-x86_64` version.
|
||||
> **⏳ Note:** The submodule https://github.com/Zaarrg/libmpv already includes .lib, just make sure to unzip the actual .dll for x64 systems.
|
||||
---
|
||||
|
||||
### 4️⃣ **Clone and Configure the Repository**
|
||||
|
||||
1. Clone the repository:
|
||||
```cmd
|
||||
git clone --recursive git@github.com:Zaarrg/stremio-desktop-v5.git
|
||||
cd stremio-dekstop-v5
|
||||
```
|
||||
2. Update CMake Options:
|
||||
```cmd
|
||||
-DCMAKE_TOOLCHAIN_FILE=C:/bin/vcpkg/scripts/buildsystems/vcpkg.cmake
|
||||
-DVCPKG_TARGET_TRIPLET=x64-windows-static
|
||||
```
|
||||
|
||||
```cmd
|
||||
-DCMAKE_TOOLCHAIN_FILE=C:\bin\vcpkg\scripts\buildsystems\vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x86-windows-static
|
||||
```
|
||||
3. Download the `server.js` file:
|
||||
```cmd
|
||||
powershell -Command Start-BitsTransfer -Source "https://s3-eu-west-1.amazonaws.com/stremio-artifacts/four/v%package_version%/server.js" -Destination server.js
|
||||
```
|
||||
|
||||
> **⏳ Note:** To run the cmake project make sure to add `stremio-runtime.exe, server.js` beside the `stremio.exe`
|
||||
|
||||
---
|
||||
|
||||
### 5️⃣ **Build / Deploying the Shell**
|
||||
|
||||
1. Make sure to run the following in the `x64 Native Tools Command Prompt for VS 2022` or `x86 Native Tools Command Prompt for VS 2022`
|
||||
|
||||
2. Run the deployment script in the ``build`` folder. By default builds ``x64``
|
||||
```cmd
|
||||
node deploy_windows.js --installer
|
||||
```
|
||||
- For Portable (Needs ``7zip`` and ``/utils/WebviewRuntime/x64/EdgeWebView`` )
|
||||
```cmd
|
||||
node deploy_windows.js --portable
|
||||
```
|
||||
|
||||
- For x86
|
||||
```cmd
|
||||
node deploy_windows.js --x86 --installer
|
||||
```
|
||||
- For Portable x86 (Needs ``7zip`` and ``/utils/WebviewRuntime/x86/EdgeWebView`` )
|
||||
```cmd
|
||||
node deploy_windows.js --x86 --portable
|
||||
```
|
||||
|
||||
|
||||
> **⏳ Note:** This script uses common path for ``DCMAKE_TOOLCHAIN_FILE`` of vcpkg, make sure the script has the correct one. If running with ``--installer`` make sure u installed ``nsis`` with the needed ``nsprocess`` plugin at least once.
|
||||
|
||||
3. Done. This will build the `installer` and ``dist/win`` folder.
|
||||
|
||||
> **⏳ Note:** This will create `dist/win` with all necessary files like `node.exe`, `ffmpeg.exe`. Also make sure to have `stremio-runtime.exe, server.js` are in `utils\windows\` folder
|
||||
---
|
||||
|
||||
## 📦 Installer (Optional)
|
||||
|
||||
1. Download and install [NSIS](https://nsis.sourceforge.io/Download).
|
||||
Default path: `C:\Program Files (x86)\NSIS`.
|
||||
|
||||
2. Generate the installer:
|
||||
```cmd
|
||||
FOR /F "tokens=4 delims=() " %i IN ('findstr /C:"project(stremio VERSION" CMakeLists.txt') DO @set "package_version=%~i"
|
||||
set arch = "x64";
|
||||
"C:\Program Files (x86)\NSIS\makensis.exe" utils\windows\installer\windows-installer.nsi
|
||||
```
|
||||
- Result: `Stremio %package_version%.exe`.
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Silent Installation
|
||||
|
||||
Run the installer with `/S` (silent mode) and configure via these options:
|
||||
|
||||
- `/notorrentassoc`: Skip `.torrent` association.
|
||||
- `/nodesktopicon`: Skip desktop shortcut.
|
||||
|
||||
Silent uninstall:
|
||||
```cmd
|
||||
"%LOCALAPPDATA%\Programs\LNV\Stremio-5\Uninstall.exe" /S /keepdata
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
✨ **Happy Building!**
|
||||
BIN
images/stremio.ico
Normal file
BIN
images/stremio.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 106 KiB |
BIN
images/stremio.png
Normal file
BIN
images/stremio.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
2721
src/main.cpp
Normal file
2721
src/main.cpp
Normal file
File diff suppressed because it is too large
Load diff
6
src/resource.h
Normal file
6
src/resource.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef RESOURCE_H
|
||||
#define RESOURCE_H
|
||||
|
||||
#define IDR_SPLASH_PNG 101
|
||||
|
||||
#endif
|
||||
7
stremio.rc
Normal file
7
stremio.rc
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#include <windows.h>
|
||||
#include "src/resource.h"
|
||||
|
||||
#define IDR_MAINFRAME 101
|
||||
|
||||
IDR_MAINFRAME ICON "images/stremio.ico"
|
||||
IDR_SPLASH_PNG RCDATA "images/stremio.png"
|
||||
17
utils/chocolatey/stremio.nuspec
Normal file
17
utils/chocolatey/stremio.nuspec
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>stremio-desktop-v5</id>
|
||||
<version>5.0.7</version>
|
||||
<title>Stremio Desktop v5</title>
|
||||
<authors>Zaarrg</authors>
|
||||
<owners>Zaarrg</owners>
|
||||
<projectUrl>https://github.com/Zaarrg/stremio-desktop-v5</projectUrl>
|
||||
<description>Stremio Desktop v5 Community</description>
|
||||
<tags>stremio video streaming media</tags>
|
||||
<licenseUrl>https://github.com/Zaarrg/stremio-desktop-v5/blob/master/LICENSE</licenseUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<dependencies>
|
||||
</dependencies>
|
||||
</metadata>
|
||||
</package>
|
||||
6
utils/chocolatey/tools/chocolateyUninstall.ps1
Normal file
6
utils/chocolatey/tools/chocolateyUninstall.ps1
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
$packageName = 'stremio-desktop-v5'
|
||||
$uninstallPath = "$env:LOCALAPPDATA\Programs\LNV\Stremio-5\Uninstall.exe"
|
||||
|
||||
If (Test-Path $uninstallPath) {
|
||||
Start-Process -FilePath $uninstallPath -ArgumentList '/S' -Wait
|
||||
}
|
||||
16
utils/chocolatey/tools/chocolateyinstall.ps1
Normal file
16
utils/chocolatey/tools/chocolateyinstall.ps1
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
$packageName = 'stremio-desktop-v5'
|
||||
$toolsDir = Split-Path $MyInvocation.MyCommand.Definition
|
||||
$packageArgs = @{
|
||||
packageName = $packageName
|
||||
fileType = 'exe'
|
||||
silentArgs = '/S'
|
||||
validExitCodes= @(0)
|
||||
}
|
||||
|
||||
if ([Environment]::Is64BitOperatingSystem) {
|
||||
$packageArgs['url'] = 'https://github.com/Zaarrg/stremio-desktop-v5/releases/download/5.0.0-beta.7/Stremio.5.0.7-x64.exe'''
|
||||
} else {
|
||||
$packageArgs['url'] = 'https://github.com/Zaarrg/stremio-desktop-v5/releases/download/5.0.0-beta.7/Stremio.5.0.7-x86.exe'''
|
||||
}
|
||||
|
||||
Install-ChocolateyPackage @packageArgs
|
||||
21
utils/mpv/README.md
Normal file
21
utils/mpv/README.md
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
## 🎬 Stremio Ready-to-Go Portable Configs for MPV
|
||||
|
||||
### 🎥 Anime4K
|
||||
- ✅ **No Special Configuration Needed**
|
||||
- 📦 Drag and drop the contents of ``anime4k-High-end.zip`` into the ``portable_config`` folder located at: `%localAppData%\Programs\LNV\Stremio-5\`
|
||||
|
||||
|
||||
|
||||
### 📸 ThumbFast
|
||||
- ✅ **No Special Configuration Needed**
|
||||
- 📦 Drag and drop the contents of ``thumbfast.7z`` into the ``portable_config`` folder located at: ``%localAppData%\Programs\LNV\Stremio-5\``
|
||||
- ⚙️ **Configuration Tip:** If you change the ``max-height`` in ``thumbfast.conf``, ensure you also update it in ``stremio-settings.ini``. Set it to `0` to disable ThumbFast handling.
|
||||
|
||||
|
||||
### 🎨 AnimeJaNai
|
||||
- ✅ **Optimized for Stremio**
|
||||
- 📥 Download the custom build of ``stremio-animejanai`` from the [Releases Tab](https://github.com/Zaarrg/stremio-desktop-v5/releases)
|
||||
- 🛠️ **Changes Made**:
|
||||
- ❌ Removed `mpvnet.exe` since Stremio serves as the player.
|
||||
- 🔧 Adjusted ``mpv.conf`` to work seamlessly with Stremio.
|
||||
- 🔧 Updated ``input.conf`` for compatibility with Stremio.
|
||||
BIN
utils/mpv/anime4k/anime4k-High-end.zip
Normal file
BIN
utils/mpv/anime4k/anime4k-High-end.zip
Normal file
Binary file not shown.
0
utils/mpv/stremio-animejanai/Download from Release Tab
Normal file
0
utils/mpv/stremio-animejanai/Download from Release Tab
Normal file
BIN
utils/mpv/thumbfast/thumbfast.7z
Normal file
BIN
utils/mpv/thumbfast/thumbfast.7z
Normal file
Binary file not shown.
59
utils/scoop/stremio-desktop-v5.json
Normal file
59
utils/scoop/stremio-desktop-v5.json
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
{
|
||||
"version": "5.0.7",
|
||||
"description": "Stremio Desktop v5 Community",
|
||||
"homepage": "https://github.com/Zaarrg/stremio-desktop-v5",
|
||||
"license": "GPL-3.0",
|
||||
"architecture": {
|
||||
"64bit": {
|
||||
"url": "https://github.com/Zaarrg/stremio-desktop-v5/releases/download/5.0.0-beta.7/Stremio.5.0.7-x64.exe",
|
||||
"hash": "a7b71844a12f23272f8a5658fefd0d94bdf9f7e3c9a820e7d1a07436b8927bdb",
|
||||
"installer": {
|
||||
"args": [
|
||||
"/S"
|
||||
]
|
||||
},
|
||||
"uninstaller": {
|
||||
"file": "%LOCALAPPDATA%\\Programs\\LNV\\Stremio-5\\Uninstall.exe",
|
||||
"args": [
|
||||
"/S"
|
||||
]
|
||||
}
|
||||
},
|
||||
"32bit": {
|
||||
"url": "https://github.com/Zaarrg/stremio-desktop-v5/releases/download/5.0.0-beta.7/Stremio.5.0.7-x86.exe",
|
||||
"hash": "65bf17a67c22d67bf602a8023ac94ae63f8a685f32e63d1d28d3a6b0cb0932ef",
|
||||
"installer": {
|
||||
"args": [
|
||||
"/S"
|
||||
]
|
||||
},
|
||||
"uninstaller": {
|
||||
"file": "%LOCALAPPDATA%\\Programs\\LNV\\Stremio-5\\Uninstall.exe",
|
||||
"args": [
|
||||
"/S"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"checkver": {
|
||||
"github": "Zaarrg/stremio-desktop-v5",
|
||||
"regex": "Stremio\\.([\\d.]+)-x64\\.exe"
|
||||
},
|
||||
"autoupdate": {
|
||||
"architecture": {
|
||||
"64bit": {
|
||||
"url": "https://github.com/Zaarrg/stremio-desktop-v5/releases/download/$version/Stremio.$version-x64.exe",
|
||||
"hash": {
|
||||
"url": "$url.sha256"
|
||||
}
|
||||
},
|
||||
"32bit": {
|
||||
"url": "https://github.com/Zaarrg/stremio-desktop-v5/releases/download/$version/Stremio.$version-x86.exe",
|
||||
"hash": {
|
||||
"url": "$url.sha256"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"notes": "Stremio Desktop v5 using silent install via /S. Built-in auto-updater may override Scoop-managed updates."
|
||||
}
|
||||
7
utils/stremio/stremio-settings.ini
Normal file
7
utils/stremio/stremio-settings.ini
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
[General]
|
||||
CloseOnExit=0
|
||||
UseDarkTheme=1
|
||||
ThumbFastHeight=0
|
||||
PauseOnMinimize=1
|
||||
PauseOnLostFocus=0
|
||||
AllowZoom=0
|
||||
BIN
utils/windows/MicrosoftEdgeWebview2Setup.exe
Normal file
BIN
utils/windows/MicrosoftEdgeWebview2Setup.exe
Normal file
Binary file not shown.
28
utils/windows/NsProcess/Include/nsProcess.nsh
Normal file
28
utils/windows/NsProcess/Include/nsProcess.nsh
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
!define nsProcess::FindProcess `!insertmacro nsProcess::FindProcess`
|
||||
|
||||
!macro nsProcess::FindProcess _FILE _ERR
|
||||
nsProcess::_FindProcess /NOUNLOAD `${_FILE}`
|
||||
Pop ${_ERR}
|
||||
!macroend
|
||||
|
||||
|
||||
!define nsProcess::KillProcess `!insertmacro nsProcess::KillProcess`
|
||||
|
||||
!macro nsProcess::KillProcess _FILE _ERR
|
||||
nsProcess::_KillProcess /NOUNLOAD `${_FILE}`
|
||||
Pop ${_ERR}
|
||||
!macroend
|
||||
|
||||
!define nsProcess::CloseProcess `!insertmacro nsProcess::CloseProcess`
|
||||
|
||||
!macro nsProcess::CloseProcess _FILE _ERR
|
||||
nsProcess::_CloseProcess /NOUNLOAD `${_FILE}`
|
||||
Pop ${_ERR}
|
||||
!macroend
|
||||
|
||||
|
||||
!define nsProcess::Unload `!insertmacro nsProcess::Unload`
|
||||
|
||||
!macro nsProcess::Unload
|
||||
nsProcess::_Unload
|
||||
!macroend
|
||||
BIN
utils/windows/NsProcess/Plugin/x86-ansi/nsProcess.dll
Normal file
BIN
utils/windows/NsProcess/Plugin/x86-ansi/nsProcess.dll
Normal file
Binary file not shown.
BIN
utils/windows/NsProcess/Plugin/x86-unicode/nsProcess.dll
Normal file
BIN
utils/windows/NsProcess/Plugin/x86-unicode/nsProcess.dll
Normal file
Binary file not shown.
BIN
utils/windows/ffmpeg/avcodec-58.dll
Normal file
BIN
utils/windows/ffmpeg/avcodec-58.dll
Normal file
Binary file not shown.
BIN
utils/windows/ffmpeg/avdevice-58.dll
Normal file
BIN
utils/windows/ffmpeg/avdevice-58.dll
Normal file
Binary file not shown.
BIN
utils/windows/ffmpeg/avfilter-7.dll
Normal file
BIN
utils/windows/ffmpeg/avfilter-7.dll
Normal file
Binary file not shown.
BIN
utils/windows/ffmpeg/avformat-58.dll
Normal file
BIN
utils/windows/ffmpeg/avformat-58.dll
Normal file
Binary file not shown.
BIN
utils/windows/ffmpeg/avutil-56.dll
Normal file
BIN
utils/windows/ffmpeg/avutil-56.dll
Normal file
Binary file not shown.
BIN
utils/windows/ffmpeg/ffmpeg.exe
Normal file
BIN
utils/windows/ffmpeg/ffmpeg.exe
Normal file
Binary file not shown.
BIN
utils/windows/ffmpeg/ffprobe.exe
Normal file
BIN
utils/windows/ffmpeg/ffprobe.exe
Normal file
Binary file not shown.
BIN
utils/windows/ffmpeg/postproc-55.dll
Normal file
BIN
utils/windows/ffmpeg/postproc-55.dll
Normal file
Binary file not shown.
BIN
utils/windows/ffmpeg/swresample-3.dll
Normal file
BIN
utils/windows/ffmpeg/swresample-3.dll
Normal file
Binary file not shown.
BIN
utils/windows/ffmpeg/swscale-5.dll
Normal file
BIN
utils/windows/ffmpeg/swscale-5.dll
Normal file
Binary file not shown.
119
utils/windows/installer/fileassoc.nsh
Normal file
119
utils/windows/installer/fileassoc.nsh
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
; fileassoc.nsh
|
||||
; File association helper macros
|
||||
; Written by Saivert
|
||||
;
|
||||
; Features automatic backup system and UPDATEFILEASSOC macro for
|
||||
; shell change notification.
|
||||
;
|
||||
; |> How to use <|
|
||||
; To associate a file with an application so you can double-click it in explorer, use
|
||||
; the APP_ASSOCIATE macro like this:
|
||||
;
|
||||
; Example:
|
||||
; !insertmacro APP_ASSOCIATE "txt" "myapp.textfile" "Description of txt files" \
|
||||
; "$INSTDIR\myapp.exe,0" "Open with myapp" "$INSTDIR\myapp.exe $\"%1$\""
|
||||
;
|
||||
; Never insert the APP_ASSOCIATE macro multiple times, it is only ment
|
||||
; to associate an application with a single file and using the
|
||||
; the "open" verb as default. To add more verbs (actions) to a file
|
||||
; use the APP_ASSOCIATE_ADDVERB macro.
|
||||
;
|
||||
; Example:
|
||||
; !insertmacro APP_ASSOCIATE_ADDVERB "myapp.textfile" "edit" "Edit with myapp" \
|
||||
; "$INSTDIR\myapp.exe /edit $\"%1$\""
|
||||
;
|
||||
; To have access to more options when registering the file association use the
|
||||
; APP_ASSOCIATE_EX macro. Here you can specify the verb and what verb is to be the
|
||||
; standard action (default verb).
|
||||
;
|
||||
; And finally: To remove the association from the registry use the APP_UNASSOCIATE
|
||||
; macro. Here is another example just to wrap it up:
|
||||
; !insertmacro APP_UNASSOCIATE "txt" "myapp.textfile"
|
||||
;
|
||||
; |> Note <|
|
||||
; When defining your file class string always use the short form of your application title
|
||||
; then a period (dot) and the type of file. This keeps the file class sort of unique.
|
||||
; Examples:
|
||||
; Winamp.Playlist
|
||||
; NSIS.Script
|
||||
; Photoshop.JPEGFile
|
||||
;
|
||||
; |> Tech info <|
|
||||
; The registry key layout for a file association is:
|
||||
; HKEY_CLASSES_ROOT
|
||||
; <applicationID> = <"description">
|
||||
; shell
|
||||
; <verb> = <"menu-item text">
|
||||
; command = <"command string">
|
||||
;
|
||||
|
||||
!macro APP_ASSOCIATE EXT FILECLASS DESCRIPTION ICON COMMANDTEXT COMMAND
|
||||
; Backup the previously associated file class
|
||||
ReadRegStr $R0 HKCU "Software\Classes\.${EXT}" ""
|
||||
WriteRegStr HKCU "Software\Classes\.${EXT}" "${FILECLASS}_backup" "$R0"
|
||||
|
||||
WriteRegStr HKCU "Software\Classes\.${EXT}" "" "${FILECLASS}"
|
||||
|
||||
WriteRegStr HKCU "Software\Classes\${FILECLASS}" "" `${DESCRIPTION}`
|
||||
WriteRegStr HKCU "Software\Classes\${FILECLASS}\DefaultIcon" "" `${ICON}`
|
||||
WriteRegStr HKCU "Software\Classes\${FILECLASS}\shell" "" "open"
|
||||
WriteRegStr HKCU "Software\Classes\${FILECLASS}\shell\open" "" `${COMMANDTEXT}`
|
||||
WriteRegStr HKCU "Software\Classes\${FILECLASS}\shell\open\command" "" `${COMMAND}`
|
||||
!macroend
|
||||
|
||||
!macro APP_ASSOCIATE_EX EXT FILECLASS DESCRIPTION ICON VERB DEFAULTVERB SHELLNEW COMMANDTEXT COMMAND
|
||||
; Backup the previously associated file class
|
||||
ReadRegStr $R0 HKCU "Software\Classes\.${EXT}" ""
|
||||
WriteRegStr HKCU "Software\Classes\.${EXT}" "${FILECLASS}_backup" "$R0"
|
||||
|
||||
WriteRegStr HKCU "Software\Classes\.${EXT}" "" "${FILECLASS}"
|
||||
StrCmp "${SHELLNEW}" "0" +2
|
||||
WriteRegStr HKCU "Software\Classes\.${EXT}\ShellNew" "NullFile" ""
|
||||
|
||||
WriteRegStr HKCU "Software\Classes\${FILECLASS}" "" `${DESCRIPTION}`
|
||||
WriteRegStr HKCU "Software\Classes\${FILECLASS}\DefaultIcon" "" `${ICON}`
|
||||
WriteRegStr HKCU "Software\Classes\${FILECLASS}\shell" "" `${DEFAULTVERB}`
|
||||
WriteRegStr HKCU "Software\Classes\${FILECLASS}\shell\${VERB}" "" `${COMMANDTEXT}`
|
||||
WriteRegStr HKCU "Software\Classes\${FILECLASS}\shell\${VERB}\command" "" `${COMMAND}`
|
||||
!macroend
|
||||
|
||||
!macro APP_ASSOCIATE_ADDVERB FILECLASS VERB COMMANDTEXT COMMAND
|
||||
WriteRegStr HKCU "Software\Classes\${FILECLASS}\shell\${VERB}" "" `${COMMANDTEXT}`
|
||||
WriteRegStr HKCU "Software\Classes\${FILECLASS}\shell\${VERB}\command" "" `${COMMAND}`
|
||||
!macroend
|
||||
|
||||
!macro APP_ASSOCIATE_REMOVEVERB FILECLASS VERB
|
||||
DeleteRegKey HKCU `Software\Classes\${FILECLASS}\shell\${VERB}`
|
||||
!macroend
|
||||
|
||||
|
||||
!macro APP_UNASSOCIATE EXT FILECLASS
|
||||
; Backup the previously associated file class
|
||||
ReadRegStr $R0 HKCU "Software\Classes\.${EXT}" `${FILECLASS}_backup`
|
||||
WriteRegStr HKCU "Software\Classes\.${EXT}" "" "$R0"
|
||||
|
||||
DeleteRegKey HKCU `Software\Classes\${FILECLASS}`
|
||||
!macroend
|
||||
|
||||
!macro APP_ASSOCIATE_GETFILECLASS OUTPUT EXT
|
||||
ReadRegStr ${OUTPUT} HKCU ".${EXT}" ""
|
||||
!macroend
|
||||
|
||||
|
||||
; !defines for use with SHChangeNotify
|
||||
!ifdef SHCNE_ASSOCCHANGED
|
||||
!undef SHCNE_ASSOCCHANGED
|
||||
!endif
|
||||
!define SHCNE_ASSOCCHANGED 0x08000000
|
||||
!ifdef SHCNF_FLUSH
|
||||
!undef SHCNF_FLUSH
|
||||
!endif
|
||||
!define SHCNF_FLUSH 0x1000
|
||||
|
||||
!macro UPDATEFILEASSOC
|
||||
; Using the system.dll plugin to call the SHChangeNotify Win32 API function so we
|
||||
; can update the shell.
|
||||
System::Call "shell32::SHChangeNotify(i,i,i,i) (${SHCNE_ASSOCCHANGED}, ${SHCNF_FLUSH}, 0, 0)"
|
||||
!macroend
|
||||
|
||||
;EOF
|
||||
BIN
utils/windows/installer/windows-installer-header.bmp
Normal file
BIN
utils/windows/installer/windows-installer-header.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
BIN
utils/windows/installer/windows-installer.bmp
Normal file
BIN
utils/windows/installer/windows-installer.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 201 KiB |
611
utils/windows/installer/windows-installer.nsi
Normal file
611
utils/windows/installer/windows-installer.nsi
Normal file
|
|
@ -0,0 +1,611 @@
|
|||
|
||||
;Stremio
|
||||
;Installer Source for NSIS 3.0 or higher
|
||||
|
||||
Unicode True
|
||||
|
||||
#Tells the compiler whether or not to do datablock optimizations.
|
||||
SetDatablockOptimize on
|
||||
|
||||
;Include Modern UI
|
||||
!include "MUI2.nsh"
|
||||
!include "FileFunc.nsh"
|
||||
!include "fileassoc.nsh"
|
||||
!include "nsProcess.nsh"
|
||||
!include "LogicLib.nsh"
|
||||
!include "x64.nsh"
|
||||
|
||||
;Parse package.json
|
||||
|
||||
!define APP_NAME "Stremio"
|
||||
!define PRODUCT_VERSION "$%package_version%"
|
||||
!define ARCH "$%arch%"
|
||||
!searchparse "${PRODUCT_VERSION}" `` VERSION_MAJOR `.` VERSION_MINOR `.` VERSION_REVISION
|
||||
!define APP_URL "https://www.stremio.com"
|
||||
!define DATA_FOLDER "stremio"
|
||||
|
||||
!define COMPANY_NAME "Smart Code Ltd"
|
||||
|
||||
|
||||
; ------------------- ;
|
||||
; Settings ;
|
||||
; ------------------- ;
|
||||
;General Settings
|
||||
Name "${APP_NAME}"
|
||||
Caption "${APP_NAME} ${PRODUCT_VERSION} - Installer"
|
||||
BrandingText "${APP_NAME} ${PRODUCT_VERSION}"
|
||||
VIAddVersionKey "ProductName" "${APP_NAME}"
|
||||
VIAddVersionKey "ProductVersion" "${PRODUCT_VERSION}"
|
||||
VIAddVersionKey "FileDescription" "${APP_NAME} ${PRODUCT_VERSION} Installer"
|
||||
VIAddVersionKey "FileVersion" "${PRODUCT_VERSION}"
|
||||
VIAddVersionKey "CompanyName" "${COMPANY_NAME}"
|
||||
VIAddVersionKey "LegalCopyright" "${APP_URL}"
|
||||
VIProductVersion "${PRODUCT_VERSION}.0"
|
||||
OutFile "../../${APP_NAME} ${PRODUCT_VERSION}-${ARCH}.exe"
|
||||
ShowInstDetails "nevershow"
|
||||
ShowUninstDetails "nevershow"
|
||||
CRCCheck on
|
||||
;SetCompressor /SOLID lzma
|
||||
;SetCompressorDictSize 4
|
||||
;SetCompressor lzma
|
||||
;SetCompressorDictSize 1
|
||||
SetCompressor /SOLID lzma
|
||||
SetCompressorDictSize 128
|
||||
|
||||
;Default installation folder
|
||||
InstallDir "$LOCALAPPDATA\Programs\LNV\${APP_NAME}-${VERSION_MAJOR}"
|
||||
InstallDirRegKey HKLM Software\SmartCode\Stremio InstallLocation
|
||||
|
||||
;Request application privileges
|
||||
;RequestExecutionLevel highest
|
||||
RequestExecutionLevel user
|
||||
;RequestExecutionLevel admin
|
||||
|
||||
!define APP_LAUNCHER "Stremio.exe"
|
||||
!define UNINSTALL_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}"
|
||||
|
||||
; ------------------- ;
|
||||
; UI Settings ;
|
||||
; ------------------- ;
|
||||
;Define UI settings
|
||||
|
||||
;!define MUI_UI_HEADERIMAGE_RIGHT "../../../images/icon.png"
|
||||
!define MUI_ICON "../../../images/stremio.ico"
|
||||
!define MUI_UNICON "../../../images/stremio.ico"
|
||||
|
||||
; WARNING; these bmps have to be generated in BMP3 - convert SMTH BMP3:SMTH.bmp
|
||||
!define MUI_WELCOMEFINISHPAGE_BITMAP "windows-installer.bmp"
|
||||
!define MUI_UNWELCOMEFINISHPAGE_BITMAP "windows-installer.bmp"
|
||||
!define MUI_ABORTWARNING
|
||||
!define MUI_FINISHPAGE_LINK "www.stremio.com"
|
||||
!define MUI_FINISHPAGE_LINK_LOCATION "${APP_URL}"
|
||||
!define MUI_FINISHPAGE_RUN "$INSTDIR\stremio.exe"
|
||||
|
||||
; Hack...
|
||||
!define MUI_FINISHPAGE_SHOWREADME ""
|
||||
;!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED
|
||||
!define MUI_FINISHPAGE_SHOWREADME_TEXT "$(desktopShortcut)"
|
||||
!define MUI_FINISHPAGE_SHOWREADME_FUNCTION finishpageaction
|
||||
!define MUI_FINISHPAGE_TITLE "Completing the ${APP_NAME} Setup"
|
||||
|
||||
; Define header image
|
||||
!define MUI_HEADERIMAGE
|
||||
!define MUI_HEADERIMAGE_BITMAP "windows-installer-header.bmp"
|
||||
!define MUI_HEADERIMAGE_BITMAP_NOSTRETCH
|
||||
!define MUI_HEADER_TRANSPARENT_TEXT
|
||||
; also consider MUI_WELCOMEFINISHPAGE_BITMAP
|
||||
|
||||
; Beautiful progress bar
|
||||
XPStyle off
|
||||
!define MUI_INSTALLCOLORS "000000 643F9E"
|
||||
!define MUI_INSTFILESPAGE_PROGRESSBAR colored
|
||||
|
||||
|
||||
# Include Sections header so that we can manipulate section properties in .onInit
|
||||
!include "Sections.nsh"
|
||||
|
||||
;ReserveFile /plugin InstallOptions.dll
|
||||
|
||||
; Pages
|
||||
;!insertmacro MUI_PAGE_WELCOME
|
||||
; !insertmacro MUI_PAGE_LICENSE "LICENSE.txt"
|
||||
;!insertmacro MUI_PAGE_DIRECTORY
|
||||
|
||||
# Perform installation (executes each enabled Section)
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
!define MUI_PAGE_CUSTOMFUNCTION_SHOW fin_pg_options
|
||||
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE fin_pg_leave
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
|
||||
; Uninstall pages
|
||||
!insertmacro MUI_UNPAGE_WELCOME
|
||||
!insertmacro MUI_UNPAGE_INSTFILES
|
||||
!insertmacro MUI_UNPAGE_FINISH
|
||||
|
||||
; Load Language Files
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
|
||||
; Progress bar - part 2
|
||||
!define MUI_PAGE_CUSTOMFUNCTION_SHOW InstShow
|
||||
|
||||
; ------------------- ;
|
||||
; Localization ;
|
||||
; ------------------- ;
|
||||
LangString removeDataFolder ${LANG_ENGLISH} "Remove all data and configuration?"
|
||||
LangString noRoot ${LANG_ENGLISH} "You cannot install Stremio in a directory that requires administrator permissions"
|
||||
LangString desktopShortcut ${LANG_ENGLISH} "Desktop Shortcut"
|
||||
LangString appIsRunning ${LANG_ENGLISH} "${APP_NAME} is running. Do you want to close it?"
|
||||
LangString appIsRunningInstallError ${LANG_ENGLISH} "${APP_NAME} cannot be installed while another instance is running."
|
||||
LangString appIsRunningUninstallError ${LANG_ENGLISH} "${APP_NAME} cannot be uninstalled while another instance is running."
|
||||
|
||||
Var Parameters
|
||||
|
||||
# Finish page custom options
|
||||
Var AssociateMagnetCheckbox
|
||||
Var AssociateMediaCheckbox
|
||||
Var AssociateTorrentCheckbox
|
||||
Var checkbox_value
|
||||
|
||||
Function fin_pg_options
|
||||
${NSD_CreateCheckbox} 180 -100 100% 8u "Associate ${APP_NAME} with .torrent files"
|
||||
Pop $AssociateTorrentCheckbox
|
||||
SetCtlColors $AssociateTorrentCheckbox '0xFF0000' '0xFFFFFF'
|
||||
${NSD_Check} $AssociateTorrentCheckbox
|
||||
|
||||
${NSD_CreateCheckbox} 180 -80 100% 8u "Associate ${APP_NAME} with magnet links"
|
||||
Pop $AssociateMagnetCheckbox
|
||||
SetCtlColors $AssociateMagnetCheckbox '0xFF0000' '0xFFFFFF'
|
||||
${NSD_Check} $AssociateMagnetCheckbox
|
||||
|
||||
${NSD_CreateCheckbox} 180 -60 100% 8u "Associate ${APP_NAME} as media player"
|
||||
Pop $AssociateMediaCheckbox
|
||||
SetCtlColors $AssociateMediaCheckbox '0xFF0000' '0xFFFFFF'
|
||||
${NSD_Check} $AssociateMediaCheckbox
|
||||
FunctionEnd
|
||||
|
||||
Function fin_pg_leave
|
||||
${NSD_GetState} $AssociateTorrentCheckbox $checkbox_value
|
||||
${If} $checkbox_value == ${BST_CHECKED}
|
||||
!insertmacro APP_ASSOCIATE "torrent" "stremio" "BitTorrent file" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
${EndIf}
|
||||
|
||||
; Set friendly name for Stremio in "Open With" menu
|
||||
WriteRegStr HKCU "Software\Classes\stremio" "FriendlyTypeName" "${APP_NAME}"
|
||||
WriteRegStr HKCU "Software\Classes\stremio\shell\open" "FriendlyAppName" "${APP_NAME}"
|
||||
|
||||
|
||||
|
||||
${NSD_GetState} $AssociateMagnetCheckbox $checkbox_value
|
||||
${If} $checkbox_value == ${BST_CHECKED}
|
||||
WriteRegStr HKCU "Software\Classes\magnet" "" "Magnet Protocol"
|
||||
WriteRegStr HKCU "Software\Classes\magnet" "URL Protocol" ""
|
||||
WriteRegStr HKCU "Software\Classes\magnet\DefaultIcon" "" "$INSTDIR\stremio.exe,0"
|
||||
WriteRegStr HKCU "Software\Classes\magnet\shell\open\command" "" '"$INSTDIR\stremio.exe" "%1"'
|
||||
${EndIf}
|
||||
|
||||
${NSD_GetState} $AssociateMediaCheckbox $checkbox_value
|
||||
|
||||
!macro APP_ASSOCIATE_EXTENSIONS
|
||||
; Define the list of extensions
|
||||
Var /GLOBAL FileExtensions
|
||||
StrCpy $FileExtensions "mp4 mkv avi mov wmv flv webm mpg mpeg 3gp m4v ts vob f4v m2ts asf divx ogv rm rmvb"
|
||||
|
||||
; Start of the loop
|
||||
Var /GLOBAL CurrentExtension
|
||||
LoopStart:
|
||||
; Extract the first extension from the list
|
||||
StrCpy $CurrentExtension $FileExtensions 4 ; Copy up to the first space
|
||||
StrCpy $FileExtensions $FileExtensions 4 - ; Remove the extracted extension from the list
|
||||
${If} $CurrentExtension != ""
|
||||
; Associate the current extension
|
||||
!insertmacro APP_ASSOCIATE "$CurrentExtension" "stremio" "Media File" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
; Continue the loop
|
||||
Goto LoopStart
|
||||
${EndIf}
|
||||
; End of the loop
|
||||
${EndIf}
|
||||
!macroend
|
||||
${If} $checkbox_value == ${BST_CHECKED}
|
||||
!insertmacro APP_ASSOCIATE "mp4" "stremio" "Media File" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
!insertmacro APP_ASSOCIATE "mkv" "stremio" "Media File" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
!insertmacro APP_ASSOCIATE "avi" "stremio" "Media File" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
!insertmacro APP_ASSOCIATE "mov" "stremio" "Media File" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
!insertmacro APP_ASSOCIATE "wmv" "stremio" "Media File" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
!insertmacro APP_ASSOCIATE "flv" "stremio" "Media File" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
!insertmacro APP_ASSOCIATE "webm" "stremio" "Media File" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
!insertmacro APP_ASSOCIATE "mpg" "stremio" "Media File" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
!insertmacro APP_ASSOCIATE "mpeg" "stremio" "Media File" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
!insertmacro APP_ASSOCIATE "3gp" "stremio" "Media File" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
!insertmacro APP_ASSOCIATE "m4v" "stremio" "Media File" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
!insertmacro APP_ASSOCIATE "ts" "stremio" "Media File" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
!insertmacro APP_ASSOCIATE "vob" "stremio" "Media File" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
!insertmacro APP_ASSOCIATE "f4v" "stremio" "Media File" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
!insertmacro APP_ASSOCIATE "m2ts" "stremio" "Media File" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
!insertmacro APP_ASSOCIATE "asf" "stremio" "Media File" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
!insertmacro APP_ASSOCIATE "divx" "stremio" "Media File" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
!insertmacro APP_ASSOCIATE "ogv" "stremio" "Media File" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
!insertmacro APP_ASSOCIATE "rm" "stremio" "Media File" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
!insertmacro APP_ASSOCIATE "rmvb" "stremio" "Media File" "$INSTDIR\stremio.exe,0" "Play with Stremio" "$INSTDIR\stremio.exe $\"%1$\""
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
|
||||
|
||||
; ---------------------------------------------------
|
||||
; Removes everything from $INSTDIR except the
|
||||
; "stremio.exe.WebView2" folder.
|
||||
; ---------------------------------------------------
|
||||
!macro RemoveAllExceptWebView2 un
|
||||
Function ${un}RemoveAllExceptWebView2
|
||||
; Hardcoded values for your scenario
|
||||
StrCpy $R0 "stremio.exe.WebView2" ; Directory to exclude
|
||||
StrCpy $R1 "$INSTDIR" ; Root directory to operate on
|
||||
|
||||
Push $R2
|
||||
Push $R3
|
||||
Push $R4
|
||||
|
||||
ClearErrors
|
||||
FindFirst $R3 $R2 "$R1\*.*"
|
||||
IfErrors Exit
|
||||
|
||||
Top:
|
||||
; Skip special directories "." and ".."
|
||||
StrCmp $R2 "." Next
|
||||
StrCmp $R2 ".." Next
|
||||
; Skip the excluded directory
|
||||
StrCmp $R2 $R0 Next
|
||||
|
||||
; Build full path for the current item
|
||||
StrCpy $R4 "$R1\$R2"
|
||||
|
||||
; Check if the current item is a directory
|
||||
IfFileExists "$R4\*.*" isDir notDir
|
||||
|
||||
notDir:
|
||||
; It's a file, so delete it
|
||||
Delete "$R4"
|
||||
Goto Next
|
||||
|
||||
isDir:
|
||||
; It's a directory, remove it recursively
|
||||
RMDir /r "$R4"
|
||||
Next:
|
||||
ClearErrors
|
||||
FindNext $R3 $R2
|
||||
IfErrors Exit
|
||||
Goto Top
|
||||
|
||||
Exit:
|
||||
FindClose $R3
|
||||
|
||||
Pop $R4
|
||||
Pop $R3
|
||||
Pop $R2
|
||||
FunctionEnd
|
||||
!macroend
|
||||
|
||||
!insertmacro RemoveAllExceptWebView2 ""
|
||||
!insertmacro RemoveAllExceptWebView2 "un."
|
||||
|
||||
!macro checkIfAppIsRunning AppIsRunningErrorMsg
|
||||
; Check if stremio.exe is running
|
||||
${nsProcess::FindProcess} ${APP_LAUNCHER} $R0
|
||||
|
||||
${If} $R0 == 0
|
||||
IfSilent killapp
|
||||
MessageBox MB_YESNO|MB_ICONQUESTION "$(appIsRunning)" IDYES killapp
|
||||
; Check if stremio.exe is still running.
|
||||
; No need to abort if the user manually closes Stremio and answer NO on the prompt
|
||||
${nsProcess::FindProcess} ${APP_LAUNCHER} $R0
|
||||
${If} $R0 == 0
|
||||
; Hide the progress bar
|
||||
FindWindow $0 "#32770" "" $HWNDPARENT
|
||||
GetDlgItem $1 $0 0x3ec
|
||||
ShowWindow $1 ${SW_HIDE}
|
||||
; Abort install
|
||||
Abort "${AppIsRunningErrorMsg}"
|
||||
${EndIf}
|
||||
killapp:
|
||||
${nsProcess::CloseProcess} "${APP_LAUNCHER}" $R0
|
||||
Sleep 2000
|
||||
${EndIf}
|
||||
|
||||
${nsProcess::Unload}
|
||||
!macroend
|
||||
|
||||
; ------------------- ;
|
||||
; WebView Check ;
|
||||
; ------------------- ;
|
||||
|
||||
Function CheckWebView2
|
||||
ClearErrors
|
||||
StrCpy $0 ""
|
||||
|
||||
${If} ${RunningX64}
|
||||
ReadRegStr $0 HKLM "SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv"
|
||||
${If} $0 == ""
|
||||
ReadRegStr $0 HKCU "Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv"
|
||||
${EndIf}
|
||||
${Else}
|
||||
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv"
|
||||
${If} $0 == ""
|
||||
ReadRegStr $0 HKCU "Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv"
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
|
||||
StrCmp $0 "" NotInstalled 0
|
||||
StrCmp $0 "0.0.0.0" NotInstalled 0
|
||||
Goto WebViewPresent
|
||||
|
||||
NotInstalled:
|
||||
; Switch details printing to text-only mode to display custom messages
|
||||
SetDetailsPrint textonly
|
||||
DetailPrint "WebView2 Runtime not found. Extracting setup..."
|
||||
|
||||
; Extract MicrosoftEdgeWebview2Setup.exe only when needed
|
||||
File "/oname=$PLUGINSDIR\MicrosoftEdgeWebview2Setup.exe" "..\MicrosoftEdgeWebview2Setup.exe"
|
||||
DetailPrint "Extracted WebView2 setup to $PLUGINSDIR."
|
||||
|
||||
DetailPrint "Installing WebView2 Runtime..."
|
||||
SetDetailsPrint none
|
||||
ExecWait '"$PLUGINSDIR\MicrosoftEdgeWebview2Setup.exe" /silent /install' $R0
|
||||
SetDetailsPrint textonly
|
||||
|
||||
${If} $R0 != 0
|
||||
DetailPrint "Failed to install WebView2 Runtime. Error code: $R0."
|
||||
MessageBox MB_OK|MB_ICONEXCLAMATION "Error installing WebView2 Runtime (error code: $R0)."
|
||||
${EndIf}
|
||||
|
||||
DetailPrint "Finished installing WebView2 Continuing installation..."
|
||||
; Restore previous details printing mode (last used setting)
|
||||
SetDetailsPrint lastused
|
||||
|
||||
WebViewPresent:
|
||||
FunctionEnd
|
||||
|
||||
|
||||
; ------------------- ;
|
||||
; Install code ;
|
||||
; ------------------- ;
|
||||
Function .onInit ; check for previous version
|
||||
ReadRegStr $0 HKCU "${UNINSTALL_KEY}" "InstallString"
|
||||
StrCmp $0 "" done
|
||||
StrCpy $INSTDIR $0
|
||||
|
||||
${GetParameters} $Parameters
|
||||
ClearErrors
|
||||
${GetOptions} $Parameters "/addon" $R1
|
||||
|
||||
FileOpen $0 "$INSTDIR\addons.txt" w
|
||||
FileWrite $0 "$R1"
|
||||
FileClose $0
|
||||
done:
|
||||
FunctionEnd
|
||||
|
||||
Section ; App Files
|
||||
!insertmacro checkIfAppIsRunning "$(appIsRunningInstallError)"
|
||||
|
||||
; Check and install WebView2 before proceeding
|
||||
Call CheckWebView2
|
||||
|
||||
; Hide details
|
||||
SetDetailsPrint None
|
||||
Call RemoveAllExceptWebView2
|
||||
|
||||
;Set output path to InstallDir
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
;Add the files
|
||||
File /r "..\..\..\dist\win-${ARCH}\*"
|
||||
|
||||
;Create uninstaller
|
||||
WriteUninstaller "$INSTDIR\Uninstall.exe"
|
||||
|
||||
SectionEnd
|
||||
|
||||
; ------------------- ;
|
||||
; Shortcuts ;
|
||||
; ------------------- ;
|
||||
Section ; Shortcuts
|
||||
; Hide details
|
||||
SetDetailsPrint none
|
||||
|
||||
;Working Directory
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
;Start Menu Shortcut
|
||||
RMDir /r "$SMPROGRAMS\${APP_NAME}"
|
||||
CreateDirectory "$SMPROGRAMS\${APP_NAME}"
|
||||
CreateShortCut "$SMPROGRAMS\${APP_NAME}\${APP_NAME}.lnk" "$INSTDIR\stremio.exe" "" "$INSTDIR\stremio.exe" "" "" "" "${APP_NAME} ${PRODUCT_VERSION}"
|
||||
CreateShortCut "$SMPROGRAMS\${APP_NAME}\Uninstall ${APP_NAME}.lnk" "$INSTDIR\Uninstall.exe" "" "$INSTDIR\stremio.exe" "" "" "" "Uninstall ${APP_NAME}"
|
||||
|
||||
;Desktop Shortcut
|
||||
Delete "$DESKTOP\${APP_NAME}.lnk"
|
||||
|
||||
;Add/remove programs uninstall entry
|
||||
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
|
||||
IntFmt $0 "0x%08X" $0
|
||||
WriteRegDWORD HKCU "${UNINSTALL_KEY}" "EstimatedSize" "$0"
|
||||
WriteRegStr HKCU "${UNINSTALL_KEY}" "DisplayName" "${APP_NAME}"
|
||||
WriteRegStr HKCU "${UNINSTALL_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
|
||||
WriteRegStr HKCU "${UNINSTALL_KEY}" "DisplayIcon" "$INSTDIR\stremio.exe"
|
||||
WriteRegStr HKCU "${UNINSTALL_KEY}" "Publisher" "${COMPANY_NAME}"
|
||||
WriteRegStr HKCU "${UNINSTALL_KEY}" "UninstallString" "$INSTDIR\Uninstall.exe"
|
||||
WriteRegStr HKCU "${UNINSTALL_KEY}" "InstallString" "$INSTDIR"
|
||||
WriteRegStr HKCU "${UNINSTALL_KEY}" "URLInfoAbout" "${APP_URL}"
|
||||
WriteRegStr HKCU "${UNINSTALL_KEY}" "NoModify" 1
|
||||
WriteRegStr HKCU "${UNINSTALL_KEY}" "NoRepair" 1
|
||||
|
||||
; Register stremio:// protocol handler
|
||||
WriteRegStr HKCU "Software\Classes\stremio" "" "URL:Stremio Protocol"
|
||||
WriteRegStr HKCU "Software\Classes\stremio" "URL Protocol" ""
|
||||
WriteRegStr HKCU "Software\Classes\stremio\DefaultIcon" "" "$INSTDIR\stremio.exe,1"
|
||||
WriteRegStr HKCU "Software\Classes\stremio\shell" "" "open"
|
||||
WriteRegStr HKCU "Software\Classes\stremio\shell\open\command" "" '"$INSTDIR\stremio.exe" "%1"'
|
||||
|
||||
IfSilent 0 end
|
||||
Call fin_pg_leave
|
||||
${GetOptions} $Parameters /nodesktopicon $R1
|
||||
IfErrors 0 end
|
||||
Call finishpageaction
|
||||
end:
|
||||
SectionEnd
|
||||
|
||||
; ------------------- ;
|
||||
; Uninstaller ;
|
||||
; ------------------- ;
|
||||
; ------------------- ;
|
||||
; Uninstaller ;
|
||||
; ------------------- ;
|
||||
Section "uninstall"
|
||||
|
||||
; Macro to check if application is running
|
||||
!insertmacro checkIfAppIsRunning "$(appIsRunningUninstallError)"
|
||||
|
||||
SetDetailsPrint none
|
||||
|
||||
; Remove shortcuts
|
||||
RMDir /r "$SMPROGRAMS\${APP_NAME}"
|
||||
Delete "$DESKTOP\${APP_NAME}.lnk"
|
||||
|
||||
; Remove registry entries
|
||||
DeleteRegKey HKCU "${UNINSTALL_KEY}"
|
||||
DeleteRegKey HKCU Software\Classes\stremio
|
||||
DeleteRegKey HKCU Software\Classes\magnet
|
||||
|
||||
; Remove friendly name registry entry
|
||||
DeleteRegKey HKCR Applications\stremio.exe
|
||||
|
||||
!insertmacro APP_UNASSOCIATE "torrent" "stremio"
|
||||
!insertmacro APP_UNASSOCIATE "mp4" "stremio"
|
||||
!insertmacro APP_UNASSOCIATE "mkv" "stremio"
|
||||
!insertmacro APP_UNASSOCIATE "avi" "stremio"
|
||||
!insertmacro APP_UNASSOCIATE "mov" "stremio"
|
||||
!insertmacro APP_UNASSOCIATE "wmv" "stremio"
|
||||
!insertmacro APP_UNASSOCIATE "flv" "stremio"
|
||||
!insertmacro APP_UNASSOCIATE "webm" "stremio"
|
||||
!insertmacro APP_UNASSOCIATE "mpg" "stremio"
|
||||
!insertmacro APP_UNASSOCIATE "mpeg" "stremio"
|
||||
!insertmacro APP_UNASSOCIATE "3gp" "stremio"
|
||||
!insertmacro APP_UNASSOCIATE "m4v" "stremio"
|
||||
!insertmacro APP_UNASSOCIATE "ts" "stremio"
|
||||
!insertmacro APP_UNASSOCIATE "vob" "stremio"
|
||||
!insertmacro APP_UNASSOCIATE "f4v" "stremio"
|
||||
!insertmacro APP_UNASSOCIATE "m2ts" "stremio"
|
||||
!insertmacro APP_UNASSOCIATE "asf" "stremio"
|
||||
!insertmacro APP_UNASSOCIATE "divx" "stremio"
|
||||
!insertmacro APP_UNASSOCIATE "ogv" "stremio"
|
||||
!insertmacro APP_UNASSOCIATE "rm" "stremio"
|
||||
!insertmacro APP_UNASSOCIATE "rmvb" "stremio"
|
||||
|
||||
|
||||
; Prompt user to see if they want to remove data
|
||||
IfSilent +3
|
||||
MessageBox MB_YESNO|MB_ICONQUESTION "$(removeDataFolder)" IDNO keepUserData
|
||||
Goto removeData
|
||||
${GetParameters} $Parameters
|
||||
ClearErrors
|
||||
${GetOptions} $Parameters "/keepdata" $R1
|
||||
IfErrors 0 keepUserData
|
||||
|
||||
removeData:
|
||||
; User chose to remove data - remove entire install folder (including .WebView2)
|
||||
RMDir /r "$INSTDIR"
|
||||
Goto done
|
||||
|
||||
keepUserData:
|
||||
; User chose to keep data - remove all but the WebView2 folder
|
||||
Call un.RemoveAllExceptWebView2
|
||||
|
||||
done:
|
||||
; Optionally open a farewell page
|
||||
IfSilent +2
|
||||
ExecShell "open" "https://github.com/Zaarrg/stremio-desktop-v5/blob/master/docs/GOODBYE.md"
|
||||
|
||||
SectionEnd
|
||||
|
||||
; ------------------- ;
|
||||
; Check if writable ;
|
||||
; ------------------- ;
|
||||
Function IsWritable
|
||||
|
||||
!define IsWritable `!insertmacro IsWritableCall`
|
||||
|
||||
!macro IsWritableCall _PATH _RESULT
|
||||
Push `${_PATH}`
|
||||
Call IsWritable
|
||||
Pop ${_RESULT}
|
||||
!macroend
|
||||
|
||||
Exch $R0
|
||||
Push $R1
|
||||
|
||||
start:
|
||||
StrLen $R1 $R0
|
||||
StrCmp $R1 0 exit
|
||||
${GetFileAttributes} $R0 "DIRECTORY" $R1
|
||||
StrCmp $R1 1 direxists
|
||||
${GetParent} $R0 $R0
|
||||
Goto start
|
||||
|
||||
direxists:
|
||||
${GetFileAttributes} $R0 "DIRECTORY" $R1
|
||||
StrCmp $R1 0 ok
|
||||
|
||||
StrCmp $R0 $PROGRAMFILES64 notok
|
||||
StrCmp $R0 $WINDIR notok
|
||||
|
||||
${GetFileAttributes} $R0 "READONLY" $R1
|
||||
|
||||
Goto exit
|
||||
|
||||
notok:
|
||||
StrCpy $R1 1
|
||||
Goto exit
|
||||
|
||||
ok:
|
||||
StrCpy $R1 0
|
||||
|
||||
exit:
|
||||
Exch
|
||||
Pop $R0
|
||||
Exch $R1
|
||||
|
||||
FunctionEnd
|
||||
|
||||
; ------------------- ;
|
||||
; Check install dir ;
|
||||
; ------------------- ;
|
||||
Function CloseBrowseForFolderDialog
|
||||
!ifmacrodef "_P<>" ; NSIS 3+
|
||||
System::Call 'USER32::GetActiveWindow()p.r0'
|
||||
${If} $0 P<> $HwndParent
|
||||
!else
|
||||
System::Call 'USER32::GetActiveWindow()i.r0'
|
||||
${If} $0 <> $HwndParent
|
||||
!endif
|
||||
SendMessage $0 ${WM_CLOSE} 0 0
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
|
||||
Function .onVerifyInstDir
|
||||
|
||||
Push $R1
|
||||
${IsWritable} $INSTDIR $R1
|
||||
IntCmp $R1 0 pathgood
|
||||
Pop $R1
|
||||
Call CloseBrowseForFolderDialog
|
||||
MessageBox MB_OK|MB_USERICON "$(noRoot)" /SD IDOK
|
||||
Abort
|
||||
|
||||
pathgood:
|
||||
Pop $R1
|
||||
|
||||
FunctionEnd
|
||||
|
||||
; ------------------ ;
|
||||
; Desktop Shortcut ;
|
||||
; ------------------ ;
|
||||
Function finishpageaction
|
||||
CreateShortCut "$DESKTOP\${APP_NAME}.lnk" "$INSTDIR\stremio.exe" "" "$INSTDIR\stremio.exe" "" "" "" "${APP_NAME} ${PRODUCT_VERSION}"
|
||||
FunctionEnd
|
||||
BIN
utils/windows/stremio-runtime.exe
Normal file
BIN
utils/windows/stremio-runtime.exe
Normal file
Binary file not shown.
17
version/version-details.json
Normal file
17
version/version-details.json
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"shellVersion": "5.0.7",
|
||||
"files": {
|
||||
"windows-x64": {
|
||||
"url": "https://github.com/Zaarrg/stremio-desktop-v5/releases/download/5.0.0-beta.7/Stremio.5.0.7-x64.exe",
|
||||
"checksum": "a7b71844a12f23272f8a5658fefd0d94bdf9f7e3c9a820e7d1a07436b8927bdb"
|
||||
},
|
||||
"windows-x86": {
|
||||
"url": "https://github.com/Zaarrg/stremio-desktop-v5/releases/download/5.0.0-beta.7/Stremio.5.0.7-x86.exe",
|
||||
"checksum": "65bf17a67c22d67bf602a8023ac94ae63f8a685f32e63d1d28d3a6b0cb0932ef"
|
||||
},
|
||||
"server.js": {
|
||||
"url": "https://dl.strem.io/server/v4.20.8/desktop/server.js",
|
||||
"checksum": "7113200f5775c958fd141bc502a808ab00ebfbb53799a13c3ab0aca84c5fb476"
|
||||
}
|
||||
}
|
||||
}
|
||||
5
version/version.json
Normal file
5
version/version.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"upToDate": false,
|
||||
"versionDesc": "https://raw.githubusercontent.com/Zaarrg/stremio-desktop-v5/refs/heads/master/version/version-details.json",
|
||||
"signature": "f5b4X5+QImy0SmCyU3iVGTnqX/xbg7B/d55G7YN/96dLnV0d0vmXU+OijfNA6pq8mw21uolrUQmkPnyPuASVxx4x98AyjVFQVYoulPfArR/ME1UnNDbfdyWZBKhR5EXuCeCqmIHGjFgH59kOp1hHsCaKhTqPFcwE/L9PLvGy0RxL3IhTSgNnadg6BRhf0izcOusc+xRFKIKQuAc3/eYLTGTJTYjHykAdl/ok1ufttHv6ZCEhjo2ki44VsnanSeYmXa3vlFriUsdhrschxrE4RApE/fqQl4VhZh/3PRwUNJX/E25b7Yyqxy1hLJd4mkaY0Ag98KsynQBdmJp8zWSYPA=="
|
||||
}
|
||||
Loading…
Reference in a new issue