You've already forked N_m3u8DL-CLI
							
							
				mirror of
				https://github.com/nilaoda/N_m3u8DL-CLI
				synced 2025-11-04 04:02:28 +01:00 
			
		
		
		
	Compare commits
	
		
			222 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					5267be1699 | ||
| 
						 | 
					20bfda39e7 | ||
| 
						 | 
					ba4c0eeda7 | ||
| 
						 | 
					5d72e24002 | ||
| 
						 | 
					a87c051d23 | ||
| 
						 | 
					44e1b68d6b | ||
| 
						 | 
					e65dfa52cd | ||
| 
						 | 
					965c173899 | ||
| 
						 | 
					880af02cc2 | ||
| 
						 | 
					2742de43c4 | ||
| 
						 | 
					9d8cb57390 | ||
| 
						 | 
					9e2a192dab | ||
| 
						 | 
					33cf9e2256 | ||
| 
						 | 
					2959cbbb5c | ||
| 
						 | 
					c2eb8a6adc | ||
| 
						 | 
					e1b591b81c | ||
| 
						 | 
					334b1939b5 | ||
| 
						 | 
					7e916b65fd | ||
| 
						 | 
					4ead563fa2 | ||
| 
						 | 
					1b387a06e5 | ||
| 
						 | 
					6e7b4ac7ea | ||
| 
						 | 
					e98c5205d1 | ||
| 
						 | 
					d7890dd124 | ||
| 
						 | 
					82f2111522 | ||
| 
						 | 
					4c3207586f | ||
| 
						 | 
					69b411e37c | ||
| 
						 | 
					1e8525041f | ||
| 
						 | 
					65ae72d4a4 | ||
| 
						 | 
					4a4bfae5ab | ||
| 
						 | 
					d586dddfcd | ||
| 
						 | 
					fca6b3ff6c | ||
| 
						 | 
					5d75626a36 | ||
| 
						 | 
					a94271c244 | ||
| 
						 | 
					c51118dce7 | ||
| 
						 | 
					81b2e87bf7 | ||
| 
						 | 
					71a9878aaa | ||
| 
						 | 
					769fe4e926 | ||
| 
						 | 
					1f57ba7c09 | ||
| 
						 | 
					71282bda30 | ||
| 
						 | 
					41ee8aebdf | ||
| 
						 | 
					a4537bc093 | ||
| 
						 | 
					b8a60b3917 | ||
| 
						 | 
					8091dd290f | ||
| 
						 | 
					d48e84e611 | ||
| 
						 | 
					9f5423a437 | ||
| 
						 | 
					ce7e38770a | ||
| 
						 | 
					8fdb2e918e | ||
| 
						 | 
					d4b7d240c1 | ||
| 
						 | 
					484d2941ed | ||
| 
						 | 
					a0f2b66575 | ||
| 
						 | 
					65cc0681e2 | ||
| 
						 | 
					7d980ec9a2 | ||
| 
						 | 
					ec5892c05a | ||
| 
						 | 
					9aed50fbf9 | ||
| 
						 | 
					d657b455cd | ||
| 
						 | 
					cda6575605 | ||
| 
						 | 
					0d6377d41b | ||
| 
						 | 
					9c76bdcbce | ||
| 
						 | 
					83915ff606 | ||
| 
						 | 
					9cd4746f33 | ||
| 
						 | 
					33a5b917ac | ||
| 
						 | 
					f69978bd82 | ||
| 
						 | 
					d9fd526886 | ||
| 
						 | 
					1cc8ecfaaf | ||
| 
						 | 
					2bc2dde2ad | ||
| 
						 | 
					c3ddcf9e0e | ||
| 
						 | 
					ba5d20dd02 | ||
| 
						 | 
					16f705fe66 | ||
| 
						 | 
					d141cabc4a | ||
| 
						 | 
					adcf884a93 | ||
| 
						 | 
					9d903a025f | ||
| 
						 | 
					0bd23ab641 | ||
| 
						 | 
					a38f27ccd7 | ||
| 
						 | 
					3acec5efd3 | ||
| 
						 | 
					90874e4bfe | ||
| 
						 | 
					b94768e3e8 | ||
| 
						 | 
					311f3b882e | ||
| 
						 | 
					4b4f537984 | ||
| 
						 | 
					8032d50b42 | ||
| 
						 | 
					f615764e55 | ||
| 
						 | 
					ccaa200ef8 | ||
| 
						 | 
					6058d878eb | ||
| 
						 | 
					c712c6dee0 | ||
| 
						 | 
					bb24bb998f | ||
| 
						 | 
					e9d951efa5 | ||
| 
						 | 
					6f88a805ef | ||
| 
						 | 
					6aa6d63a8d | ||
| 
						 | 
					147246caba | ||
| 
						 | 
					35c1ee4777 | ||
| 
						 | 
					8b32081b85 | ||
| 
						 | 
					c00de328d1 | ||
| 
						 | 
					d5193c1645 | ||
| 
						 | 
					c06fbf5820 | ||
| 
						 | 
					e700edba56 | ||
| 
						 | 
					aad948da7c | ||
| 
						 | 
					14f7b20176 | ||
| 
						 | 
					a66a9a4096 | ||
| 
						 | 
					c862f23a9c | ||
| 
						 | 
					1a722e80de | ||
| 
						 | 
					eff43e8ac3 | ||
| 
						 | 
					7648f8f8dc | ||
| 
						 | 
					1edc1a43fe | ||
| 
						 | 
					01e7735018 | ||
| 
						 | 
					a0c41d6116 | ||
| 
						 | 
					c3c25774de | ||
| 
						 | 
					ba40641a21 | ||
| 
						 | 
					5d76418780 | ||
| 
						 | 
					fd48b766b5 | ||
| 
						 | 
					0f25cc0ae8 | ||
| 
						 | 
					1c6bd688e3 | ||
| 
						 | 
					480857cc3b | ||
| 
						 | 
					52af9a44a8 | ||
| 
						 | 
					84d137b504 | ||
| 
						 | 
					a4f1064c81 | ||
| 
						 | 
					eac08b12f8 | ||
| 
						 | 
					c81c911888 | ||
| 
						 | 
					361e901e5b | ||
| 
						 | 
					3567f4c4cc | ||
| 
						 | 
					2f7b0f7304 | ||
| 
						 | 
					000d0db4ae | ||
| 
						 | 
					d551ad52c1 | ||
| 
						 | 
					c064c83c21 | ||
| 
						 | 
					f6ed0f9e4d | ||
| 
						 | 
					f65fee94ca | ||
| 
						 | 
					ce64a92b0d | ||
| 
						 | 
					42790ce540 | ||
| 
						 | 
					83d8ca1c8c | ||
| 
						 | 
					4b5a64eb98 | ||
| 
						 | 
					2b5af09c3b | ||
| 
						 | 
					6368adc2ab | ||
| 
						 | 
					fcd7840091 | ||
| 
						 | 
					d77cb62dff | ||
| 
						 | 
					34394c6a2b | ||
| 
						 | 
					091cba8555 | ||
| 
						 | 
					b02b6b7168 | ||
| 
						 | 
					b7408b0599 | ||
| 
						 | 
					b83cb35170 | ||
| 
						 | 
					ed0a7b71a7 | ||
| 
						 | 
					50eae19bf3 | ||
| 
						 | 
					cba8f3ea52 | ||
| 
						 | 
					7fd93e1232 | ||
| 
						 | 
					74a7e3c3ec | ||
| 
						 | 
					849d712e11 | ||
| 
						 | 
					7544f3a02c | ||
| 
						 | 
					0120736c53 | ||
| 
						 | 
					e4bde4926c | ||
| 
						 | 
					d42cd6a60d | ||
| 
						 | 
					175f13adc9 | ||
| 
						 | 
					72f1c043b1 | ||
| 
						 | 
					a2e2070f5d | ||
| 
						 | 
					6c96deb366 | ||
| 
						 | 
					2bd900ee5d | ||
| 
						 | 
					1261810510 | ||
| 
						 | 
					26823dbd7e | ||
| 
						 | 
					698699d9fc | ||
| 
						 | 
					ebed7fa1e3 | ||
| 
						 | 
					73a8348155 | ||
| 
						 | 
					5ace0b3a4f | ||
| 
						 | 
					5abe889da0 | ||
| 
						 | 
					f1070fd1b4 | ||
| 
						 | 
					4af82cc7f9 | ||
| 
						 | 
					809380b7ab | ||
| 
						 | 
					ab57420507 | ||
| 
						 | 
					80230f12fe | ||
| 
						 | 
					a6c7c0fd8c | ||
| 
						 | 
					bd6df6b58c | ||
| 
						 | 
					e0a9071d62 | ||
| 
						 | 
					5c9bcf72d2 | ||
| 
						 | 
					7cf2c12d0c | ||
| 
						 | 
					1b35fe2d2c | ||
| 
						 | 
					ed3aae1cb9 | ||
| 
						 | 
					01c2ecbeb5 | ||
| 
						 | 
					9993ec8177 | ||
| 
						 | 
					464300c860 | ||
| 
						 | 
					45fa58a46f | ||
| 
						 | 
					f93ddc7107 | ||
| 
						 | 
					05f450fa6d | ||
| 
						 | 
					580c374d7b | ||
| 
						 | 
					b58dc5d8e0 | ||
| 
						 | 
					f50cf7862a | ||
| 
						 | 
					fdad68d483 | ||
| 
						 | 
					d7aaa5323b | ||
| 
						 | 
					6c2e13b800 | ||
| 
						 | 
					086fc57958 | ||
| 
						 | 
					bc349b8977 | ||
| 
						 | 
					cc4efed3c6 | ||
| 
						 | 
					cf958e833b | ||
| 
						 | 
					fb09add0cd | ||
| 
						 | 
					5a3c5baefd | ||
| 
						 | 
					839afd8e61 | ||
| 
						 | 
					338c7a25d0 | ||
| 
						 | 
					f57ce8c2da | ||
| 
						 | 
					a5009e1683 | ||
| 
						 | 
					66933da9de | ||
| 
						 | 
					136389e248 | ||
| 
						 | 
					7971104bd4 | ||
| 
						 | 
					cc4941554d | ||
| 
						 | 
					c50371080a | ||
| 
						 | 
					154c5f84a1 | ||
| 
						 | 
					1556ee42df | ||
| 
						 | 
					121ff9f226 | ||
| 
						 | 
					e5b84c2f04 | ||
| 
						 | 
					7e562a06bb | ||
| 
						 | 
					1eae19c3ea | ||
| 
						 | 
					ba33049b99 | ||
| 
						 | 
					9773087bf9 | ||
| 
						 | 
					b60d39ad0d | ||
| 
						 | 
					e89705a370 | ||
| 
						 | 
					4aea16d672 | ||
| 
						 | 
					afc69eae1a | ||
| 
						 | 
					2446a25b35 | ||
| 
						 | 
					d37524180d | ||
| 
						 | 
					b02a29fbb7 | ||
| 
						 | 
					e87d02230d | ||
| 
						 | 
					63609a0970 | ||
| 
						 | 
					1fe798ab19 | ||
| 
						 | 
					21b9977501 | ||
| 
						 | 
					fbe37be499 | ||
| 
						 | 
					6416dd642d | ||
| 
						 | 
					967f0582a6 | ||
| 
						 | 
					a5aeffc6ec | ||
