From a73707fabf58ac57f5a2e2a15f56ba59caac9ae0 Mon Sep 17 00:00:00 2001 From: Christopher Rosell Date: Sat, 29 Sep 2012 01:15:46 +0200 Subject: Add tools to build standalone Windows version and installer. --- win32/AdvReplaceInFile.nsh | 106 +++++++++++ win32/EnvVarUpdate.nsh | 327 +++++++++++++++++++++++++++++++++ win32/build-bbfreeze.py | 28 +++ win32/livestreamer-win32-installer.nsi | 144 +++++++++++++++ win32/livestreamerrc | 29 +++ win32/rtmpdump/README.txt | 23 +++ win32/rtmpdump/librtmp.dll | Bin 0 -> 262555 bytes win32/rtmpdump/rtmpdump.exe | Bin 0 -> 271737 bytes win32/rtmpdump/rtmpgw.exe | Bin 0 -> 267792 bytes win32/rtmpdump/rtmpsrv.exe | Bin 0 -> 260643 bytes win32/rtmpdump/rtmpsuck.exe | Bin 0 -> 260097 bytes 11 files changed, 657 insertions(+) create mode 100644 win32/AdvReplaceInFile.nsh create mode 100644 win32/EnvVarUpdate.nsh create mode 100644 win32/build-bbfreeze.py create mode 100644 win32/livestreamer-win32-installer.nsi create mode 100644 win32/livestreamerrc create mode 100644 win32/rtmpdump/README.txt create mode 100644 win32/rtmpdump/librtmp.dll create mode 100644 win32/rtmpdump/rtmpdump.exe create mode 100644 win32/rtmpdump/rtmpgw.exe create mode 100644 win32/rtmpdump/rtmpsrv.exe create mode 100644 win32/rtmpdump/rtmpsuck.exe diff --git a/win32/AdvReplaceInFile.nsh b/win32/AdvReplaceInFile.nsh new file mode 100644 index 0000000..c8c2c0b --- /dev/null +++ b/win32/AdvReplaceInFile.nsh @@ -0,0 +1,106 @@ +Function AdvReplaceInFile +Exch $0 ;file to replace in +Exch +Exch $1 ;number to replace after +Exch +Exch 2 +Exch $2 ;replace and onwards +Exch 2 +Exch 3 +Exch $3 ;replace with +Exch 3 +Exch 4 +Exch $4 ;to replace +Exch 4 +Push $5 ;minus count +Push $6 ;universal +Push $7 ;end string +Push $8 ;left string +Push $9 ;right string +Push $R0 ;file1 +Push $R1 ;file2 +Push $R2 ;read +Push $R3 ;universal +Push $R4 ;count (onwards) +Push $R5 ;count (after) +Push $R6 ;temp file name + + GetTempFileName $R6 + FileOpen $R1 $0 r ;file to search in + FileOpen $R0 $R6 w ;temp file + StrLen $R3 $4 + StrCpy $R4 -1 + StrCpy $R5 -1 + +loop_read: + ClearErrors + FileRead $R1 $R2 ;read line + IfErrors exit + + StrCpy $5 0 + StrCpy $7 $R2 + +loop_filter: + IntOp $5 $5 - 1 + StrCpy $6 $7 $R3 $5 ;search + StrCmp $6 "" file_write1 + StrCmp $6 $4 0 loop_filter + +StrCpy $8 $7 $5 ;left part +IntOp $6 $5 + $R3 +IntCmp $6 0 is0 not0 +is0: +StrCpy $9 "" +Goto done +not0: +StrCpy $9 $7 "" $6 ;right part +done: +StrCpy $7 $8$3$9 ;re-join + +IntOp $R4 $R4 + 1 +StrCmp $2 all loop_filter +StrCmp $R4 $2 0 file_write2 +IntOp $R4 $R4 - 1 + +IntOp $R5 $R5 + 1 +StrCmp $1 all loop_filter +StrCmp $R5 $1 0 file_write1 +IntOp $R5 $R5 - 1 +Goto file_write2 + +file_write1: + FileWrite $R0 $7 ;write modified line +Goto loop_read + +file_write2: + FileWrite $R0 $R2 ;write unmodified line +Goto loop_read + +exit: + FileClose $R0 + FileClose $R1 + + SetDetailsPrint none + Delete $0 + Rename $R6 $0 + Delete $R6 + SetDetailsPrint both + +Pop $R6 +Pop $R5 +Pop $R4 +Pop $R3 +Pop $R2 +Pop $R1 +Pop $R0 +Pop $9 +Pop $8 +Pop $7 +Pop $6 +Pop $5 +Pop $0 +Pop $1 +Pop $2 +Pop $3 +Pop $4 +FunctionEnd diff --git a/win32/EnvVarUpdate.nsh b/win32/EnvVarUpdate.nsh new file mode 100644 index 0000000..839d6a0 --- /dev/null +++ b/win32/EnvVarUpdate.nsh @@ -0,0 +1,327 @@ +/** + * EnvVarUpdate.nsh + * : Environmental Variables: append, prepend, and remove entries + * + * WARNING: If you use StrFunc.nsh header then include it before this file + * with all required definitions. This is to avoid conflicts + * + * Usage: + * ${EnvVarUpdate} "ResultVar" "EnvVarName" "Action" "RegLoc" "PathString" + * + * Credits: + * Version 1.0 + * * Cal Turney (turnec2) + * * Amir Szekely (KiCHiK) and e-circ for developing the forerunners of this + * function: AddToPath, un.RemoveFromPath, AddToEnvVar, un.RemoveFromEnvVar, + * WriteEnvStr, and un.DeleteEnvStr + * * Diego Pedroso (deguix) for StrTok + * * Kevin English (kenglish_hi) for StrContains + * * Hendri Adriaens (Smile2Me), Diego Pedroso (deguix), and Dan Fuhry + * (dandaman32) for StrReplace + * + * Version 1.1 (compatibility with StrFunc.nsh) + * * techtonik + * + * http://nsis.sourceforge.net/Environmental_Variables:_append%2C_prepend%2C_and_remove_entries + * + */ + + +!ifndef ENVVARUPDATE_FUNCTION +!define ENVVARUPDATE_FUNCTION +!verbose push +!verbose 3 +!include "LogicLib.nsh" +!include "WinMessages.NSH" +!include "StrFunc.nsh" + +; ---- Fix for conflict if StrFunc.nsh is already includes in main file ----------------------- +!macro _IncludeStrFunction StrFuncName + !ifndef ${StrFuncName}_INCLUDED + ${${StrFuncName}} + !endif + !ifndef Un${StrFuncName}_INCLUDED + ${Un${StrFuncName}} + !endif + !define un.${StrFuncName} "${Un${StrFuncName}}" +!macroend + +!insertmacro _IncludeStrFunction StrTok +!insertmacro _IncludeStrFunction StrStr +!insertmacro _IncludeStrFunction StrRep + +; ---------------------------------- Macro Definitions ---------------------------------------- +!macro _EnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString + Push "${EnvVarName}" + Push "${Action}" + Push "${RegLoc}" + Push "${PathString}" + Call EnvVarUpdate + Pop "${ResultVar}" +!macroend +!define EnvVarUpdate '!insertmacro "_EnvVarUpdateConstructor"' + +!macro _unEnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString + Push "${EnvVarName}" + Push "${Action}" + Push "${RegLoc}" + Push "${PathString}" + Call un.EnvVarUpdate + Pop "${ResultVar}" +!macroend +!define un.EnvVarUpdate '!insertmacro "_unEnvVarUpdateConstructor"' +; ---------------------------------- Macro Definitions end------------------------------------- + +;----------------------------------- EnvVarUpdate start---------------------------------------- +!define hklm_all_users 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' +!define hkcu_current_user 'HKCU "Environment"' + +!macro EnvVarUpdate UN + +Function ${UN}EnvVarUpdate + + Push $0 + Exch 4 + Exch $1 + Exch 3 + Exch $2 + Exch 2 + Exch $3 + Exch + Exch $4 + Push $5 + Push $6 + Push $7 + Push $8 + Push $9 + Push $R0 + + /* After this point: + ------------------------- + $0 = ResultVar (returned) + $1 = EnvVarName (input) + $2 = Action (input) + $3 = RegLoc (input) + $4 = PathString (input) + $5 = Orig EnvVar (read from registry) + $6 = Len of $0 (temp) + $7 = tempstr1 (temp) + $8 = Entry counter (temp) + $9 = tempstr2 (temp) + $R0 = tempChar (temp) */ + + ; Step 1: Read contents of EnvVarName from RegLoc + ; + ; Check for empty EnvVarName + ${If} $1 == "" + SetErrors + DetailPrint "ERROR: EnvVarName is blank" + Goto EnvVarUpdate_Restore_Vars + ${EndIf} + + ; Check for valid Action + ${If} $2 != "A" + ${AndIf} $2 != "P" + ${AndIf} $2 != "R" + SetErrors + DetailPrint "ERROR: Invalid Action - must be A, P, or R" + Goto EnvVarUpdate_Restore_Vars + ${EndIf} + + ${If} $3 == HKLM + ReadRegStr $5 ${hklm_all_users} $1 ; Get EnvVarName from all users into $5 + ${ElseIf} $3 == HKCU + ReadRegStr $5 ${hkcu_current_user} $1 ; Read EnvVarName from current user into $5 + ${Else} + SetErrors + DetailPrint 'ERROR: Action is [$3] but must be "HKLM" or HKCU"' + Goto EnvVarUpdate_Restore_Vars + ${EndIf} + + ; Check for empty PathString + ${If} $4 == "" + SetErrors + DetailPrint "ERROR: PathString is blank" + Goto EnvVarUpdate_Restore_Vars + ${EndIf} + + ; Make sure we've got some work to do + ${If} $5 == "" + ${AndIf} $2 == "R" + SetErrors + DetailPrint "$1 is empty - Nothing to remove" + Goto EnvVarUpdate_Restore_Vars + ${EndIf} + + ; Step 2: Scrub EnvVar + ; + StrCpy $0 $5 ; Copy the contents to $0 + ; Remove spaces around semicolons (NOTE: spaces before the 1st entry or + ; after the last one are not removed here but instead in Step 3) + ${If} $0 != "" ; If EnvVar is not empty ... + ${Do} + ${${UN}StrStr} $7 $0 " ;" + ${If} $7 == "" + ${ExitDo} + ${EndIf} + ${${UN}StrRep} $0 $0 " ;" ";" ; Remove ';' + ${Loop} + ${Do} + ${${UN}StrStr} $7 $0 "; " + ${If} $7 == "" + ${ExitDo} + ${EndIf} + ${${UN}StrRep} $0 $0 "; " ";" ; Remove ';' + ${Loop} + ${Do} + ${${UN}StrStr} $7 $0 ";;" + ${If} $7 == "" + ${ExitDo} + ${EndIf} + ${${UN}StrRep} $0 $0 ";;" ";" + ${Loop} + + ; Remove a leading or trailing semicolon from EnvVar + StrCpy $7 $0 1 0 + ${If} $7 == ";" + StrCpy $0 $0 "" 1 ; Change ';' to '' + ${EndIf} + StrLen $6 $0 + IntOp $6 $6 - 1 + StrCpy $7 $0 1 $6 + ${If} $7 == ";" + StrCpy $0 $0 $6 ; Change ';' to '' + ${EndIf} + ; DetailPrint "Scrubbed $1: [$0]" ; Uncomment to debug + ${EndIf} + + /* Step 3. Remove all instances of the target path/string (even if "A" or "P") + $6 = bool flag (1 = found and removed PathString) + $7 = a string (e.g. path) delimited by semicolon(s) + $8 = entry counter starting at 0 + $9 = copy of $0 + $R0 = tempChar */ + + ${If} $5 != "" ; If EnvVar is not empty ... + StrCpy $9 $0 + StrCpy $0 "" + StrCpy $8 0 + StrCpy $6 0 + + ${Do} + ${${UN}StrTok} $7 $9 ";" $8 "0" ; $7 = next entry, $8 = entry counter + + ${If} $7 == "" ; If we've run out of entries, + ${ExitDo} ; were done + ${EndIf} ; + + ; Remove leading and trailing spaces from this entry (critical step for Action=Remove) + ${Do} + StrCpy $R0 $7 1 + ${If} $R0 != " " + ${ExitDo} + ${EndIf} + StrCpy $7 $7 "" 1 ; Remove leading space + ${Loop} + ${Do} + StrCpy $R0 $7 1 -1 + ${If} $R0 != " " + ${ExitDo} + ${EndIf} + StrCpy $7 $7 -1 ; Remove trailing space + ${Loop} + ${If} $7 == $4 ; If string matches, remove it by not appending it + StrCpy $6 1 ; Set 'found' flag + ${ElseIf} $7 != $4 ; If string does NOT match + ${AndIf} $0 == "" ; and the 1st string being added to $0, + StrCpy $0 $7 ; copy it to $0 without a prepended semicolon + ${ElseIf} $7 != $4 ; If string does NOT match + ${AndIf} $0 != "" ; and this is NOT the 1st string to be added to $0, + StrCpy $0 $0;$7 ; append path to $0 with a prepended semicolon + ${EndIf} ; + + IntOp $8 $8 + 1 ; Bump counter + ${Loop} ; Check for duplicates until we run out of paths + ${EndIf} + + ; Step 4: Perform the requested Action + ; + ${If} $2 != "R" ; If Append or Prepend + ${If} $6 == 1 ; And if we found the target + DetailPrint "Target is already present in $1. It will be removed and" + ${EndIf} + ${If} $0 == "" ; If EnvVar is (now) empty + StrCpy $0 $4 ; just copy PathString to EnvVar + ${If} $6 == 0 ; If found flag is either 0 + ${OrIf} $6 == "" ; or blank (if EnvVarName is empty) + DetailPrint "$1 was empty and has been updated with the target" + ${EndIf} + ${ElseIf} $2 == "A" ; If Append (and EnvVar is not empty), + StrCpy $0 $0;$4 ; append PathString + ${If} $6 == 1 + DetailPrint "appended to $1" + ${Else} + DetailPrint "Target was appended to $1" + ${EndIf} + ${Else} ; If Prepend (and EnvVar is not empty), + StrCpy $0 $4;$0 ; prepend PathString + ${If} $6 == 1 + DetailPrint "prepended to $1" + ${Else} + DetailPrint "Target was prepended to $1" + ${EndIf} + ${EndIf} + ${Else} ; If Action = Remove + ${If} $6 == 1 ; and we found the target + DetailPrint "Target was found and removed from $1" + ${Else} + DetailPrint "Target was NOT found in $1 (nothing to remove)" + ${EndIf} + ${If} $0 == "" + DetailPrint "$1 is now empty" + ${EndIf} + ${EndIf} + + ; Step 5: Update the registry at RegLoc with the updated EnvVar and announce the change + ; + ClearErrors + ${If} $3 == HKLM + WriteRegExpandStr ${hklm_all_users} $1 $0 ; Write it in all users section + ${ElseIf} $3 == HKCU + WriteRegExpandStr ${hkcu_current_user} $1 $0 ; Write it to current user section + ${EndIf} + + IfErrors 0 +4 + MessageBox MB_OK|MB_ICONEXCLAMATION "Could not write updated $1 to $3" + DetailPrint "Could not write updated $1 to $3" + Goto EnvVarUpdate_Restore_Vars + + ; "Export" our change + SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 + + EnvVarUpdate_Restore_Vars: + ; + ; Restore the user's variables and return ResultVar + Pop $R0 + Pop $9 + Pop $8 + Pop $7 + Pop $6 + Pop $5 + Pop $4 + Pop $3 + Pop $2 + Pop $1 + Push $0 ; Push my $0 (ResultVar) + Exch + Pop $0 ; Restore his $0 + +FunctionEnd + +!macroend ; EnvVarUpdate UN +!insertmacro EnvVarUpdate "" +!insertmacro EnvVarUpdate "un." +;----------------------------------- EnvVarUpdate end---------------------------------------- + +!verbose pop +!endif diff --git a/win32/build-bbfreeze.py b/win32/build-bbfreeze.py new file mode 100644 index 0000000..8dd9d82 --- /dev/null +++ b/win32/build-bbfreeze.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python + +build_version = "1.3.1" +python_path = "C:\\Python27\\" + +import os +import glob +import shutil + +from bbfreeze import Freezer + +shutil.copy(python_path + "Scripts\livestreamer-script.py", python_path + "Scripts\livestreamer.py") + +includes = ("pbs", "requests", "re", "xml", "xml.dom.minidom", + "zlib", "ctypes", "argparse", "hmac", "tempfile", + "os", "sys", "subprocess", "getpass", "msvcrt", + "urllib", "urlparse", "pkgutil", "imp") + +dst = "..\\build-win32\\livestreamer-bbfreeze-" + build_version + "\\" + +f = Freezer(dst, includes=includes) +f.include_py = False +f.addScript(python_path + "Scripts\livestreamer.py", gui_only=False) + +f() + + + diff --git a/win32/livestreamer-win32-installer.nsi b/win32/livestreamer-win32-installer.nsi new file mode 100644 index 0000000..c935180 --- /dev/null +++ b/win32/livestreamer-win32-installer.nsi @@ -0,0 +1,144 @@ +# Livestreamer Windows installer script + +# Set default compressor +SetCompressor lzma + +### +### --- The PROGRAM_VERSION !define need to be updated with new Deluge versions --- +### + +# Script version; displayed when running the installer +!define LIVESTREAMER_INSTALLER_VERSION "0.1" + +# Deluge program information +!define PROGRAM_NAME "Livestreamer" +!define PROGRAM_VERSION "1.3.1" +!define PROGRAM_WEB_SITE "http://github.com/chrippa/livestreamer" + +# Python files generated with bbfreeze +!define LIVESTREAMER_PYTHON_BBFREEZE_OUTPUT_DIR "..\build-win32\livestreamer-bbfreeze-${PROGRAM_VERSION}" + +# EnvVarUpdate +!include EnvVarUpdate.nsh +!include AdvReplaceInFile.nsh + +# --- Interface settings --- + +# Modern User Interface 2 +!include MUI2.nsh + +# Installer +!define MUI_COMPONENTSPAGE_SMALLDESC +!define MUI_FINISHPAGE_NOAUTOCLOSE +!define MUI_ABORTWARNING + +# Uninstaller +!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" +!define MUI_UNFINISHPAGE_NOAUTOCLOSE + +# --- Start of Modern User Interface --- + +# Welcome page +!insertmacro MUI_PAGE_WELCOME + +# License page +!insertmacro MUI_PAGE_LICENSE "..\LICENSE" + +# Components page +!insertmacro MUI_PAGE_COMPONENTS + +# Let the user select the installation directory +!insertmacro MUI_PAGE_DIRECTORY + +# Run installation +!insertmacro MUI_PAGE_INSTFILES + +# Display 'finished' page +!insertmacro MUI_PAGE_FINISH + +# Uninstaller pages +!insertmacro MUI_UNPAGE_INSTFILES + +# Language files +!insertmacro MUI_LANGUAGE "English" + + +# --- Functions --- + +Function un.onUninstSuccess + HideWindow + MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer." +FunctionEnd + +Function un.onInit + MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Do you want to completely remove $(^Name) and all of its components?" IDYES +2 + Abort +FunctionEnd + + +# --- Installation sections --- + +# Compare versions +!include "WordFunc.nsh" + +!define PROGRAM_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGRAM_NAME}" +!define PROGRAM_UNINST_ROOT_KEY "HKLM" + +# Branding text +BrandingText "Livestreamer Installer v${LIVESTREAMER_INSTALLER_VERSION}" + +Name "${PROGRAM_NAME} ${PROGRAM_VERSION}" +OutFile "..\build-win32\livestreamer-${PROGRAM_VERSION}-win32-setup.exe" + +InstallDir "$PROGRAMFILES\Livestreamer" + +ShowInstDetails show +ShowUnInstDetails show + +# Install main application +Section "Livestreamer" Section1 + SectionIn RO + + SetOutPath $INSTDIR + File /r "${LIVESTREAMER_PYTHON_BBFREEZE_OUTPUT_DIR}\*.*" + File /r "rtmpdump" + + SetOutPath "$APPDATA\livestreamer" + + SetOverwrite off + File "livestreamerrc" + + Push @INSTDIR@ + Push $INSTDIR + Push all + Push all + Push "$APPDATA\livestreamer\livestreamerrc" + Call AdvReplaceInFile + + ${EnvVarUpdate} $0 "PATH" "A" "HKLM" "$INSTDIR" +SectionEnd + +Section -Uninstaller + WriteUninstaller "$INSTDIR\Livestreamer-uninst.exe" + WriteRegStr ${PROGRAM_UNINST_ROOT_KEY} "${PROGRAM_UNINST_KEY}" "DisplayName" "$(^Name)" + WriteRegStr ${PROGRAM_UNINST_ROOT_KEY} "${PROGRAM_UNINST_KEY}" "UninstallString" "$INSTDIR\Livestreamer-uninst.exe" +SectionEnd + + +LangString DESC_Section1 ${LANG_ENGLISH} "Install Livestreamer." + +!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN + !insertmacro MUI_DESCRIPTION_TEXT ${Section1} $(DESC_Section1) +!insertmacro MUI_FUNCTION_DESCRIPTION_END + + +# --- Uninstallation section(s) --- + +Section Uninstall + RmDir /r "$INSTDIR" + + SetShellVarContext all + + DeleteRegKey ${PROGRAM_UNINST_ROOT_KEY} "${PROGRAM_UNINST_KEY}" + ${un.EnvVarUpdate} $0 "PATH" "R" "HKLM" "$INSTDIR" +SectionEnd diff --git a/win32/livestreamerrc b/win32/livestreamerrc new file mode 100644 index 0000000..2de65b5 --- /dev/null +++ b/win32/livestreamerrc @@ -0,0 +1,29 @@ +# Path to a video player that can read from standard input (e.g VLC, mplayer) + +# Important: You must use a quoted path if there are spaces in the path. This only +# applies to the player and not the rtmpdump path since the player command is passed +# through the "shell" to allow parameters to be passed to the player. + +player="C:\Program Files (x86)\VideoLAN\VLC\vlc.exe" +#player="C:\Program Files\VideoLAN\VLC\vlc.exe" + +# Hides console output from video player +quiet-player + +# Full path to rtmpdump (ony needed for RTMP based streams) +rtmpdump=@INSTDIR@\rtmpdump\rtmpdump.exe + +# Log level, default is info +#loglevel=debug + +# A cookie from your web browser to allow access to Twitch/JustinTV streams that require authentication +#jtv-cookie= + +# A cookie from your web browser to allow access to GOMTV.net streams +#gomtv-cookie= + +# A username and password to allow access to GOMTV.net streams +#gomtv-username= +#gomtv-password= + + diff --git a/win32/rtmpdump/README.txt b/win32/rtmpdump/README.txt new file mode 100644 index 0000000..4f1b9be --- /dev/null +++ b/win32/rtmpdump/README.txt @@ -0,0 +1,23 @@ + +This is a RTMPdump Win32 static build by Steven Penny. + +Steven’s Blog: http://svnpenn.blogspot.com + + +RTMPdump version 2.4 git-6230845 2011-9-25 + +The source code for this RTMPdump build can be found at: + http://rtmpdump.mplayerhq.hu + http://repo.or.cz/w/rtmpdump.git + +This version of RTMPdump was built on: + Windows 7 Ultimate Service Pack 1 + +These binaries were built with: + + MinGW 0.3-alpha-2.1 + GCC 4.6.1-2 + Bash 3.1.17-4 + Make 3.81-3 + ZLib 1.2.5 + PolarSSL 1.0.0 \ No newline at end of file diff --git a/win32/rtmpdump/librtmp.dll b/win32/rtmpdump/librtmp.dll new file mode 100644 index 0000000..d21c52a Binary files /dev/null and b/win32/rtmpdump/librtmp.dll differ diff --git a/win32/rtmpdump/rtmpdump.exe b/win32/rtmpdump/rtmpdump.exe new file mode 100644 index 0000000..c8b82ce Binary files /dev/null and b/win32/rtmpdump/rtmpdump.exe differ diff --git a/win32/rtmpdump/rtmpgw.exe b/win32/rtmpdump/rtmpgw.exe new file mode 100644 index 0000000..b4f063f Binary files /dev/null and b/win32/rtmpdump/rtmpgw.exe differ diff --git a/win32/rtmpdump/rtmpsrv.exe b/win32/rtmpdump/rtmpsrv.exe new file mode 100644 index 0000000..19f488c Binary files /dev/null and b/win32/rtmpdump/rtmpsrv.exe differ diff --git a/win32/rtmpdump/rtmpsuck.exe b/win32/rtmpdump/rtmpsuck.exe new file mode 100644 index 0000000..e0ffa41 Binary files /dev/null and b/win32/rtmpdump/rtmpsuck.exe differ -- cgit v1.2.3