| 
						 | 
					745cbd92ad | 
							
								
								
									
										63
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
				
			|||||||
 | 
					###############################################################################
 | 
				
			||||||
 | 
					# Set default behavior to automatically normalize line endings.
 | 
				
			||||||
 | 
					###############################################################################
 | 
				
			||||||
 | 
					* text=auto
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					###############################################################################
 | 
				
			||||||
 | 
					# Set default behavior for command prompt diff.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This is need for earlier builds of msysgit that does not have it on by
 | 
				
			||||||
 | 
					# default for csharp files.
 | 
				
			||||||
 | 
					# Note: This is only used by command line
 | 
				
			||||||
 | 
					###############################################################################
 | 
				
			||||||
 | 
					#*.cs     diff=csharp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					###############################################################################
 | 
				
			||||||
 | 
					# Set the merge driver for project and solution files
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Merging from the command prompt will add diff markers to the files if there
 | 
				
			||||||
 | 
					# are conflicts (Merging from VS is not affected by the settings below, in VS
 | 
				
			||||||
 | 
					# the diff markers are never inserted). Diff markers may cause the following 
 | 
				
			||||||
 | 
					# file extensions to fail to load in VS. An alternative would be to treat
 | 
				
			||||||
 | 
					# these files as binary and thus will always conflict and require user
 | 
				
			||||||
 | 
					# intervention with every merge. To do so, just uncomment the entries below
 | 
				
			||||||
 | 
					###############################################################################
 | 
				
			||||||
 | 
					#*.sln       merge=binary
 | 
				
			||||||
 | 
					#*.csproj    merge=binary
 | 
				
			||||||
 | 
					#*.vbproj    merge=binary
 | 
				
			||||||
 | 
					#*.vcxproj   merge=binary
 | 
				
			||||||
 | 
					#*.vcproj    merge=binary
 | 
				
			||||||
 | 
					#*.dbproj    merge=binary
 | 
				
			||||||
 | 
					#*.fsproj    merge=binary
 | 
				
			||||||
 | 
					#*.lsproj    merge=binary
 | 
				
			||||||
 | 
					#*.wixproj   merge=binary
 | 
				
			||||||
 | 
					#*.modelproj merge=binary
 | 
				
			||||||
 | 
					#*.sqlproj   merge=binary
 | 
				
			||||||
 | 
					#*.wwaproj   merge=binary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					###############################################################################
 | 
				
			||||||
 | 
					# behavior for image files
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# image files are treated as binary by default.
 | 
				
			||||||
 | 
					###############################################################################
 | 
				
			||||||
 | 
					#*.jpg   binary
 | 
				
			||||||
 | 
					#*.png   binary
 | 
				
			||||||
 | 
					#*.gif   binary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					###############################################################################
 | 
				
			||||||
 | 
					# diff behavior for common document formats
 | 
				
			||||||
 | 
					# 
 | 
				
			||||||
 | 
					# Convert binary document formats to text before diffing them. This feature
 | 
				
			||||||
 | 
					# is only available from the command line. Turn it on by uncommenting the 
 | 
				
			||||||
 | 
					# entries below.
 | 
				
			||||||
 | 
					###############################################################################
 | 
				
			||||||
 | 
					#*.doc   diff=astextplain
 | 
				
			||||||
 | 
					#*.DOC   diff=astextplain
 | 
				
			||||||
 | 
					#*.docx  diff=astextplain
 | 
				
			||||||
 | 
					#*.DOCX  diff=astextplain
 | 
				
			||||||
 | 
					#*.dot   diff=astextplain
 | 
				
			||||||
 | 
					#*.DOT   diff=astextplain
 | 
				
			||||||
 | 
					#*.pdf   diff=astextplain
 | 
				
			||||||
 | 
					#*.PDF   diff=astextplain
 | 
				
			||||||
 | 
					#*.rtf   diff=astextplain
 | 
				
			||||||
 | 
					#*.RTF   diff=astextplain
 | 
				
			||||||
							
								
								
									
										34
									
								
								.github/workflows/build_latest.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								.github/workflows/build_latest.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					name: Build_Latest
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					on: [push]
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					jobs:
 | 
				
			||||||
 | 
					  build:
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					    runs-on: windows-latest
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					    - uses: actions/checkout@v1
 | 
				
			||||||
 | 
					      name: Checkout Code
 | 
				
			||||||
 | 
					     
 | 
				
			||||||
 | 
					    - name: Setup MSBuild Path
 | 
				
			||||||
 | 
					      uses: warrenbuckley/Setup-MSBuild@v1
 | 
				
			||||||
 | 
					      env:
 | 
				
			||||||
 | 
					        ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true'
 | 
				
			||||||
 | 
					       
 | 
				
			||||||
 | 
					    - name: Setup NuGet
 | 
				
			||||||
 | 
					      uses: NuGet/setup-nuget@v1.0.2
 | 
				
			||||||
 | 
					      env:
 | 
				
			||||||
 | 
					        ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true'
 | 
				
			||||||
 | 
					     
 | 
				
			||||||
 | 
					    - name: Restore NuGet Packages
 | 
				
			||||||
 | 
					      run: nuget restore N_m3u8DL-CLI.sln
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					    - name: Build 
 | 
				
			||||||
 | 
					      run: msbuild N_m3u8DL-CLI.sln /p:Configuration=Release /p:DebugSymbols=false /p:DebugType=None
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					    - name: Upload Artifact
 | 
				
			||||||
 | 
					      uses: actions/upload-artifact@v1.0.0
 | 
				
			||||||
 | 
					      with:
 | 
				
			||||||
 | 
					        name: N_m3u8DL-CLI_latest
 | 
				
			||||||
 | 
					        path: N_m3u8DL-CLI\bin\Release\
 | 
				
			||||||
							
								
								
									
										261
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										261
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										21
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					MIT License
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Copyright (c) 2019 nilaoda
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The above copyright notice and this permission notice shall be included in all
 | 
				
			||||||
 | 
					copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
				
			||||||
 | 
					SOFTWARE.
 | 
				
			||||||
							
								
								
									
										25
									
								
								N_m3u8DL-CLI.sln
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								N_m3u8DL-CLI.sln
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					Microsoft Visual Studio Solution File, Format Version 12.00
 | 
				
			||||||
 | 
					# Visual Studio Version 16
 | 
				
			||||||
 | 
					VisualStudioVersion = 16.0.29215.179
 | 
				
			||||||
 | 
					MinimumVisualStudioVersion = 10.0.40219.1
 | 
				
			||||||
 | 
					Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "N_m3u8DL-CLI", "N_m3u8DL-CLI\N_m3u8DL-CLI.csproj", "{4FB61439-B738-46AC-B3AF-2BF72150D057}"
 | 
				
			||||||
 | 
					EndProject
 | 
				
			||||||
 | 
					Global
 | 
				
			||||||
 | 
						GlobalSection(SolutionConfigurationPlatforms) = preSolution
 | 
				
			||||||
 | 
							Debug|Any CPU = Debug|Any CPU
 | 
				
			||||||
 | 
							Release|Any CPU = Release|Any CPU
 | 
				
			||||||
 | 
						EndGlobalSection
 | 
				
			||||||
 | 
						GlobalSection(ProjectConfigurationPlatforms) = postSolution
 | 
				
			||||||
 | 
							{4FB61439-B738-46AC-B3AF-2BF72150D057}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 | 
				
			||||||
 | 
							{4FB61439-B738-46AC-B3AF-2BF72150D057}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
				
			||||||
 | 
							{4FB61439-B738-46AC-B3AF-2BF72150D057}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
				
			||||||
 | 
							{4FB61439-B738-46AC-B3AF-2BF72150D057}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
				
			||||||
 | 
						EndGlobalSection
 | 
				
			||||||
 | 
						GlobalSection(SolutionProperties) = preSolution
 | 
				
			||||||
 | 
							HideSolutionNode = FALSE
 | 
				
			||||||
 | 
						EndGlobalSection
 | 
				
			||||||
 | 
						GlobalSection(ExtensibilityGlobals) = postSolution
 | 
				
			||||||
 | 
							SolutionGuid = {82B9270D-B7B2-4591-BF8A-5B4EBCD0EA8A}
 | 
				
			||||||
 | 
						EndGlobalSection
 | 
				
			||||||
 | 
					EndGlobal
 | 
				
			||||||
							
								
								
									
										6
									
								
								N_m3u8DL-CLI/App.config
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								N_m3u8DL-CLI/App.config
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<configuration>
 | 
				
			||||||
 | 
					    <startup> 
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/></startup>
 | 
				
			||||||
 | 
					</configuration>
 | 
				
			||||||
							
								
								
									
										80
									
								
								N_m3u8DL-CLI/CommandLineArgument.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								N_m3u8DL-CLI/CommandLineArgument.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
				
			|||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace N_m3u8DL_CLI
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * https://www.cnblogs.com/linxuanchen/p/c-sharp-command-line-argument-parser.html
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public class CommandLineArgument
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        List<CommandLineArgument> _arguments;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int _index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        string _argumentText;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public CommandLineArgument Next
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (_index < _arguments.Count - 1)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return _arguments[_index + 1];
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public CommandLineArgument Previous
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (_index > 0)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return _arguments[_index - 1];
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        internal CommandLineArgument(List<CommandLineArgument> args, int index, string argument)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _arguments = args;
 | 
				
			||||||
 | 
					            _index = index;
 | 
				
			||||||
 | 
					            _argumentText = argument;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public CommandLineArgument Take()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return Next;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IEnumerable<CommandLineArgument> Take(int count)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var list = new List<CommandLineArgument>();
 | 
				
			||||||
 | 
					            var parent = this;
 | 
				
			||||||
 | 
					            for (int i = 0; i < count; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var next = parent.Next;
 | 
				
			||||||
 | 
					                if (next == null)
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                list.Add(next);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                parent = next;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return list;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static implicit operator string(CommandLineArgument argument)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return argument._argumentText;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public override string ToString()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return _argumentText;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										39
									
								
								N_m3u8DL-CLI/CommandLineArgumentParser.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								N_m3u8DL-CLI/CommandLineArgumentParser.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace N_m3u8DL_CLI
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class CommandLineArgumentParser
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        List<CommandLineArgument> _arguments;
 | 
				
			||||||
 | 
					        public static CommandLineArgumentParser Parse(string[] args)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new CommandLineArgumentParser(args);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public CommandLineArgumentParser(string[] args)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _arguments = new List<CommandLineArgument>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for (int i = 0; i < args.Length; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _arguments.Add(new CommandLineArgument(_arguments, i, args[i]));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public CommandLineArgument Get(string argumentName)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return _arguments.FirstOrDefault(p => p == argumentName);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public bool Has(string argumentName)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return _arguments.Count(p => p == argumentName) > 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										318
									
								
								N_m3u8DL-CLI/Decode51CtoKey.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										318
									
								
								N_m3u8DL-CLI/Decode51CtoKey.cs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										41
									
								
								N_m3u8DL-CLI/DecodeDdyun.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								N_m3u8DL-CLI/DecodeDdyun.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					using System.Security.Cryptography;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Text.RegularExpressions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace N_m3u8DL_CLI
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class DecodeDdyun
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public static string DecryptM3u8(byte[] byteArray)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            string tmp = DecodeNfmovies.DecryptM3u8(byteArray);
 | 
				
			||||||
 | 
					            if (tmp.StartsWith("duoduo.key"))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                tmp = Regex.Replace(tmp, @"#EXT-X-BYTERANGE:.*\s", "");
 | 
				
			||||||
 | 
					                tmp = tmp.Replace("https:", "jump/https:")
 | 
				
			||||||
 | 
					                    .Replace("inews.gtimg.com", "puui.qpic.cn");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return tmp;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //https://player.ddyunp.com/jQuery.min.js?v1.5
 | 
				
			||||||
 | 
					        public static string GetVaildM3u8Url(string url)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            //url: https://hls.ddyunp.com/ddyun/id/1/key/playlist.m3u8
 | 
				
			||||||
 | 
					            string id = Regex.Match(url, @"\w{20,}").Value;
 | 
				
			||||||
 | 
					            string tm = Global.GetTimeStamp(false);
 | 
				
			||||||
 | 
					            string t = ((long.Parse(tm) / 0x186a0) * 0x64).ToString();
 | 
				
			||||||
 | 
					            string tmp = id + "duoduo" + "1" + t;
 | 
				
			||||||
 | 
					            MD5 md5 = MD5.Create();
 | 
				
			||||||
 | 
					            byte[] bs = Encoding.UTF8.GetBytes(tmp);
 | 
				
			||||||
 | 
					            byte[] hs = md5.ComputeHash(bs);
 | 
				
			||||||
 | 
					            StringBuilder sb = new StringBuilder();
 | 
				
			||||||
 | 
					            foreach (byte b in hs)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                sb.Append(b.ToString("x2"));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            string key = sb.ToString();
 | 
				
			||||||
 | 
					            return Regex.Replace(url, @"1/\w{20,}", "1/" + key);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										53
									
								
								N_m3u8DL-CLI/DecodeHuke88Key.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								N_m3u8DL-CLI/DecodeHuke88Key.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					using Newtonsoft.Json.Linq;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Security.Cryptography;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Text.RegularExpressions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace N_m3u8DL_CLI
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    //https://js.huke88.com/assets/revision/js/plugins/tcplayer/tcplayer.v4.1.min.js?v=930
 | 
				
			||||||
 | 
					    //https://js.huke88.com/assets/revision/js/plugins/tcplayer/libs/hls.min.0.13.2m.js?v=930
 | 
				
			||||||
 | 
					    class DecodeHuke88Key
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private static string[] GetOverlayInfo(string url)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var enc = new Regex("eyJ\\w{100,}").Match(url).Value;
 | 
				
			||||||
 | 
					            var json = Encoding.UTF8.GetString(Convert.FromBase64String(enc));
 | 
				
			||||||
 | 
					            JObject jObject = JObject.Parse(json);
 | 
				
			||||||
 | 
					            var key = jObject["overlayKey"].ToString();
 | 
				
			||||||
 | 
					            var iv = jObject["overlayIv"].ToString();
 | 
				
			||||||
 | 
					            return new string[] { key, iv };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static string DecodeKey(string url, byte[] data)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var info = GetOverlayInfo(url);
 | 
				
			||||||
 | 
					            var overlayKey = info[0];
 | 
				
			||||||
 | 
					            var overlayIv = info[1];
 | 
				
			||||||
 | 
					            var l = new List<byte>();
 | 
				
			||||||
 | 
					            var c = new List<byte>();
 | 
				
			||||||
 | 
					            for (int h = 0; h < 16; h++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var f = overlayKey.Substring(2 * h, 2);
 | 
				
			||||||
 | 
					                var g = overlayIv.Substring(2 * h, 2);
 | 
				
			||||||
 | 
					                l.Add(Convert.ToByte(f, 16));
 | 
				
			||||||
 | 
					                c.Add(Convert.ToByte(g, 16));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var _lastCipherblock = c.ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var t = new byte[data.Length];
 | 
				
			||||||
 | 
					            var r = data;
 | 
				
			||||||
 | 
					            r = Decrypter.AES128Decrypt(data, l.ToArray(), Decrypter.HexStringToBytes("00000000000000000000000000000000"), CipherMode.CBC, PaddingMode.Zeros);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for (var o = 0; o < 16; o++)
 | 
				
			||||||
 | 
					                t[o] = (byte)(r[o] ^ _lastCipherblock[o]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var key = Convert.ToBase64String(t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return key;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										203
									
								
								N_m3u8DL-CLI/DecodeImooc.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										203
									
								
								N_m3u8DL-CLI/DecodeImooc.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,203 @@
 | 
				
			|||||||
 | 
					using NiL.JS.BaseLibrary;
 | 
				
			||||||
 | 
					using NiL.JS.Core;
 | 
				
			||||||
 | 
					using NiL.JS.Extensions;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using Array = System.Array;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace N_m3u8DL_CLI
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * js代码来自:https://www.imooc.com/static/moco/player/3.0.6.3/mocoplayer.js?v=202006122046
 | 
				
			||||||
 | 
					     * 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    class DecodeImooc
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private static string JS = @"
 | 
				
			||||||
 | 
					function n(t, e) {
 | 
				
			||||||
 | 
					                function r(t, e) {
 | 
				
			||||||
 | 
					                    var r = '';
 | 
				
			||||||
 | 
					                    if ('object' == typeof t)
 | 
				
			||||||
 | 
					                        for (var n = 0; n < t.length; n++)
 | 
				
			||||||
 | 
					                            r += String.fromCharCode(t[n]);
 | 
				
			||||||
 | 
					                    t = r || t;
 | 
				
			||||||
 | 
					                    for (var i, o, a = new Uint8Array(t.length), s = e.length, n = 0; n < t.length; n++)
 | 
				
			||||||
 | 
					                        o = n % s,
 | 
				
			||||||
 | 
					                        i = t[n],
 | 
				
			||||||
 | 
					                        i = i.toString().charCodeAt(0),
 | 
				
			||||||
 | 
					                        a[n] = i ^ e.charCodeAt(o);
 | 
				
			||||||
 | 
					                    return a
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                function n(t) {
 | 
				
			||||||
 | 
					                    var e = '';
 | 
				
			||||||
 | 
					                    if ('object' == typeof t)
 | 
				
			||||||
 | 
					                        for (var r = 0; r < t.length; r++)
 | 
				
			||||||
 | 
					                            e += String.fromCharCode(t[r]);
 | 
				
			||||||
 | 
					                    t = e || t;
 | 
				
			||||||
 | 
					                    var n = new Uint8Array(t.length);
 | 
				
			||||||
 | 
					                    for (r = 0; r < t.length; r++)
 | 
				
			||||||
 | 
					                        n[r] = t[r].toString().charCodeAt(0);
 | 
				
			||||||
 | 
					                    var i, o, r = 0;
 | 
				
			||||||
 | 
					                    for (r = 0; r < n.length; r++)
 | 
				
			||||||
 | 
					                        0 != (i = n[r] % 3) && r + i < n.length && (o = n[r + 1],
 | 
				
			||||||
 | 
					                        n[r + 1] = n[r + i],
 | 
				
			||||||
 | 
					                        n[r + i] = o,
 | 
				
			||||||
 | 
					                        r = r + i + 1);
 | 
				
			||||||
 | 
					                    return n
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                function i(t) {
 | 
				
			||||||
 | 
					                    var e = '';
 | 
				
			||||||
 | 
					                    if ('object' == typeof t)
 | 
				
			||||||
 | 
					                        for (var r = 0; r < t.length; r++)
 | 
				
			||||||
 | 
					                            e += String.fromCharCode(t[r]);
 | 
				
			||||||
 | 
					                    t = e || t;
 | 
				
			||||||
 | 
					                    var n = new Uint8Array(t.length);
 | 
				
			||||||
 | 
					                    for (r = 0; r < t.length; r++)
 | 
				
			||||||
 | 
					                        n[r] = t[r].toString().charCodeAt(0);
 | 
				
			||||||
 | 
					                    var r = 0
 | 
				
			||||||
 | 
					                      , i = 0
 | 
				
			||||||
 | 
					                      , o = 0
 | 
				
			||||||
 | 
					                      , a = 0;
 | 
				
			||||||
 | 
					                    for (r = 0; r < n.length; r++)
 | 
				
			||||||
 | 
					                        o = n[r] % 2,
 | 
				
			||||||
 | 
					                        o && r++,
 | 
				
			||||||
 | 
					                        a++;
 | 
				
			||||||
 | 
					                    var s = new Uint8Array(a);
 | 
				
			||||||
 | 
					                    for (r = 0; r < n.length; r++)
 | 
				
			||||||
 | 
					                        o = n[r] % 2,
 | 
				
			||||||
 | 
					                        s[i++] = o ? n[r++] : n[r];
 | 
				
			||||||
 | 
					                    return s
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                function o(t, e) {
 | 
				
			||||||
 | 
					                    var r = 0
 | 
				
			||||||
 | 
					                      , n = 0
 | 
				
			||||||
 | 
					                      , i = 0
 | 
				
			||||||
 | 
					                      , o = 0
 | 
				
			||||||
 | 
					                      , a = '';
 | 
				
			||||||
 | 
					                    if ('object' == typeof t)
 | 
				
			||||||
 | 
					                        for (var r = 0; r < t.length; r++)
 | 
				
			||||||
 | 
					                            a += String.fromCharCode(t[r]);
 | 
				
			||||||
 | 
					                    t = a || t;
 | 
				
			||||||
 | 
					                    var s = new Uint8Array(t.length);
 | 
				
			||||||
 | 
					                    for (r = 0; r < t.length; r++)
 | 
				
			||||||
 | 
					                        s[r] = t[r].toString().charCodeAt(0);
 | 
				
			||||||
 | 
					                    for (r = 0; r < t.length; r++)
 | 
				
			||||||
 | 
					                        if (0 != (o = s[r] % 5) && 1 != o && r + o < s.length && (i = s[r + 1],
 | 
				
			||||||
 | 
					                        n = r + 2,
 | 
				
			||||||
 | 
					                        s[r + 1] = s[r + o],
 | 
				
			||||||
 | 
					                        s[o + r] = i,
 | 
				
			||||||
 | 
					                        (r = r + o + 1) - 2 > n))
 | 
				
			||||||
 | 
					                            for (; n < r - 2; n++)
 | 
				
			||||||
 | 
					                                s[n] = s[n] ^ e.charCodeAt(n % e.length);
 | 
				
			||||||
 | 
					                    for (r = 0; r < t.length; r++)
 | 
				
			||||||
 | 
					                        s[r] = s[r] ^ e.charCodeAt(r % e.length);
 | 
				
			||||||
 | 
					                    return s
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                for (var a = {
 | 
				
			||||||
 | 
					                    data: {
 | 
				
			||||||
 | 
					                        info: t
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }, s = {
 | 
				
			||||||
 | 
					                    q: r,
 | 
				
			||||||
 | 
					                    h: n,
 | 
				
			||||||
 | 
					                    m: i,
 | 
				
			||||||
 | 
					                    k: o
 | 
				
			||||||
 | 
					                }, l = a.data.info, u = l.substring(l.length - 4).split(''), c = 0; c < u.length; c++)
 | 
				
			||||||
 | 
					                    u[c] = u[c].toString().charCodeAt(0) % 4;
 | 
				
			||||||
 | 
					                u.reverse();
 | 
				
			||||||
 | 
					                for (var d = [], c = 0; c < u.length; c++)
 | 
				
			||||||
 | 
					                    d.push(l.substring(u[c] + 1, u[c] + 2)),
 | 
				
			||||||
 | 
					                    l = l.substring(0, u[c] + 1) + l.substring(u[c] + 2);
 | 
				
			||||||
 | 
					                a.data.encrypt_table = d,
 | 
				
			||||||
 | 
					                a.data.key_table = [];
 | 
				
			||||||
 | 
					                for (var c in a.data.encrypt_table)
 | 
				
			||||||
 | 
					                    'q' != a.data.encrypt_table[c] && 'k' != a.data.encrypt_table[c] || (a.data.key_table.push(l.substring(l.length - 12)),
 | 
				
			||||||
 | 
					                    l = l.substring(0, l.length - 12));
 | 
				
			||||||
 | 
					                a.data.key_table.reverse(),
 | 
				
			||||||
 | 
					                a.data.info = l;
 | 
				
			||||||
 | 
					                var f = new Array(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1);
 | 
				
			||||||
 | 
					                a.data.info = function(t) {
 | 
				
			||||||
 | 
					                    var e, r, n, i, o, a, s;
 | 
				
			||||||
 | 
					                    for (a = t.length,
 | 
				
			||||||
 | 
					                    o = 0,
 | 
				
			||||||
 | 
					                    s = ''; o < a; ) {
 | 
				
			||||||
 | 
					                        do {
 | 
				
			||||||
 | 
					                            e = f[255 & t.charCodeAt(o++)]
 | 
				
			||||||
 | 
					                        } while (o < a && -1 == e);if (-1 == e)
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        do {
 | 
				
			||||||
 | 
					                            r = f[255 & t.charCodeAt(o++)]
 | 
				
			||||||
 | 
					                        } while (o < a && -1 == r);if (-1 == r)
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        s += String.fromCharCode(e << 2 | (48 & r) >> 4);
 | 
				
			||||||
 | 
					                        do {
 | 
				
			||||||
 | 
					                            if (61 == (n = 255 & t.charCodeAt(o++)))
 | 
				
			||||||
 | 
					                                return s;
 | 
				
			||||||
 | 
					                            n = f[n]
 | 
				
			||||||
 | 
					                        } while (o < a && -1 == n);if (-1 == n)
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        s += String.fromCharCode((15 & r) << 4 | (60 & n) >> 2);
 | 
				
			||||||
 | 
					                        do {
 | 
				
			||||||
 | 
					                            if (61 == (i = 255 & t.charCodeAt(o++)))
 | 
				
			||||||
 | 
					                                return s;
 | 
				
			||||||
 | 
					                            i = f[i]
 | 
				
			||||||
 | 
					                        } while (o < a && -1 == i);if (-1 == i)
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        s += String.fromCharCode((3 & n) << 6 | i)
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    return s
 | 
				
			||||||
 | 
					                }(a.data.info);
 | 
				
			||||||
 | 
					                for (var c in a.data.encrypt_table) {
 | 
				
			||||||
 | 
					                    var h = a.data.encrypt_table[c];
 | 
				
			||||||
 | 
					                    if ('q' == h || 'k' == h) {
 | 
				
			||||||
 | 
					                        var p = a.data.key_table.pop();
 | 
				
			||||||
 | 
					                        a.data.info = s[a.data.encrypt_table[c]](a.data.info, p)
 | 
				
			||||||
 | 
					                    } else
 | 
				
			||||||
 | 
					                        a.data.info = s[a.data.encrypt_table[c]](a.data.info)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (e)
 | 
				
			||||||
 | 
					                    return a.data.info;
 | 
				
			||||||
 | 
					                var g = '';
 | 
				
			||||||
 | 
					                for (c = 0; c < a.data.info.length; c++)
 | 
				
			||||||
 | 
					                    g += String.fromCharCode(a.data.info[c]);
 | 
				
			||||||
 | 
					                return g
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            function Uint8ArrayToString(fileData){
 | 
				
			||||||
 | 
					              var dataString = '';
 | 
				
			||||||
 | 
					              for (var i = 0; i < fileData.length; i++) {
 | 
				
			||||||
 | 
					                dataString += Number(fileData[i]) + ',';
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					              return dataString;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            function decodeKey(resp){
 | 
				
			||||||
 | 
					                var string = eval('('+resp+')');
 | 
				
			||||||
 | 
					                //return btoa(String.fromCharCode.apply(null, new Uint8Array(n(string.data.info, 1))));
 | 
				
			||||||
 | 
					                return Uint8ArrayToString(new Uint8Array(n(string.data.info, 1)));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            function decodeM3u8(resp){
 | 
				
			||||||
 | 
					                var string = eval('('+resp+')');
 | 
				
			||||||
 | 
					                return n(string.data.info);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            ";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static string DecodeM3u8(string resp)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var context = new Context();
 | 
				
			||||||
 | 
					            context.Eval(JS);
 | 
				
			||||||
 | 
					            var concatFunction = context.GetVariable("decodeM3u8").As<Function>();
 | 
				
			||||||
 | 
					            string m3u8 = concatFunction.Call(new Arguments { resp }).ToString();
 | 
				
			||||||
 | 
					            return m3u8;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static string DecodeKey(string resp)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var context = new Context();
 | 
				
			||||||
 | 
					            context.Eval(JS);
 | 
				
			||||||
 | 
					            var concatFunction = context.GetVariable("decodeKey").As<Function>();
 | 
				
			||||||
 | 
					            string key = concatFunction.Call(new Arguments { resp }).ToString();
 | 
				
			||||||
 | 
					            byte[] v = Array.ConvertAll(key.Trim(',').Split(','), s => (byte)int.Parse(s));
 | 
				
			||||||
 | 
					            string realKey = Convert.ToBase64String(v);
 | 
				
			||||||
 | 
					            return realKey;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										36
									
								
								N_m3u8DL-CLI/DecodeNfmovies.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								N_m3u8DL-CLI/DecodeNfmovies.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace N_m3u8DL_CLI
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class DecodeNfmovies
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        //https://jx.nfmovies.com/hls.min.js
 | 
				
			||||||
 | 
					        public static string DecryptM3u8(byte[] byteArray)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var t = byteArray;
 | 
				
			||||||
 | 
					            var decrypt = "";
 | 
				
			||||||
 | 
					            if (137 == t[0] && 80 == t[1] && 130 == t[354] && 96 == t[353]) t = t.Skip(355).ToArray();
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (137 != t[0] || 80 != t[1] || 130 != t[394] || 96 != t[393])
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    for (var i = 0; i < t.Length; i++) decrypt += Convert.ToChar(t[i]);
 | 
				
			||||||
 | 
					                    return decrypt;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                t = t.Skip(395).ToArray();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            using (var zipStream =
 | 
				
			||||||
 | 
					                new System.IO.Compression.GZipStream(new MemoryStream(t), System.IO.Compression.CompressionMode.Decompress))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                using (StreamReader sr = new StreamReader(zipStream, Encoding.UTF8))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    decrypt = sr.ReadToEnd();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return decrypt;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										78
									
								
								N_m3u8DL-CLI/Decrypter.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								N_m3u8DL-CLI/Decrypter.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					using System.Security.Cryptography;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace N_m3u8DL_CLI
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class Decrypter
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public static byte[] AES128Decrypt(string filePath, byte[] keyByte, byte[] ivByte, CipherMode mode = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            FileStream fs = new FileStream(filePath, FileMode.Open);
 | 
				
			||||||
 | 
					            //获取文件大小
 | 
				
			||||||
 | 
					            long size = fs.Length;
 | 
				
			||||||
 | 
					            byte[] inBuff = new byte[size];
 | 
				
			||||||
 | 
					            fs.Read(inBuff, 0, inBuff.Length);
 | 
				
			||||||
 | 
					            fs.Close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Aes dcpt = Aes.Create();
 | 
				
			||||||
 | 
					            dcpt.BlockSize = 128;
 | 
				
			||||||
 | 
					            dcpt.KeySize = 128;
 | 
				
			||||||
 | 
					            dcpt.Key = keyByte;
 | 
				
			||||||
 | 
					            dcpt.IV = ivByte;
 | 
				
			||||||
 | 
					            dcpt.Mode = mode;
 | 
				
			||||||
 | 
					            dcpt.Padding = padding;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ICryptoTransform cTransform = dcpt.CreateDecryptor();
 | 
				
			||||||
 | 
					            Byte[] resultArray = cTransform.TransformFinalBlock(inBuff, 0, inBuff.Length);
 | 
				
			||||||
 | 
					            return resultArray;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static byte[] AES128Decrypt(byte[] encryptedBuff, byte[] keyByte, byte[] ivByte, CipherMode mode = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            byte[] inBuff = encryptedBuff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Aes dcpt = Aes.Create();
 | 
				
			||||||
 | 
					            dcpt.BlockSize = 128;
 | 
				
			||||||
 | 
					            dcpt.KeySize = 128;
 | 
				
			||||||
 | 
					            dcpt.Key = keyByte;
 | 
				
			||||||
 | 
					            dcpt.IV = ivByte;
 | 
				
			||||||
 | 
					            dcpt.Mode = mode;
 | 
				
			||||||
 | 
					            dcpt.Padding = padding;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ICryptoTransform cTransform = dcpt.CreateDecryptor();
 | 
				
			||||||
 | 
					            Byte[] resultArray = cTransform.TransformFinalBlock(inBuff, 0, inBuff.Length);
 | 
				
			||||||
 | 
					            return resultArray;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static byte[] HexStringToBytes(string hexStr)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (string.IsNullOrEmpty(hexStr))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return new byte[0];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (hexStr.StartsWith("0x") || hexStr.StartsWith("0X"))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                hexStr = hexStr.Remove(0, 2);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int count = hexStr.Length;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (count % 2 == 1)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new ArgumentException("Invalid length of bytes:" + count);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int byteCount = count / 2;
 | 
				
			||||||
 | 
					            byte[] result = new byte[byteCount];
 | 
				
			||||||
 | 
					            for (int ii = 0; ii < byteCount; ++ii)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var tempBytes = Byte.Parse(hexStr.Substring(2 * ii, 2), System.Globalization.NumberStyles.HexNumber);
 | 
				
			||||||
 | 
					                result[ii] = tempBytes;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return result;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										664
									
								
								N_m3u8DL-CLI/DownloadManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										664
									
								
								N_m3u8DL-CLI/DownloadManager.cs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										252
									
								
								N_m3u8DL-CLI/Downloader.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										252
									
								
								N_m3u8DL-CLI/Downloader.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,252 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.ComponentModel;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Net;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace N_m3u8DL_CLI
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class Downloader
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private int timeOut = 0;
 | 
				
			||||||
 | 
					        private int retry = 5;
 | 
				
			||||||
 | 
					        private int count = 0;
 | 
				
			||||||
 | 
					        private int segIndex = 0;
 | 
				
			||||||
 | 
					        private double segDur = 0;
 | 
				
			||||||
 | 
					        private string fileUrl = string.Empty;
 | 
				
			||||||
 | 
					        private string savePath = string.Empty;
 | 
				
			||||||
 | 
					        private string headers = string.Empty;
 | 
				
			||||||
 | 
					        private string method = string.Empty;
 | 
				
			||||||
 | 
					        private string key = string.Empty;
 | 
				
			||||||
 | 
					        private string iv = string.Empty;
 | 
				
			||||||
 | 
					        private string liveFile = string.Empty;
 | 
				
			||||||
 | 
					        private long expectByte = -1;
 | 
				
			||||||
 | 
					        private long startByte = 0;
 | 
				
			||||||
 | 
					        private bool isLive = false;
 | 
				
			||||||
 | 
					        private bool isDone = false;
 | 
				
			||||||
 | 
					        private bool firstSeg = true;
 | 
				
			||||||
 | 
					        private FileStream liveStream = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string FileUrl { get => fileUrl; set => fileUrl = value; }
 | 
				
			||||||
 | 
					        public string SavePath { get => savePath; set => savePath = value; }
 | 
				
			||||||
 | 
					        public string Headers { get => headers; set => headers = value; }
 | 
				
			||||||
 | 
					        public string Method { get => method; set => method = value; }
 | 
				
			||||||
 | 
					        public string Key { get => key; set => key = value; }
 | 
				
			||||||
 | 
					        public string Iv { get => iv; set => iv = value; }
 | 
				
			||||||
 | 
					        public bool IsLive { get => isLive; set => isLive = value; }
 | 
				
			||||||
 | 
					        public int Retry { get => retry; set => retry = value; }
 | 
				
			||||||
 | 
					        public bool IsDone { get => isDone; set => isDone = value; }
 | 
				
			||||||
 | 
					        public int SegIndex { get => segIndex; set => segIndex = value; }
 | 
				
			||||||
 | 
					        public int TimeOut { get => timeOut; set => timeOut = value; }
 | 
				
			||||||
 | 
					        public FileStream LiveStream { get => liveStream; set => liveStream = value; }
 | 
				
			||||||
 | 
					        public string LiveFile { get => liveFile; set => liveFile = value; }
 | 
				
			||||||
 | 
					        public long ExpectByte { get => expectByte; set => expectByte = value; }
 | 
				
			||||||
 | 
					        public long StartByte { get => startByte; set => startByte = value; }
 | 
				
			||||||
 | 
					        public double SegDur { get => segDur; set => segDur = value; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //重写WebClinet
 | 
				
			||||||
 | 
					        //private class WebClient : System.Net.WebClient
 | 
				
			||||||
 | 
					        //{
 | 
				
			||||||
 | 
					        //    protected override WebRequest GetWebRequest(Uri uri)
 | 
				
			||||||
 | 
					        //    {
 | 
				
			||||||
 | 
					        //        WebRequest lWebRequest = base.GetWebRequest(uri);
 | 
				
			||||||
 | 
					        //        lWebRequest.Timeout = TimeOut;
 | 
				
			||||||
 | 
					        //        ((HttpWebRequest)lWebRequest).ReadWriteTimeout = TimeOut;
 | 
				
			||||||
 | 
					        //        return lWebRequest;
 | 
				
			||||||
 | 
					        //    }
 | 
				
			||||||
 | 
					        //}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //WebClient client = new WebClient();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Down()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                //直播下载
 | 
				
			||||||
 | 
					                if (IsLive)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    IsDone = false;  //设置为未完成下载
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (Method == "NONE" || method.Contains("NOTSUPPORTED")) 
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        LOGGER.PrintLine("<" + SegIndex + " Downloading>");
 | 
				
			||||||
 | 
					                        LOGGER.WriteLine("<" + SegIndex + " Downloading>");
 | 
				
			||||||
 | 
					                        byte[] segBuff = Global.HttpDownloadFileToBytes(fileUrl, Headers, TimeOut);
 | 
				
			||||||
 | 
					                        //byte[] segBuff = Global.WebClientDownloadToBytes(fileUrl, Headers);
 | 
				
			||||||
 | 
					                        Global.AppendBytesToFileStreamAndDoNotClose(LiveStream, segBuff);
 | 
				
			||||||
 | 
					                        LOGGER.PrintLine("<" + SegIndex + " Complete>\r\n");
 | 
				
			||||||
 | 
					                        LOGGER.WriteLine("<" + SegIndex + " Complete>");
 | 
				
			||||||
 | 
					                        IsDone = true;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else if (Method == "AES-128")
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        LOGGER.PrintLine("<" + SegIndex + " Downloading>");
 | 
				
			||||||
 | 
					                        LOGGER.WriteLine("<" + SegIndex + " Downloading>");
 | 
				
			||||||
 | 
					                        byte[] encryptedBuff = Global.HttpDownloadFileToBytes(fileUrl, Headers, TimeOut);
 | 
				
			||||||
 | 
					                        //byte[] encryptedBuff = Global.WebClientDownloadToBytes(fileUrl, Headers);
 | 
				
			||||||
 | 
					                        byte[] decryptBuff = null;
 | 
				
			||||||
 | 
					                        decryptBuff = Decrypter.AES128Decrypt(
 | 
				
			||||||
 | 
					                            encryptedBuff,
 | 
				
			||||||
 | 
					                            Convert.FromBase64String(Key),
 | 
				
			||||||
 | 
					                            Decrypter.HexStringToBytes(Iv)
 | 
				
			||||||
 | 
					                            );
 | 
				
			||||||
 | 
					                        Global.AppendBytesToFileStreamAndDoNotClose(LiveStream, decryptBuff);
 | 
				
			||||||
 | 
					                        LOGGER.PrintLine("<" + SegIndex + " Complete>\r\n");
 | 
				
			||||||
 | 
					                        LOGGER.WriteLine("<" + SegIndex + " Complete>");
 | 
				
			||||||
 | 
					                        IsDone = true;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        //LOGGER.PrintLine("不支持这种加密方式!", LOGGER.Error);
 | 
				
			||||||
 | 
					                        IsDone = true;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    if (firstSeg && Global.FileSize(LiveFile) != 0)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        //LOGGER.STOPLOG = false;  //记录日志
 | 
				
			||||||
 | 
					                        foreach (string ss in (string[])Global.GetVideoInfo(LiveFile).ToArray(typeof(string)))
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            LOGGER.WriteLine(ss.Trim());
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        firstSeg = false;
 | 
				
			||||||
 | 
					                        //LOGGER.STOPLOG = true;  //停止记录日志
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    HLSLiveDownloader.REC_DUR += SegDur;
 | 
				
			||||||
 | 
					                    if (HLSLiveDownloader.REC_DUR_LIMIT != -1 && HLSLiveDownloader.REC_DUR >= HLSLiveDownloader.REC_DUR_LIMIT) 
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        LOGGER.PrintLine(strings.recordLimitReached, LOGGER.Warning);
 | 
				
			||||||
 | 
					                        LOGGER.WriteLine(strings.recordLimitReached);
 | 
				
			||||||
 | 
					                        Environment.Exit(0); //正常退出
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                //点播下载
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (!Directory.Exists(Path.GetDirectoryName(SavePath)))
 | 
				
			||||||
 | 
					                        Directory.CreateDirectory(Path.GetDirectoryName(SavePath)); //新建文件夹  
 | 
				
			||||||
 | 
					                    //是否存在文件,存在则不下载
 | 
				
			||||||
 | 
					                    if (File.Exists(Path.GetDirectoryName(savePath) + "\\" + Path.GetFileNameWithoutExtension(savePath) + ".ts"))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        Global.BYTEDOWN++; //防止被速度监控程序杀死
 | 
				
			||||||
 | 
					                        //Console.WriteLine("Exists " + Path.GetFileNameWithoutExtension(savePath) + ".ts");
 | 
				
			||||||
 | 
					                        return;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    //Console.WriteLine("开始下载 " + fileUrl);
 | 
				
			||||||
 | 
					                    //本地文件
 | 
				
			||||||
 | 
					                    if (fileUrl.StartsWith("file:"))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        Uri t = new Uri(fileUrl);
 | 
				
			||||||
 | 
					                        fileUrl = t.LocalPath;
 | 
				
			||||||
 | 
					                        if (File.Exists(fileUrl))
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            if (ExpectByte == -1)  //没有RANGE
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                FileInfo fi = new FileInfo(fileUrl);
 | 
				
			||||||
 | 
					                                fi.CopyTo(savePath);
 | 
				
			||||||
 | 
					                                Global.BYTEDOWN += fi.Length;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            else
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                FileStream stream = new FileInfo(fileUrl).OpenRead();
 | 
				
			||||||
 | 
					                                //seek文件
 | 
				
			||||||
 | 
					                                stream.Seek(StartByte, SeekOrigin.Begin);
 | 
				
			||||||
 | 
					                                Byte[] buffer = new Byte[ExpectByte];
 | 
				
			||||||
 | 
					                                //从流中读取字节块并将该数据写入给定缓冲区buffer中
 | 
				
			||||||
 | 
					                                stream.Read(buffer, 0, Convert.ToInt32(buffer.Length));
 | 
				
			||||||
 | 
					                                stream.Close();
 | 
				
			||||||
 | 
					                                //写出文件
 | 
				
			||||||
 | 
					                                MemoryStream m = new MemoryStream(buffer);
 | 
				
			||||||
 | 
					                                FileStream fs = new FileStream(savePath, FileMode.OpenOrCreate);
 | 
				
			||||||
 | 
					                                m.WriteTo(fs);
 | 
				
			||||||
 | 
					                                m.Close();
 | 
				
			||||||
 | 
					                                fs.Close();
 | 
				
			||||||
 | 
					                                m = null;
 | 
				
			||||||
 | 
					                                fs = null;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        //下载
 | 
				
			||||||
 | 
					                        Global.HttpDownloadFile(fileUrl, savePath, TimeOut, Headers, StartByte, ExpectByte);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (File.Exists(savePath) && Global.ShouldStop == false) 
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    FileInfo fi = new FileInfo(savePath);
 | 
				
			||||||
 | 
					                    if (Method == "NONE" || method.Contains("NOTSUPPORTED"))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        fi.MoveTo(Path.GetDirectoryName(savePath) + "\\" + Path.GetFileNameWithoutExtension(savePath) + ".ts");
 | 
				
			||||||
 | 
					                        DownloadManager.DownloadedSize += fi.Length;
 | 
				
			||||||
 | 
					                        //Console.WriteLine(Path.GetFileNameWithoutExtension(savePath) + " Completed.");
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else if (File.Exists(fi.FullName)
 | 
				
			||||||
 | 
					                        && Method == "AES-128") 
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        //解密
 | 
				
			||||||
 | 
					                        try
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            byte[] decryptBuff = null;
 | 
				
			||||||
 | 
					                            if(fileUrl.Contains(".51cto.com/")) //使用AES-128-ECB模式解密
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                decryptBuff = Decrypter.AES128Decrypt(
 | 
				
			||||||
 | 
					                                    fi.FullName,
 | 
				
			||||||
 | 
					                                    Convert.FromBase64String(Key),
 | 
				
			||||||
 | 
					                                    Decrypter.HexStringToBytes(Iv),
 | 
				
			||||||
 | 
					                                    System.Security.Cryptography.CipherMode.ECB
 | 
				
			||||||
 | 
					                                    );
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            else
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                decryptBuff = Decrypter.AES128Decrypt(
 | 
				
			||||||
 | 
					                                    fi.FullName,
 | 
				
			||||||
 | 
					                                    Convert.FromBase64String(Key),
 | 
				
			||||||
 | 
					                                    Decrypter.HexStringToBytes(Iv)
 | 
				
			||||||
 | 
					                                    );
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            FileStream fs = new FileStream(Path.GetDirectoryName(savePath) + "\\" + Path.GetFileNameWithoutExtension(savePath) + ".ts", FileMode.Create);
 | 
				
			||||||
 | 
					                            fs.Write(decryptBuff, 0, decryptBuff.Length);
 | 
				
			||||||
 | 
					                            fs.Close();
 | 
				
			||||||
 | 
					                            DownloadManager.DownloadedSize += fi.Length;
 | 
				
			||||||
 | 
					                            fi.Delete();
 | 
				
			||||||
 | 
					                            //Console.WriteLine(Path.GetFileNameWithoutExtension(savePath) + " Completed & Decrypted.");
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        catch (Exception ex)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            LOGGER.PrintLine(ex.Message, LOGGER.Error);
 | 
				
			||||||
 | 
					                            LOGGER.WriteLineError(ex.Message);
 | 
				
			||||||
 | 
					                            Thread.Sleep(3000);
 | 
				
			||||||
 | 
					                            Environment.Exit(-1);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        LOGGER.WriteLineError(strings.SomethingWasWrong);
 | 
				
			||||||
 | 
					                        LOGGER.PrintLine(strings.SomethingWasWrong, LOGGER.Error);
 | 
				
			||||||
 | 
					                        return;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                LOGGER.WriteLineError(ex.Message);
 | 
				
			||||||
 | 
					                if (ex.Message.Contains("404") || ex.Message.Contains("400"))//(400) 错误的请求,片段过期会提示400错误
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    IsDone = true;
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else if (IsLive && count++ < Retry) 
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    Thread.Sleep(2000);//直播一般3-6秒一个片段
 | 
				
			||||||
 | 
					                    Down();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										177
									
								
								N_m3u8DL-CLI/FFmpeg.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								N_m3u8DL-CLI/FFmpeg.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,177 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Diagnostics;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace N_m3u8DL_CLI
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class FFmpeg
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public static string FFMPEG_PATH = "ffmpeg";
 | 
				
			||||||
 | 
					        public static string REC_TIME = ""; //录制日期
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static string OutPutPath { get; set; } = string.Empty;
 | 
				
			||||||
 | 
					        public static string ReportFile { get; set; } = string.Empty;
 | 
				
			||||||
 | 
					        public static bool UseAACFilter { get; set; } = false;  //是否启用滤镜
 | 
				
			||||||
 | 
					        public static bool WriteDate { get; set; } = true;  //是否写入录制日期
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static void Merge(string[] files, string muxFormat, bool fastStart,
 | 
				
			||||||
 | 
					            string poster = "", string audioName = "", string title = "",
 | 
				
			||||||
 | 
					            string copyright = "", string comment = "", string encodingTool = "")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            string dateString = string.IsNullOrEmpty(REC_TIME) ? DateTime.Now.ToString("o") : REC_TIME;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //同名文件已存在的共存策略
 | 
				
			||||||
 | 
					            if (File.Exists($"{OutPutPath}.{muxFormat.ToLower()}")) 
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                OutPutPath = Path.Combine(Path.GetDirectoryName(OutPutPath),
 | 
				
			||||||
 | 
					                    Path.GetFileName(OutPutPath) + "_" + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            string command = "-loglevel warning -i concat:\"";
 | 
				
			||||||
 | 
					            string data = string.Empty;
 | 
				
			||||||
 | 
					            string ddpAudio = string.Empty;
 | 
				
			||||||
 | 
					            string addPoster = "-map 1 -c:v:1 copy -disposition:v:1 attached_pic";
 | 
				
			||||||
 | 
					            ddpAudio = (File.Exists($"{Path.GetFileNameWithoutExtension(OutPutPath + ".mp4")}.txt") ? File.ReadAllText($"{Path.GetFileNameWithoutExtension(OutPutPath + ".mp4")}.txt") : "") ;
 | 
				
			||||||
 | 
					            if (!string.IsNullOrEmpty(ddpAudio)) UseAACFilter = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            foreach (string t in files)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                command += Path.GetFileName(t) + "|";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            switch (muxFormat.ToUpper())
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                case ("MP4"):
 | 
				
			||||||
 | 
					                    command += "\" " + (string.IsNullOrEmpty(poster) ? "" : "-i \"" + poster + "\"");
 | 
				
			||||||
 | 
					                    command += " " + (string.IsNullOrEmpty(ddpAudio) ? "" : "-i \"" + ddpAudio + "\"");
 | 
				
			||||||
 | 
					                    command +=
 | 
				
			||||||
 | 
					                        $" -map 0:v? {(string.IsNullOrEmpty(ddpAudio) ? "-map 0:a?" : $"-map {(string.IsNullOrEmpty(poster) ? "1" : "2")}:a -map 0:a?")} -map 0:s? " + (string.IsNullOrEmpty(poster) ? "" : addPoster)
 | 
				
			||||||
 | 
					                        + (WriteDate ? " -metadata date=\"" + dateString + "\"" : "") +
 | 
				
			||||||
 | 
					                        " -metadata encoding_tool=\"" + encodingTool + "\" -metadata title=\"" + title +
 | 
				
			||||||
 | 
					                        "\" -metadata copyright=\"" + copyright + "\" -metadata comment=\"" + comment +
 | 
				
			||||||
 | 
					                        $"\" -metadata:s:a:{(string.IsNullOrEmpty(ddpAudio) ? "0" : "1")} handler_name=\"" + audioName + $"\" -metadata:s:a:{(string.IsNullOrEmpty(ddpAudio) ? "0" : "1")} handler=\"" + audioName + "\" ";
 | 
				
			||||||
 | 
					                    command += (string.IsNullOrEmpty(ddpAudio) ? "" : " -metadata:s:a:0 handler_name=\"DD+\" -metadata:s:a:0 handler=\"DD+\" ");
 | 
				
			||||||
 | 
					                    if (fastStart)
 | 
				
			||||||
 | 
					                        command += "-movflags +faststart";
 | 
				
			||||||
 | 
					                    command += "  -c copy -y " + (UseAACFilter ? "-bsf:a aac_adtstoasc" : "") + " \"" + OutPutPath + ".mp4\"";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case ("MKV"):
 | 
				
			||||||
 | 
					                    command += "\" -map 0  -c copy -y " + (UseAACFilter ? "-bsf:a aac_adtstoasc" : "") + " \"" + OutPutPath + ".mkv\"";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case ("FLV"):
 | 
				
			||||||
 | 
					                    command += "\" -map 0  -c copy -y " + (UseAACFilter ? "-bsf:a aac_adtstoasc" : "") + " \"" + OutPutPath + ".flv\"";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case ("TS"):
 | 
				
			||||||
 | 
					                    command += "\" -map 0  -c copy -y -f mpegts -bsf:v h264_mp4toannexb \"" + OutPutPath + ".ts\"";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case ("VTT"):
 | 
				
			||||||
 | 
					                    command += "\" -map 0  -y \"" + OutPutPath + ".srt\"";  //Convert To Srt
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case ("EAC3"):
 | 
				
			||||||
 | 
					                    command += "\" -map 0:a -c copy -y \"" + OutPutPath + ".eac3\"";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case ("AAC"):
 | 
				
			||||||
 | 
					                    command += "\" -map 0:a -c copy -y \"" + OutPutPath + ".m4a\"";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case ("AC3"):
 | 
				
			||||||
 | 
					                    command += "\" -map 0:a -c copy -y \"" + OutPutPath + ".ac3\"";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Run(FFMPEG_PATH, command, Path.GetDirectoryName(files[0]));
 | 
				
			||||||
 | 
					            LOGGER.WriteLine(strings.ffmpegDone);
 | 
				
			||||||
 | 
					            //Console.WriteLine(command);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static void ConvertToMPEGTS(string file)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (Global.VIDEO_TYPE == "H264")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Run(FFMPEG_PATH,
 | 
				
			||||||
 | 
					                    "-loglevel quiet -i \"" + file + "\" -map 0 -c copy -copy_unknown -f mpegts -bsf:v h264_mp4toannexb \""
 | 
				
			||||||
 | 
					                    + Path.GetFileNameWithoutExtension(file) + "[MPEGTS].ts\"", 
 | 
				
			||||||
 | 
					                    Path.GetDirectoryName(file));
 | 
				
			||||||
 | 
					                if (File.Exists(Path.GetDirectoryName(file) + "\\" + Path.GetFileNameWithoutExtension(file) + "[MPEGTS].ts"))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    File.Delete(file);
 | 
				
			||||||
 | 
					                    File.Move(Path.GetDirectoryName(file) + "\\" + Path.GetFileNameWithoutExtension(file) + "[MPEGTS].ts", file);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else if (Global.VIDEO_TYPE == "H265")
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Run(FFMPEG_PATH,
 | 
				
			||||||
 | 
					                    "-loglevel quiet -i \"" + file + "\" -map 0 -c copy -copy_unknown -f mpegts -bsf:v hevc_mp4toannexb \""
 | 
				
			||||||
 | 
					                    + Path.GetFileNameWithoutExtension(file) + "[MPEGTS].ts\"",
 | 
				
			||||||
 | 
					                    Path.GetDirectoryName(file));
 | 
				
			||||||
 | 
					                if (File.Exists(Path.GetDirectoryName(file) + "\\" + Path.GetFileNameWithoutExtension(file) + "[MPEGTS].ts"))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    File.Delete(file);
 | 
				
			||||||
 | 
					                    File.Move(Path.GetDirectoryName(file) + "\\" + Path.GetFileNameWithoutExtension(file) + "[MPEGTS].ts", file);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                LOGGER.WriteLineError("Unkown Video Type");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static void Run(string path, string args, string workDir)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            string nowDir = Directory.GetCurrentDirectory();  //当前工作路径
 | 
				
			||||||
 | 
					            Directory.SetCurrentDirectory(workDir);
 | 
				
			||||||
 | 
					            Process p = new Process();//建立外部调用线程
 | 
				
			||||||
 | 
					            p.StartInfo.FileName = path;//要调用外部程序的绝对路径
 | 
				
			||||||
 | 
					            Environment.SetEnvironmentVariable("FFREPORT", "file=" + ReportFile + ":level=32"); //兼容XP系统
 | 
				
			||||||
 | 
					            //p.StartInfo.Environment.Add("FFREPORT", "file=" + ReportFile + ":level=32");
 | 
				
			||||||
 | 
					            p.StartInfo.Arguments = args;//参数(这里就是FFMPEG的参数了)
 | 
				
			||||||
 | 
					            p.StartInfo.UseShellExecute = false;//不使用操作系统外壳程序启动线程(一定为FALSE,详细的请看MSDN)
 | 
				
			||||||
 | 
					            p.StartInfo.RedirectStandardError = true;//把外部程序错误输出写到StandardError流中(这个一定要注意,FFMPEG的所有输出信息,都为错误输出流,用StandardOutput是捕获不到任何消息的...这是我耗费了2个多月得出来的经验...mencoder就是用standardOutput来捕获的)
 | 
				
			||||||
 | 
					            p.StartInfo.CreateNoWindow = false;//不创建进程窗口
 | 
				
			||||||
 | 
					            p.ErrorDataReceived += new DataReceivedEventHandler(Output);//外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDN
 | 
				
			||||||
 | 
					            p.StartInfo.StandardErrorEncoding = Encoding.UTF8;
 | 
				
			||||||
 | 
					            p.Start();//启动线程
 | 
				
			||||||
 | 
					            p.BeginErrorReadLine();//开始异步读取
 | 
				
			||||||
 | 
					            p.WaitForExit();//阻塞等待进程结束
 | 
				
			||||||
 | 
					            p.Close();//关闭进程
 | 
				
			||||||
 | 
					            p.Dispose();//释放资源
 | 
				
			||||||
 | 
					            Environment.SetEnvironmentVariable("FFREPORT", null); //兼容XP系统
 | 
				
			||||||
 | 
					            Directory.SetCurrentDirectory(nowDir);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static void Output(object sendProcess, DataReceivedEventArgs output)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (!String.IsNullOrEmpty(output.Data))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                LOGGER.PrintLine(output.Data, LOGGER.Warning);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static bool CheckMPEGTS(string file)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            //放行杜比视界或纯音频文件
 | 
				
			||||||
 | 
					            if (Global.VIDEO_TYPE == "DV" || Global.AUDIO_TYPE != "")
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            //如果是多分片,也认为不是MPEGTS
 | 
				
			||||||
 | 
					            if (DownloadManager.PartsCount > 1)
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read)) 
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                byte[] firstByte = new byte[1];
 | 
				
			||||||
 | 
					                fs.Read(firstByte, 0, 1);
 | 
				
			||||||
 | 
					                //第一字节的16进制字符串
 | 
				
			||||||
 | 
					                string _1_byte_str = Convert.ToString(firstByte[0], 16);
 | 
				
			||||||
 | 
					                //syncword不为47就不处理
 | 
				
			||||||
 | 
					                if (_1_byte_str != "47")
 | 
				
			||||||
 | 
					                    return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1222
									
								
								N_m3u8DL-CLI/Global.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1222
									
								
								N_m3u8DL-CLI/Global.cs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										153
									
								
								N_m3u8DL-CLI/HLSLiveDownloader.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								N_m3u8DL-CLI/HLSLiveDownloader.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,153 @@
 | 
				
			|||||||
 | 
					using Newtonsoft.Json.Linq;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading;
 | 
				
			||||||
 | 
					using System.Timers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace N_m3u8DL_CLI
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class HLSLiveDownloader
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public static int REC_DUR_LIMIT = -1; //默认不限制录制时长
 | 
				
			||||||
 | 
					        public static double REC_DUR = 0; //已录制时长
 | 
				
			||||||
 | 
					        private string liveFile = string.Empty;
 | 
				
			||||||
 | 
					        private string jsonFile = string.Empty;
 | 
				
			||||||
 | 
					        private string headers = string.Empty;
 | 
				
			||||||
 | 
					        private string downDir = string.Empty;
 | 
				
			||||||
 | 
					        private FileStream liveStream = null;
 | 
				
			||||||
 | 
					        private double targetduration = 10;
 | 
				
			||||||
 | 
					        private bool isFirstJson = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public double TotalDuration { get; set; }
 | 
				
			||||||
 | 
					        public string Headers { get => headers; set => headers = value; }
 | 
				
			||||||
 | 
					        public string DownDir { get => downDir; set => downDir = value; }
 | 
				
			||||||
 | 
					        public FileStream LiveStream { get => liveStream; set => liveStream = value; }
 | 
				
			||||||
 | 
					        public string LiveFile { get => liveFile; set => liveFile = value; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ArrayList toDownList = new ArrayList();  //所有待下载的列表
 | 
				
			||||||
 | 
					        System.Timers.Timer timer = new System.Timers.Timer();
 | 
				
			||||||
 | 
					        Downloader sd = new Downloader();  //只有一个实例
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void TimerStart()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            timer.Enabled = true;
 | 
				
			||||||
 | 
					            //timer.Interval = (targetduration - 2) * 1000; //执行间隔时间,单位为毫秒
 | 
				
			||||||
 | 
					            timer.Start();
 | 
				
			||||||
 | 
					            timer.Elapsed += new ElapsedEventHandler(UpdateList);
 | 
				
			||||||
 | 
					            UpdateList(timer, new EventArgs());  //立即执行一次
 | 
				
			||||||
 | 
					            Record();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void TimerStop()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            timer.Stop();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //更新列表
 | 
				
			||||||
 | 
					        private void UpdateList(object source, EventArgs e)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            jsonFile = Path.Combine(DownDir, "meta.json");
 | 
				
			||||||
 | 
					            if (!File.Exists(jsonFile)) 
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                TimerStop();
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            string jsonContent = File.ReadAllText(jsonFile);
 | 
				
			||||||
 | 
					            JObject initJson = JObject.Parse(jsonContent);
 | 
				
			||||||
 | 
					            string m3u8Url = initJson["m3u8"].Value<string>();
 | 
				
			||||||
 | 
					            targetduration = initJson["m3u8Info"]["targetDuration"].Value<double>();
 | 
				
			||||||
 | 
					            TotalDuration = initJson["m3u8Info"]["totalDuration"].Value<double>();
 | 
				
			||||||
 | 
					            timer.Interval = (TotalDuration - targetduration) * 1000;//设置定时器运行间隔
 | 
				
			||||||
 | 
					            JArray lastSegments = JArray.Parse(initJson["m3u8Info"]["segments"][0].ToString().Trim());  //上次的分段,用于比对新分段
 | 
				
			||||||
 | 
					            ArrayList tempList = new ArrayList();  //所有待下载的列表
 | 
				
			||||||
 | 
					            tempList.Clear();
 | 
				
			||||||
 | 
					            foreach (JObject seg in lastSegments)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                tempList.Add(seg.ToString());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(isFirstJson)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                toDownList = tempList;
 | 
				
			||||||
 | 
					                isFirstJson = false;
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Parser parser = new Parser();
 | 
				
			||||||
 | 
					            parser.DownDir = Path.GetDirectoryName(jsonFile);
 | 
				
			||||||
 | 
					            parser.M3u8Url = m3u8Url;
 | 
				
			||||||
 | 
					            parser.LiveStream = true;
 | 
				
			||||||
 | 
					            parser.Parse();  //产生新的json文件
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            jsonContent = File.ReadAllText(jsonFile);
 | 
				
			||||||
 | 
					            initJson = JObject.Parse(jsonContent);
 | 
				
			||||||
 | 
					            JArray segments = JArray.Parse(initJson["m3u8Info"]["segments"][0].ToString());  //大分组
 | 
				
			||||||
 | 
					            foreach (JObject seg in segments)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (!tempList.Contains(seg.ToString()))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    toDownList.Add(seg.ToString());  //加入真正的待下载队列
 | 
				
			||||||
 | 
					                    //Console.WriteLine(seg.ToString());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (toDownList.Count > 0)
 | 
				
			||||||
 | 
					                Record();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //public void TryDownload()
 | 
				
			||||||
 | 
					        //{
 | 
				
			||||||
 | 
					        //    Thread t = new Thread(Download);
 | 
				
			||||||
 | 
					        //    while (toDownList.Count != 0)
 | 
				
			||||||
 | 
					        //    {
 | 
				
			||||||
 | 
					        //        t = new Thread(Download);
 | 
				
			||||||
 | 
					        //        t.Start();
 | 
				
			||||||
 | 
					        //        t.Join();
 | 
				
			||||||
 | 
					        //        while (sd.IsDone != true) ;  //忙等待
 | 
				
			||||||
 | 
					        //        if (toDownList.Count > 0)
 | 
				
			||||||
 | 
					        //            toDownList.RemoveAt(0);  //下完删除一项
 | 
				
			||||||
 | 
					        //    }
 | 
				
			||||||
 | 
					        //    Console.WriteLine("Waiting...");
 | 
				
			||||||
 | 
					        //}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void Record()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            while (toDownList.Count > 0 && (sd.FileUrl != "" ? sd.IsDone : true)) 
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                JObject info = JObject.Parse(toDownList[0].ToString());
 | 
				
			||||||
 | 
					                int index = info["index"].Value<int>();
 | 
				
			||||||
 | 
					                sd.FileUrl = info["segUri"].Value<string>();
 | 
				
			||||||
 | 
					                sd.Method = info["method"].Value<string>();
 | 
				
			||||||
 | 
					                if (sd.Method != "NONE")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    sd.Key = info["key"].Value<string>();
 | 
				
			||||||
 | 
					                    sd.Iv = info["iv"].Value<string>();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                sd.TimeOut = (int)timer.Interval - 1000;//超时时间不超过下次执行时间
 | 
				
			||||||
 | 
					                sd.SegIndex = index;
 | 
				
			||||||
 | 
					                sd.Headers = Headers;
 | 
				
			||||||
 | 
					                sd.SegDur = info["duration"].Value<double>();
 | 
				
			||||||
 | 
					                sd.IsLive = true;  //标记为直播
 | 
				
			||||||
 | 
					                sd.LiveFile = LiveFile;
 | 
				
			||||||
 | 
					                sd.LiveStream = LiveStream;
 | 
				
			||||||
 | 
					                sd.Down();  //开始下载
 | 
				
			||||||
 | 
					                while (sd.IsDone != true) { Thread.Sleep(1); };  //忙等待 Thread.Sleep(1) 可防止cpu 100% 防止电脑风扇狂转
 | 
				
			||||||
 | 
					                if (toDownList.Count > 0)
 | 
				
			||||||
 | 
					                    toDownList.RemoveAt(0);  //下完删除一项
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            LOGGER.PrintLine("Waiting...", LOGGER.Warning);
 | 
				
			||||||
 | 
					            LOGGER.WriteLine("Waiting...");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //检测是否有新分片
 | 
				
			||||||
 | 
					        private bool isNewSeg()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (toDownList.Count > 0)
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										38
									
								
								N_m3u8DL-CLI/HLSTags.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								N_m3u8DL-CLI/HLSTags.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace N_m3u8DL_CLI
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class HLSTags
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public static string ext_m3u = "#EXTM3U";
 | 
				
			||||||
 | 
					        public static string ext_x_targetduration = "#EXT-X-TARGETDURATION";
 | 
				
			||||||
 | 
					        public static string ext_x_media_sequence = "#EXT-X-MEDIA-SEQUENCE";
 | 
				
			||||||
 | 
					        public static string ext_x_discontinuity_sequence = "#EXT-X-DISCONTINUITY-SEQUENCE";
 | 
				
			||||||
 | 
					        public static string ext_x_program_date_time = "#EXT-X-PROGRAM-DATE-TIME";
 | 
				
			||||||
 | 
					        public static string ext_x_media = "#EXT-X-MEDIA";
 | 
				
			||||||
 | 
					        public static string ext_x_playlist_type = "#EXT-X-PLAYLIST-TYPE";
 | 
				
			||||||
 | 
					        public static string ext_x_key = "#EXT-X-KEY";
 | 
				
			||||||
 | 
					        public static string ext_x_stream_inf = "#EXT-X-STREAM-INF";
 | 
				
			||||||
 | 
					        public static string ext_x_version = "#EXT-X-VERSION";
 | 
				
			||||||
 | 
					        public static string ext_x_allow_cache = "#EXT-X-ALLOW-CACHE";
 | 
				
			||||||
 | 
					        public static string ext_x_endlist = "#EXT-X-ENDLIST";
 | 
				
			||||||
 | 
					        public static string extinf = "#EXTINF";
 | 
				
			||||||
 | 
					        public static string ext_i_frames_only = "#EXT-X-I-FRAMES-ONLY";
 | 
				
			||||||
 | 
					        public static string ext_x_byterange = "#EXT-X-BYTERANGE";
 | 
				
			||||||
 | 
					        public static string ext_x_i_frame_stream_inf = "#EXT-X-I-FRAME-STREAM-INF";
 | 
				
			||||||
 | 
					        public static string ext_x_discontinuity = "#EXT-X-DISCONTINUITY";
 | 
				
			||||||
 | 
					        public static string ext_x_cue_out_start = "#EXT-X-CUE-OUT";
 | 
				
			||||||
 | 
					        public static string ext_x_cue_out = "#EXT-X-CUE-OUT-CONT";
 | 
				
			||||||
 | 
					        public static string ext_is_independent_segments = "#EXT-X-INDEPENDENT-SEGMENTS";
 | 
				
			||||||
 | 
					        public static string ext_x_scte35 = "#EXT-OATCLS-SCTE35";
 | 
				
			||||||
 | 
					        public static string ext_x_cue_start = "#EXT-X-CUE-OUT";
 | 
				
			||||||
 | 
					        public static string ext_x_cue_end = "#EXT-X-CUE-IN";
 | 
				
			||||||
 | 
					        public static string ext_x_cue_span = "#EXT-X-CUE-SPAN";
 | 
				
			||||||
 | 
					        public static string ext_x_map = "#EXT-X-MAP";
 | 
				
			||||||
 | 
					        public static string ext_x_start = "#EXT-X-START";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										163
									
								
								N_m3u8DL-CLI/LOGGER.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								N_m3u8DL-CLI/LOGGER.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,163 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Diagnostics;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace N_m3u8DL_CLI
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class LOGGER
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public static int CursorIndex = 5;
 | 
				
			||||||
 | 
					        public static int FFmpegCorsorIndex = 5;
 | 
				
			||||||
 | 
					        public const int Default = 1;
 | 
				
			||||||
 | 
					        public const int Error = 2;
 | 
				
			||||||
 | 
					        public const int Warning = 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static string LOGFILE;
 | 
				
			||||||
 | 
					        public static bool STOPLOG = false;
 | 
				
			||||||
 | 
					        public static string FindLog(string dir)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            DirectoryInfo d = new DirectoryInfo(dir);
 | 
				
			||||||
 | 
					            foreach (FileInfo fi in d.GetFiles())
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (fi.Extension.ToUpper() == ".LOG")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return fi.FullName;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return "";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static void InitLog()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (!Directory.Exists(Path.GetDirectoryName(LOGFILE)))//若文件夹不存在则新建文件夹   
 | 
				
			||||||
 | 
					                Directory.CreateDirectory(Path.GetDirectoryName(LOGFILE)); //新建文件夹
 | 
				
			||||||
 | 
					            if (File.Exists(LOGFILE))//若文件存在则删除
 | 
				
			||||||
 | 
					                File.Delete(LOGFILE);
 | 
				
			||||||
 | 
					            string file = LOGFILE;
 | 
				
			||||||
 | 
					            string now = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
 | 
				
			||||||
 | 
					            string init = "LOG " + DateTime.Now.ToString("yyyy/MM/dd") + "\r\n"
 | 
				
			||||||
 | 
					                + "Save Path: " + Path.GetDirectoryName(LOGFILE) + "\r\n"
 | 
				
			||||||
 | 
					                + "Task Start: " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "\r\n"
 | 
				
			||||||
 | 
					                + "Task CommandLine: " + Environment.CommandLine;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (File.Exists(Path.Combine(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName), "N_m3u8DL-CLI.args.txt")))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                init += "\r\nAdditional Args: " + File.ReadAllText(Path.Combine(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName), "N_m3u8DL-CLI.args.txt"));  //解析命令行
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            init += "\r\n\r\n";
 | 
				
			||||||
 | 
					            File.WriteAllText(file, init, Encoding.UTF8);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //读写锁机制,当资源被占用,其他线程等待
 | 
				
			||||||
 | 
					        static ReaderWriterLockSlim LogWriteLock = new ReaderWriterLockSlim();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static void PrintLine(string text, int printLevel = 1, int cursorIndex = 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (CursorIndex > 1000)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    Console.Clear();
 | 
				
			||||||
 | 
					                    CursorIndex = 0;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (cursorIndex == 0)
 | 
				
			||||||
 | 
					                    Console.SetCursorPosition(0, CursorIndex++);
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                    Console.SetCursorPosition(0, cursorIndex);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            switch (printLevel)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                case 0:
 | 
				
			||||||
 | 
					                    Console.WriteLine(" ".PadRight(12) + " " + text);
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 1:
 | 
				
			||||||
 | 
					                    Console.Write(DateTime.Now.ToString("HH:mm:ss.fff") + " ");
 | 
				
			||||||
 | 
					                    Console.WriteLine(text);
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 2:
 | 
				
			||||||
 | 
					                    Console.Write(DateTime.Now.ToString("HH:mm:ss.fff") + " ");
 | 
				
			||||||
 | 
					                    Console.ForegroundColor = ConsoleColor.Red;
 | 
				
			||||||
 | 
					                    Console.WriteLine(text);
 | 
				
			||||||
 | 
					                    Console.ResetColor();
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 3:
 | 
				
			||||||
 | 
					                    Console.Write(DateTime.Now.ToString("HH:mm:ss.fff") + " ");
 | 
				
			||||||
 | 
					                    Console.ForegroundColor = ConsoleColor.DarkYellow;
 | 
				
			||||||
 | 
					                    Console.WriteLine(text);
 | 
				
			||||||
 | 
					                    Console.ResetColor();
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static void WriteLine(string text)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (STOPLOG)
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            if (!File.Exists(LOGFILE))
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                string file = LOGFILE;
 | 
				
			||||||
 | 
					                //进入写入
 | 
				
			||||||
 | 
					                LogWriteLock.EnterWriteLock();
 | 
				
			||||||
 | 
					                using (StreamWriter sw = File.AppendText(file))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    sw.WriteLine(DateTime.Now.ToString("HH:mm:ss.fff") + " / (NORMAL) " + text, Encoding.UTF8);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            finally
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                //释放占用
 | 
				
			||||||
 | 
					                LogWriteLock.ExitWriteLock();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static void WriteLineError(string text)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (!File.Exists(LOGFILE))
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                string file = LOGFILE;
 | 
				
			||||||
 | 
					                //进入写入
 | 
				
			||||||
 | 
					                LogWriteLock.EnterWriteLock();
 | 
				
			||||||
 | 
					                using (StreamWriter sw = File.AppendText(file))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    sw.WriteLine(DateTime.Now.ToString("HH:mm:ss.fff") + " / (ERROR) " + text, Encoding.UTF8);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            finally
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                //释放占用
 | 
				
			||||||
 | 
					                LogWriteLock.ExitWriteLock();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static void Show(string text)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Console.ForegroundColor = ConsoleColor.Red;
 | 
				
			||||||
 | 
					            Console.WriteLine(DateTime.Now.ToString("o") + "  " + text);
 | 
				
			||||||
 | 
					            while (Console.ForegroundColor == ConsoleColor.Red) 
 | 
				
			||||||
 | 
					                Console.ResetColor();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										824
									
								
								N_m3u8DL-CLI/MPDParser.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										824
									
								
								N_m3u8DL-CLI/MPDParser.cs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										148
									
								
								N_m3u8DL-CLI/N_m3u8DL-CLI.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								N_m3u8DL-CLI/N_m3u8DL-CLI.csproj
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,148 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
				
			||||||
 | 
					  <Import Project="..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props" Condition="Exists('..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props')" />
 | 
				
			||||||
 | 
					  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
 | 
				
			||||||
 | 
					  <PropertyGroup>
 | 
				
			||||||
 | 
					    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
 | 
				
			||||||
 | 
					    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
 | 
				
			||||||
 | 
					    <ProjectGuid>{4FB61439-B738-46AC-B3AF-2BF72150D057}</ProjectGuid>
 | 
				
			||||||
 | 
					    <OutputType>Exe</OutputType>
 | 
				
			||||||
 | 
					    <RootNamespace>N_m3u8DL_CLI</RootNamespace>
 | 
				
			||||||
 | 
					    <AssemblyName>N_m3u8DL-CLI</AssemblyName>
 | 
				
			||||||
 | 
					    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
 | 
				
			||||||
 | 
					    <FileAlignment>512</FileAlignment>
 | 
				
			||||||
 | 
					    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
 | 
				
			||||||
 | 
					    <TargetFrameworkProfile />
 | 
				
			||||||
 | 
					    <NuGetPackageImportStamp>
 | 
				
			||||||
 | 
					    </NuGetPackageImportStamp>
 | 
				
			||||||
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
 | 
				
			||||||
 | 
					    <PlatformTarget>x86</PlatformTarget>
 | 
				
			||||||
 | 
					    <DebugSymbols>true</DebugSymbols>
 | 
				
			||||||
 | 
					    <DebugType>full</DebugType>
 | 
				
			||||||
 | 
					    <Optimize>false</Optimize>
 | 
				
			||||||
 | 
					    <OutputPath>bin\Debug\</OutputPath>
 | 
				
			||||||
 | 
					    <DefineConstants>DEBUG;TRACE</DefineConstants>
 | 
				
			||||||
 | 
					    <ErrorReport>prompt</ErrorReport>
 | 
				
			||||||
 | 
					    <WarningLevel>4</WarningLevel>
 | 
				
			||||||
 | 
					    <Prefer32Bit>false</Prefer32Bit>
 | 
				
			||||||
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
 | 
				
			||||||
 | 
					    <PlatformTarget>AnyCPU</PlatformTarget>
 | 
				
			||||||
 | 
					    <DebugType>pdbonly</DebugType>
 | 
				
			||||||
 | 
					    <Optimize>true</Optimize>
 | 
				
			||||||
 | 
					    <OutputPath>bin\Release\</OutputPath>
 | 
				
			||||||
 | 
					    <DefineConstants>TRACE</DefineConstants>
 | 
				
			||||||
 | 
					    <ErrorReport>prompt</ErrorReport>
 | 
				
			||||||
 | 
					    <WarningLevel>4</WarningLevel>
 | 
				
			||||||
 | 
					    <Prefer32Bit>false</Prefer32Bit>
 | 
				
			||||||
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					  <PropertyGroup>
 | 
				
			||||||
 | 
					    <ApplicationIcon>logo_3Iv_icon.ico</ApplicationIcon>
 | 
				
			||||||
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <Reference Include="Costura, Version=4.1.0.0, Culture=neutral, PublicKeyToken=9919ef960d84173d, processorArchitecture=MSIL">
 | 
				
			||||||
 | 
					      <HintPath>..\packages\Costura.Fody.4.1.0\lib\net40\Costura.dll</HintPath>
 | 
				
			||||||
 | 
					    </Reference>
 | 
				
			||||||
 | 
					    <Reference Include="Microsoft.JScript" />
 | 
				
			||||||
 | 
					    <Reference Include="netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" />
 | 
				
			||||||
 | 
					    <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
 | 
				
			||||||
 | 
					      <HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
 | 
				
			||||||
 | 
					    </Reference>
 | 
				
			||||||
 | 
					    <Reference Include="NiL.JS, Version=2.5.1428.0, Culture=neutral, PublicKeyToken=fa941a7c2a4de689, processorArchitecture=MSIL">
 | 
				
			||||||
 | 
					      <HintPath>..\packages\NiL.JS.2.5.1428\lib\net45\NiL.JS.dll</HintPath>
 | 
				
			||||||
 | 
					    </Reference>
 | 
				
			||||||
 | 
					    <Reference Include="PresentationFramework" />
 | 
				
			||||||
 | 
					    <Reference Include="System" />
 | 
				
			||||||
 | 
					    <Reference Include="System.Collections" />
 | 
				
			||||||
 | 
					    <Reference Include="System.Core" />
 | 
				
			||||||
 | 
					    <Reference Include="System.IO" />
 | 
				
			||||||
 | 
					    <Reference Include="System.Web" />
 | 
				
			||||||
 | 
					    <Reference Include="System.Xml.Linq" />
 | 
				
			||||||
 | 
					    <Reference Include="System.Data.DataSetExtensions" />
 | 
				
			||||||
 | 
					    <Reference Include="Microsoft.CSharp" />
 | 
				
			||||||
 | 
					    <Reference Include="System.Data" />
 | 
				
			||||||
 | 
					    <Reference Include="System.Net.Http" />
 | 
				
			||||||
 | 
					    <Reference Include="System.Xml" />
 | 
				
			||||||
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <Compile Include="CommandLineArgument.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="CommandLineArgumentParser.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Decode51CtoKey.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="DecodeDdyun.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="DecodeHuke88Key.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="DecodeImooc.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="DecodeNfmovies.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Decrypter.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="FFmpeg.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Global.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="HLSLiveDownloader.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="HLSTags.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="LOGGER.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="DownloadManager.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="MPDParser.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Parser.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Program.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Properties\AssemblyInfo.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Downloader.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="strings.Designer.cs">
 | 
				
			||||||
 | 
					      <AutoGen>True</AutoGen>
 | 
				
			||||||
 | 
					      <DesignTime>True</DesignTime>
 | 
				
			||||||
 | 
					      <DependentUpon>strings.resx</DependentUpon>
 | 
				
			||||||
 | 
					    </Compile>
 | 
				
			||||||
 | 
					    <Compile Include="strings.en-US.Designer.cs">
 | 
				
			||||||
 | 
					      <AutoGen>True</AutoGen>
 | 
				
			||||||
 | 
					      <DesignTime>True</DesignTime>
 | 
				
			||||||
 | 
					      <DependentUpon>strings.en-US.resx</DependentUpon>
 | 
				
			||||||
 | 
					    </Compile>
 | 
				
			||||||
 | 
					    <Compile Include="strings.zh-TW.Designer.cs">
 | 
				
			||||||
 | 
					      <AutoGen>True</AutoGen>
 | 
				
			||||||
 | 
					      <DesignTime>True</DesignTime>
 | 
				
			||||||
 | 
					      <DependentUpon>strings.zh-TW.resx</DependentUpon>
 | 
				
			||||||
 | 
					    </Compile>
 | 
				
			||||||
 | 
					    <Compile Include="Watcher.cs" />
 | 
				
			||||||
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <None Include="App.config">
 | 
				
			||||||
 | 
					      <SubType>Designer</SubType>
 | 
				
			||||||
 | 
					    </None>
 | 
				
			||||||
 | 
					    <None Include="packages.config" />
 | 
				
			||||||
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <COMReference Include="Scripting">
 | 
				
			||||||
 | 
					      <Guid>{420B2830-E718-11CF-893D-00A0C9054228}</Guid>
 | 
				
			||||||
 | 
					      <VersionMajor>1</VersionMajor>
 | 
				
			||||||
 | 
					      <VersionMinor>0</VersionMinor>
 | 
				
			||||||
 | 
					      <Lcid>0</Lcid>
 | 
				
			||||||
 | 
					      <WrapperTool>tlbimp</WrapperTool>
 | 
				
			||||||
 | 
					      <Isolated>False</Isolated>
 | 
				
			||||||
 | 
					      <EmbedInteropTypes>True</EmbedInteropTypes>
 | 
				
			||||||
 | 
					    </COMReference>
 | 
				
			||||||
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <Content Include="logo_3Iv_icon.ico" />
 | 
				
			||||||
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <EmbeddedResource Include="strings.en-US.resx">
 | 
				
			||||||
 | 
					      <Generator>ResXFileCodeGenerator</Generator>
 | 
				
			||||||
 | 
					      <LastGenOutput>strings.en-US.Designer.cs</LastGenOutput>
 | 
				
			||||||
 | 
					    </EmbeddedResource>
 | 
				
			||||||
 | 
					    <EmbeddedResource Include="strings.resx">
 | 
				
			||||||
 | 
					      <Generator>ResXFileCodeGenerator</Generator>
 | 
				
			||||||
 | 
					      <LastGenOutput>strings.Designer.cs</LastGenOutput>
 | 
				
			||||||
 | 
					    </EmbeddedResource>
 | 
				
			||||||
 | 
					    <EmbeddedResource Include="strings.zh-TW.resx">
 | 
				
			||||||
 | 
					      <Generator>ResXFileCodeGenerator</Generator>
 | 
				
			||||||
 | 
					      <LastGenOutput>strings.zh-TW.Designer.cs</LastGenOutput>
 | 
				
			||||||
 | 
					    </EmbeddedResource>
 | 
				
			||||||
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 | 
				
			||||||
 | 
					  <Import Project="..\packages\Fody.6.0.0\build\Fody.targets" Condition="Exists('..\packages\Fody.6.0.0\build\Fody.targets')" />
 | 
				
			||||||
 | 
					  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
 | 
				
			||||||
 | 
					    <PropertyGroup>
 | 
				
			||||||
 | 
					      <ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
 | 
				
			||||||
 | 
					    </PropertyGroup>
 | 
				
			||||||
 | 
					    <Error Condition="!Exists('..\packages\Fody.6.0.0\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.6.0.0\build\Fody.targets'))" />
 | 
				
			||||||
 | 
					    <Error Condition="!Exists('..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props'))" />
 | 
				
			||||||
 | 
					  </Target>
 | 
				
			||||||
 | 
					</Project>
 | 
				
			||||||
							
								
								
									
										957
									
								
								N_m3u8DL-CLI/Parser.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										957
									
								
								N_m3u8DL-CLI/Parser.cs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										501
									
								
								N_m3u8DL-CLI/Program.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										501
									
								
								N_m3u8DL-CLI/Program.cs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										36
									
								
								N_m3u8DL-CLI/Properties/AssemblyInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								N_m3u8DL-CLI/Properties/AssemblyInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					using System.Reflection;
 | 
				
			||||||
 | 
					using System.Runtime.CompilerServices;
 | 
				
			||||||
 | 
					using System.Runtime.InteropServices;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 有关程序集的一般信息由以下
 | 
				
			||||||
 | 
					// 控制。更改这些特性值可修改
 | 
				
			||||||
 | 
					// 与程序集关联的信息。
 | 
				
			||||||
 | 
					[assembly: AssemblyTitle("N_m3u8DL-CLI")]
 | 
				
			||||||
 | 
					[assembly: AssemblyDescription("一款命令行m3u8下载器")]
 | 
				
			||||||
 | 
					[assembly: AssemblyConfiguration("")]
 | 
				
			||||||
 | 
					[assembly: AssemblyCompany("nilaoda")]
 | 
				
			||||||
 | 
					[assembly: AssemblyProduct("N_m3u8DL-CLI")]
 | 
				
			||||||
 | 
					[assembly: AssemblyCopyright("Copyright ©  2020")]
 | 
				
			||||||
 | 
					[assembly: AssemblyTrademark("")]
 | 
				
			||||||
 | 
					[assembly: AssemblyCulture("")]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 将 ComVisible 设置为 false 会使此程序集中的类型
 | 
				
			||||||
 | 
					//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
 | 
				
			||||||
 | 
					//请将此类型的 ComVisible 特性设置为 true。
 | 
				
			||||||
 | 
					[assembly: ComVisible(false)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
 | 
				
			||||||
 | 
					[assembly: Guid("4fb61439-b738-46ac-b3af-2bf72150d057")]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 程序集的版本信息由下列四个值组成: 
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//      主版本
 | 
				
			||||||
 | 
					//      次版本
 | 
				
			||||||
 | 
					//      生成号
 | 
				
			||||||
 | 
					//      修订号
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
 | 
				
			||||||
 | 
					// 方法是按如下所示使用“*”: :
 | 
				
			||||||
 | 
					// [assembly: AssemblyVersion("1.0.*")]
 | 
				
			||||||
 | 
					[assembly: AssemblyVersion("1.0.0.0")]
 | 
				
			||||||
 | 
					[assembly: AssemblyFileVersion("2.7.0.0")]
 | 
				
			||||||
							
								
								
									
										104
									
								
								N_m3u8DL-CLI/Watcher.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								N_m3u8DL-CLI/Watcher.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,104 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using System.Timers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace N_m3u8DL_CLI
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class Watcher
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private string dir = string.Empty;
 | 
				
			||||||
 | 
					        private int total = 0;
 | 
				
			||||||
 | 
					        private static double totalDuration = 0; //总时长
 | 
				
			||||||
 | 
					        private int now = 0;
 | 
				
			||||||
 | 
					        private int partsCount = 0;
 | 
				
			||||||
 | 
					        FileSystemWatcher watcher = new FileSystemWatcher();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public int Total { get => total; set => total = value; }
 | 
				
			||||||
 | 
					        public int Now { get => now; set => now = value; }
 | 
				
			||||||
 | 
					        public int PartsCount { get => partsCount; set => partsCount = value; }
 | 
				
			||||||
 | 
					        public static double TotalDuration { get => totalDuration; set => totalDuration = value; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Watcher(string Dir)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this.dir = Dir;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void WatcherStrat()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            for (int i = 0; i < PartsCount; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Now += Global.GetFileCount(dir + "\\Part_" + i.ToString(DownloadManager.partsPadZero), ".ts");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            watcher.Path = dir;
 | 
				
			||||||
 | 
					            watcher.Filter = "*.ts";
 | 
				
			||||||
 | 
					            watcher.IncludeSubdirectories = true;  //包括子目录
 | 
				
			||||||
 | 
					            watcher.EnableRaisingEvents = true;    //开启提交事件
 | 
				
			||||||
 | 
					            watcher.Created += new FileSystemEventHandler(OnCreated);
 | 
				
			||||||
 | 
					            watcher.Renamed += new RenamedEventHandler(OnCreated);
 | 
				
			||||||
 | 
					            watcher.Deleted += new FileSystemEventHandler(OnDeleted);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void WatcherStop()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            watcher.Dispose();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void OnCreated(object source, FileSystemEventArgs e)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (Path.GetFileNameWithoutExtension(e.FullPath).StartsWith("Part"))
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            Now++;
 | 
				
			||||||
 | 
					            if (Now > Total)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            //Console.Title = Now + "   /   " + Total;
 | 
				
			||||||
 | 
					            string downloadedSize = Global.FormatFileSize(DownloadManager.DownloadedSize);
 | 
				
			||||||
 | 
					            string estimatedSize = Global.FormatFileSize(DownloadManager.DownloadedSize * total / now);
 | 
				
			||||||
 | 
					            string percent = (Convert.ToDouble(now) / Convert.ToDouble(total) * 100).ToString("0.00") + "%";
 | 
				
			||||||
 | 
					            Console.SetCursorPosition(0, 2);
 | 
				
			||||||
 | 
					            Console.Write(("Progress: " + Now + " of " + Total
 | 
				
			||||||
 | 
					                + $" ({percent}/{downloadedSize}/{estimatedSize}/{Global.FormatTime(Convert.ToInt32(TotalDuration))})").PadRight(62));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void OnRenamed(object source, RenamedEventArgs e)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (Path.GetFileNameWithoutExtension(e.FullPath).StartsWith("Part"))
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            Now++;
 | 
				
			||||||
 | 
					            if (Now > Total)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            //Console.Title = Now + "   /   " + Total;
 | 
				
			||||||
 | 
					            string downloadedSize = Global.FormatFileSize(DownloadManager.DownloadedSize);
 | 
				
			||||||
 | 
					            string estimatedSize = Global.FormatFileSize(DownloadManager.DownloadedSize * total / now);
 | 
				
			||||||
 | 
					            string percent = (Convert.ToDouble(now) / Convert.ToDouble(total) * 100).ToString("0.00") + "%";
 | 
				
			||||||
 | 
					            Console.SetCursorPosition(0, 2);
 | 
				
			||||||
 | 
					            Console.Write(("Progress: " + Now + " of " + Total
 | 
				
			||||||
 | 
					                + $" ({percent}/{downloadedSize}/{estimatedSize}/{Global.FormatTime(Convert.ToInt32(TotalDuration))})").PadRight(62));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void OnDeleted(object source, FileSystemEventArgs e)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (Path.GetFileNameWithoutExtension(e.FullPath).StartsWith("Part"))
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            Now--;
 | 
				
			||||||
 | 
					            if (Now > Total)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            //Console.Title = Now + "   /   " + Total;
 | 
				
			||||||
 | 
					            string downloadedSize = Global.FormatFileSize(DownloadManager.DownloadedSize);
 | 
				
			||||||
 | 
					            string estimatedSize = Global.FormatFileSize(DownloadManager.DownloadedSize * total / now);
 | 
				
			||||||
 | 
					            string percent = (Convert.ToDouble(now) / Convert.ToDouble(total) * 100).ToString("0.00") + "%";
 | 
				
			||||||
 | 
					            Console.SetCursorPosition(0, 2);
 | 
				
			||||||
 | 
					            Console.Write(("Progress: " + Now + " of " + Total
 | 
				
			||||||
 | 
					                + $" ({percent}/{downloadedSize}/{estimatedSize}/{Global.FormatTime(Convert.ToInt32(TotalDuration))})").PadRight(62));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										333
									
								
								N_m3u8DL-CLI/changelog.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										333
									
								
								N_m3u8DL-CLI/changelog.txt
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								N_m3u8DL-CLI/logo_3Iv_icon.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								N_m3u8DL-CLI/logo_3Iv_icon.ico
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 25 KiB  | 
							
								
								
									
										7
									
								
								N_m3u8DL-CLI/packages.config
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								N_m3u8DL-CLI/packages.config
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<packages>
 | 
				
			||||||
 | 
					  <package id="Fody" version="6.0.0" targetFramework="net46" developmentDependency="true" />
 | 
				
			||||||
 | 
					  <package id="Costura.Fody" version="4.1.0" targetFramework="net46" />
 | 
				
			||||||
 | 
					  <package id="Newtonsoft.Json" version="12.0.3" targetFramework="net46" />
 | 
				
			||||||
 | 
					  <package id="NiL.JS" version="2.5.1428" targetFramework="net46" />
 | 
				
			||||||
 | 
					</packages>
 | 
				
			||||||
							
								
								
									
										559
									
								
								N_m3u8DL-CLI/strings.Designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										559
									
								
								N_m3u8DL-CLI/strings.Designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										0
									
								
								N_m3u8DL-CLI/strings.en-US.Designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								N_m3u8DL-CLI/strings.en-US.Designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user