Compare commits
2 Commits
ae5cdfb5e9
...
dd02f0250c
| Author | SHA1 | Date | |
|---|---|---|---|
| dd02f0250c | |||
| d10869dd3e |
@@ -1,14 +1,16 @@
|
|||||||
<!-- Generated by SpecStory -->
|
<!-- Generated by SpecStory -->
|
||||||
|
|
||||||
|
<!-- cursor Session c905dc1e-3b07-499f-8906-d3b9d49bb984 (2025-06-26 04:00Z) -->
|
||||||
|
|
||||||
# Test encode for one minute (2025-06-26 04:00Z)
|
# Test encode for one minute (2025-06-26 04:00Z)
|
||||||
|
|
||||||
_**User**_
|
_**User (2025-07-03 15:00Z)**_
|
||||||
|
|
||||||
can we do a test encode for 1 min?
|
can we do a test encode for 1 min?
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
_**Assistant**_
|
_**Assistant (default)**_
|
||||||
|
|
||||||
Yes, you can perform a test encode for just 1 minute of each file by modifying the FFmpeg command to only process the first 60 seconds. In FFmpeg, you can use the -t 60 option to limit the output duration to 60 seconds.
|
Yes, you can perform a test encode for just 1 minute of each file by modifying the FFmpeg command to only process the first 60 seconds. In FFmpeg, you can use the -t 60 option to limit the output duration to 60 seconds.
|
||||||
|
|
||||||
@@ -20,7 +22,7 @@ Would you like this as a permanent option (e.g., via a command-line flag or prom
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
_**User**_
|
_**User (2025-07-03 15:00Z)**_
|
||||||
|
|
||||||
the output got stuck on this, but it shows my download rate @ ~300-400 mbps (it's encoding on a network share) do I just wait?
|
the output got stuck on this, but it shows my download rate @ ~300-400 mbps (it's encoding on a network share) do I just wait?
|
||||||
|
|
||||||
@@ -36,7 +38,7 @@ FFmpeg: [out#0/mp4 @ 00000287de38b840] Terminating thread with return code 0 (su
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
_**Assistant**_
|
_**Assistant (default)**_
|
||||||
|
|
||||||
Yes, you should wait! The output shows that FFmpeg is still processing and hasn't actually gotten stuck. Here's what's happening:
|
Yes, you should wait! The output shows that FFmpeg is still processing and hasn't actually gotten stuck. Here's what's happening:
|
||||||
|
|
||||||
@@ -60,7 +62,7 @@ The 300-400 Mbps network activity you're seeing is likely the input file being r
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
_**User**_
|
_**User (2025-07-03 15:00Z)**_
|
||||||
|
|
||||||
what does this mean then? keep in mind my cpu is no longer being utilized
|
what does this mean then? keep in mind my cpu is no longer being utilized
|
||||||
FFmpeg: [out#0/mp4 @ 00000287de38b840] All streams finished
|
FFmpeg: [out#0/mp4 @ 00000287de38b840] All streams finished
|
||||||
@@ -68,7 +70,7 @@ FFmpeg: [out#0/mp4 @ 00000287de38b840] Terminating thread with return code 0 (su
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
_**Assistant**_
|
_**Assistant (default)**_
|
||||||
|
|
||||||
That output means **the encoding is complete and successful!**
|
That output means **the encoding is complete and successful!**
|
||||||
|
|
||||||
@@ -89,13 +91,13 @@ The 15-second test encode is complete! You should find the output file in your `
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
_**User**_
|
_**User (2025-07-03 15:00Z)**_
|
||||||
|
|
||||||
why would ffmpeg.exe still be accessing files at this point?
|
why would ffmpeg.exe still be accessing files at this point?
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
_**Assistant**_
|
_**Assistant (default)**_
|
||||||
|
|
||||||
FFmpeg might still be accessing files for several reasons even after the encoding is "complete":
|
FFmpeg might still be accessing files for several reasons even after the encoding is "complete":
|
||||||
|
|
||||||
@@ -116,19 +118,21 @@ If it's taking an unusually long time (>30 seconds), you could check if there ar
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
_**User**_
|
_**User (2025-07-03 15:00Z)**_
|
||||||
|
|
||||||
the resultant file is broken.
|
the resultant file is broken.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
_**Assistant**_
|
_**Assistant (default)**_
|
||||||
|
|
||||||
The broken output file could be due to several issues. Let me help you troubleshoot:
|
The broken output file could be due to several issues. Let me help you troubleshoot:
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
Tool use: **read_file**
|
||||||
|
|
||||||
Read file: encode_dvr_lossless_vp9.py
|
Read file: encode_dvr_lossless_vp9.py
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -146,7 +150,18 @@ The issue is likely that the process was interrupted or didn't complete properly
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
Tool use: **edit_file**
|
||||||
|
|
||||||
|
|
||||||
|
<details><summary>Edit file: encode_dvr_lossless_vp9.py</summary>
|
||||||
|
|
||||||
|
I'll modify the FFmpeg command to be more robust by adding proper output format specification and ensuring clean termination
|
||||||
|
|
||||||
|
**Chunk 1**
|
||||||
|
Lines added: 2, lines removed: undefined
|
||||||
|
|
||||||
```diff
|
```diff
|
||||||
|
@@ -117,4 +117,6 @@
|
||||||
'-c:a', 'copy',
|
'-c:a', 'copy',
|
||||||
'-map', '0',
|
'-map', '0',
|
||||||
+ '-f', 'mp4', # Explicitly specify output format
|
+ '-f', 'mp4', # Explicitly specify output format
|
||||||
@@ -155,6 +170,8 @@ The issue is likely that the process was interrupted or didn't complete properly
|
|||||||
# Add metadata for each audio stream if label exists
|
# Add metadata for each audio stream if label exists
|
||||||
```
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Also, let's add a simple test to verify the output file:**
|
**Also, let's add a simple test to verify the output file:**
|
||||||
@@ -162,7 +179,18 @@ The issue is likely that the process was interrupted or didn't complete properly
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
Tool use: **edit_file**
|
||||||
|
|
||||||
|
|
||||||
|
<details><summary>Edit file: encode_dvr_lossless_vp9.py</summary>
|
||||||
|
|
||||||
|
I'll add a function to verify the output file integrity after encoding
|
||||||
|
|
||||||
|
**Chunk 1**
|
||||||
|
Lines added: 9, lines removed: undefined
|
||||||
|
|
||||||
```diff
|
```diff
|
||||||
|
@@ -68,4 +68,13 @@
|
||||||
return f"{size_bytes:.2f} TB"
|
return f"{size_bytes:.2f} TB"
|
||||||
|
|
||||||
+ def verify_output_file(output_path):
|
+ def verify_output_file(output_path):
|
||||||
@@ -178,9 +206,22 @@ The issue is likely that the process was interrupted or didn't complete properly
|
|||||||
input_path = Path(input_file)
|
input_path = Path(input_file)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
Tool use: **edit_file**
|
||||||
|
|
||||||
|
|
||||||
|
<details><summary>Edit file: encode_dvr_lossless_vp9.py</summary>
|
||||||
|
|
||||||
|
I'll add file verification after successful encoding
|
||||||
|
|
||||||
|
**Chunk 1**
|
||||||
|
Lines added: 8, lines removed: undefined
|
||||||
|
|
||||||
```diff
|
```diff
|
||||||
|
@@ -159,9 +159,17 @@
|
||||||
compression_ratio = input_size / output_size if output_size > 0 else 0
|
compression_ratio = input_size / output_size if output_size > 0 else 0
|
||||||
|
|
||||||
+ # Verify output file integrity
|
+ # Verify output file integrity
|
||||||
@@ -200,6 +241,8 @@ The issue is likely that the process was interrupted or didn't complete properly
|
|||||||
logging.error(f"FFmpeg process failed with return code {process.returncode}")
|
logging.error(f"FFmpeg process failed with return code {process.returncode}")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Now try the test again with these improvements:**
|
**Now try the test again with these improvements:**
|
||||||
@@ -217,13 +260,13 @@ The updated script should be more robust and will automatically detect and remov
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
_**User**_
|
_**User (2025-07-09 00:17Z)**_
|
||||||
|
|
||||||
results are working, but I'm noticing massive sizes. is there a cq 0 option?
|
results are working, but I'm noticing massive sizes. is there a cq 0 option?
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
_**Assistant**_
|
_**Assistant (default)**_
|
||||||
|
|
||||||
Yes! The issue is that you're using lossless VP9 encoding, which creates very large files. VP9 doesn't have a traditional "CQ 0" option like H.264/H.265, but you can use **CRF (Constant Rate Factor)** which is similar.
|
Yes! The issue is that you're using lossless VP9 encoding, which creates very large files. VP9 doesn't have a traditional "CQ 0" option like H.264/H.265, but you can use **CRF (Constant Rate Factor)** which is similar.
|
||||||
|
|
||||||
@@ -238,8 +281,42 @@ Let me modify the script to use CRF instead of lossless:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
Tool use: **search_replace**
|
||||||
|
|
||||||
|
|
||||||
|
<details><summary>Edit file: encode_dvr_lossless_vp9.py</summary>
|
||||||
|
|
||||||
|
**Chunk 1**
|
||||||
|
Lines added: 1, lines removed: 1
|
||||||
|
|
||||||
|
```diff
|
||||||
|
@@ -104,5 +104,5 @@
|
||||||
|
logging.info(f"Audio labels: {audio_labels}")
|
||||||
|
|
||||||
|
- # FFmpeg command for lossless VP9 encoding with 60s timeout
|
||||||
|
+ # FFmpeg command for high-quality VP9 encoding with 60s timeout
|
||||||
|
cmd = [
|
||||||
|
'ffmpeg',
|
||||||
|
```
|
||||||
|
|
||||||
|
**Chunk 2**
|
||||||
|
Lines added: 3, lines removed: 2
|
||||||
|
|
||||||
|
```diff
|
||||||
|
@@ -111,6 +111,7 @@
|
||||||
|
'-t', '1',
|
||||||
|
'-c:v', 'libvpx-vp9',
|
||||||
|
- '-lossless', '1',
|
||||||
|
- '-cpu-used', '0',
|
||||||
|
+ '-crf', '15', # High quality (0=lossless, 10-20=visually lossless, 20-30=high quality)
|
||||||
|
+ '-b:v', '0', # Let CRF control bitrate
|
||||||
|
+ '-cpu-used', '2', # Faster encoding (0=slowest, 5=fastest)
|
||||||
|
'-row-mt', '1',
|
||||||
|
'-threads', '0',
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Key changes:**
|
**Key changes:**
|
||||||
@@ -258,21 +335,44 @@ The current setting of CRF 15 should give you excellent quality with much smalle
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
_**User**_
|
_**User (2025-07-09 00:17Z)**_
|
||||||
|
|
||||||
these look good, can I test the full video lengths now?
|
these look good, can I test the full video lengths now?
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
_**Assistant**_
|
_**Assistant (default)**_
|
||||||
|
|
||||||
Yes! To test the full video lengths, you just need to remove the `-t 1` parameter from the FFmpeg command. This will encode the entire duration of each video.
|
Yes! To test the full video lengths, you just need to remove the `-t 1` parameter from the FFmpeg command. This will encode the entire duration of each video.
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
Tool use: **search_replace**
|
||||||
|
|
||||||
|
|
||||||
|
<details><summary>Edit file: encode_dvr_lossless_vp9.py</summary>
|
||||||
|
|
||||||
|
**Chunk 1**
|
||||||
|
Lines added: 1, lines removed: 2
|
||||||
|
|
||||||
|
```diff
|
||||||
|
@@ -104,10 +104,9 @@
|
||||||
|
logging.info(f"Audio labels: {audio_labels}")
|
||||||
|
|
||||||
|
- # FFmpeg command for high-quality VP9 encoding with 60s timeout
|
||||||
|
+ # FFmpeg command for high-quality VP9 encoding
|
||||||
|
cmd = [
|
||||||
|
'ffmpeg',
|
||||||
|
'-v', 'verbose',
|
||||||
|
'-i', str(input_path),
|
||||||
|
- '-t', '1',
|
||||||
|
'-c:v', 'libvpx-vp9',
|
||||||
|
'-crf', '15', # High quality (0=lossless, 10-20=visually lossless, 20-30=high quality)
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Perfect! Now the script will encode the full duration of each video. With your current settings:
|
Perfect! Now the script will encode the full duration of each video. With your current settings:
|
||||||
@@ -287,13 +387,13 @@ You can run the script now and it will process all 14 files in your input direct
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
_**User**_
|
_**User (2025-07-09 00:17Z)**_
|
||||||
|
|
||||||
other than increasing the rate limit, how can I make this higher quality?
|
other than increasing the rate limit, how can I make this higher quality?
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
_**Assistant**_
|
_**Assistant (default)**_
|
||||||
|
|
||||||
For higher quality VP9 encoding, here are the key parameters you can adjust:
|
For higher quality VP9 encoding, here are the key parameters you can adjust:
|
||||||
|
|
||||||
@@ -312,8 +412,35 @@ For higher quality VP9 encoding, here are the key parameters you can adjust:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
Tool use: **search_replace**
|
||||||
|
|
||||||
|
|
||||||
|
<details><summary>Edit file: encode_dvr_lossless_vp9.py</summary>
|
||||||
|
|
||||||
|
**Chunk 1**
|
||||||
|
Lines added: 5, lines removed: 2
|
||||||
|
|
||||||
|
```diff
|
||||||
|
@@ -111,10 +111,13 @@
|
||||||
|
'-t', '1', # Render only 1 second
|
||||||
|
'-c:v', 'libvpx-vp9',
|
||||||
|
- '-crf', '0',
|
||||||
|
+ '-crf', '5', # Extremely high quality (0=lossless, 5-10=extremely high)
|
||||||
|
'-b:v', '10000k',
|
||||||
|
'-maxrate', '10000k',
|
||||||
|
- '-cpu-used', '0',
|
||||||
|
+ '-cpu-used', '0', # Slowest encoding for highest quality
|
||||||
|
'-row-mt', '1',
|
||||||
|
'-threads', '0',
|
||||||
|
+ '-tile-columns', '2', # Better quality for 1080p
|
||||||
|
+ '-frame-parallel', '1', # Parallel frame processing
|
||||||
|
+ '-lag-in-frames', '25', # More frames for better compression
|
||||||
|
'-c:a', 'copy',
|
||||||
|
'-map', '0',
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Quality improvements added:**
|
**Quality improvements added:**
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
<!-- Generated by SpecStory -->
|
||||||
|
|
||||||
|
<!-- cursor Session fd1849e6-e572-4051-8efe-3106af3956ce (2025-10-01 20:10Z) -->
|
||||||
|
|
||||||
|
# Delete specific files from output (2025-10-01 20:10Z)
|
||||||
|
|
||||||
|
_**User (2025-10-01 20:08Z)**_
|
||||||
|
|
||||||
|
could you delete these 4 files from output? don't touch input, and don't touch any other files in output.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
_**Assistant (default)**_
|
||||||
|
|
||||||
|
Deleting the 4 problematic files from the output directory.
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Tool use: **delete_file**
|
||||||
|
|
||||||
|
undefined
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Tool use: **delete_file**
|
||||||
|
|
||||||
|
undefined
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Tool use: **delete_file**
|
||||||
|
|
||||||
|
undefined
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Tool use: **delete_file**
|
||||||
|
|
||||||
|
undefined
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Deleted the 4 files from the output directory:
|
||||||
|
|
||||||
|
- `2024-08-08 smithereens.ts.mp4` (audio stream count mismatch)
|
||||||
|
- `2024-08-28 dejection.ts.mp4` (duration mismatch)
|
||||||
|
- `2024-09-04 chaos.ts.mp4` (audio stream count mismatch)
|
||||||
|
- `2024-09-05 resolute.ts.mp4` (duration mismatch)
|
||||||
|
|
||||||
|
No other files were modified.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -20,8 +20,7 @@ log_file = os.path.join(log_dir, f"check_{datetime.now().strftime('%Y%m%d_%H%M%S
|
|||||||
logging.basicConfig(filename=log_file, level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
logging.basicConfig(filename=log_file, level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||||
|
|
||||||
def write_debug_info(message):
|
def write_debug_info(message):
|
||||||
with open("debug_output.txt", "a", encoding='utf-8') as f:
|
logging.info(message)
|
||||||
f.write(f"{message}\n")
|
|
||||||
|
|
||||||
def get_file_info(file_path):
|
def get_file_info(file_path):
|
||||||
try:
|
try:
|
||||||
@@ -107,9 +106,8 @@ def check_file(input_path, output_path):
|
|||||||
return f"Error checking file: {str(e)}"
|
return f"Error checking file: {str(e)}"
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
# Clear previous debug output
|
# Start debug section in the log file
|
||||||
with open("debug_output.txt", "w", encoding='utf-8') as f:
|
logging.info("=== Debug Output ===")
|
||||||
f.write("=== Debug Output ===\n")
|
|
||||||
|
|
||||||
input_dir = "input"
|
input_dir = "input"
|
||||||
output_dir = "output"
|
output_dir = "output"
|
||||||
@@ -139,7 +137,7 @@ def main():
|
|||||||
# Try to list contents using different methods
|
# Try to list contents using different methods
|
||||||
write_debug_info("\nTrying 'dir' command:")
|
write_debug_info("\nTrying 'dir' command:")
|
||||||
try:
|
try:
|
||||||
result = subprocess.run(['dir', input_dir], capture_output=True, text=True)
|
result = subprocess.run(['cmd', '/c', 'dir', input_dir], capture_output=True, text=True)
|
||||||
write_debug_info("Input directory contents (dir command):")
|
write_debug_info("Input directory contents (dir command):")
|
||||||
write_debug_info(result.stdout)
|
write_debug_info(result.stdout)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -162,8 +160,8 @@ def main():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
write_debug_info(f"Error with Path.iterdir: {str(e)}")
|
write_debug_info(f"Error with Path.iterdir: {str(e)}")
|
||||||
|
|
||||||
print("\nDebug information has been written to debug_output.txt")
|
print(f"\nDebug information has been written to {log_file}")
|
||||||
print("Please check that file to see what's actually in the directories")
|
print("Please check that log to see what's actually in the directories")
|
||||||
|
|
||||||
# Continue with the rest of the script...
|
# Continue with the rest of the script...
|
||||||
print("\nChecking files for inconsistencies...")
|
print("\nChecking files for inconsistencies...")
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
=== Debug Output ===
|
|
||||||
|
|
||||||
Checking directories at 2025-08-16 01:57:13.833883
|
|
||||||
Input dir: input
|
|
||||||
Output dir: output
|
|
||||||
|
|
||||||
Directory existence check:
|
|
||||||
Input directory exists: True
|
|
||||||
Output directory exists: True
|
|
||||||
|
|
||||||
Trying 'dir' command:
|
|
||||||
Error with dir command: [WinError 2] The system cannot find the file specified
|
|
||||||
|
|
||||||
Trying os.listdir():
|
|
||||||
Input directory contents (os.listdir):
|
|
||||||
Repo 2025.08.14 - 20.49.10.02.DVR.mp4 - Exists: True - Is file: True
|
|
||||||
Repo 2025.08.14 - 20.58.54.03.DVR.mp4 - Exists: True - Is file: True
|
|
||||||
Repo 2025.08.14 - 21.42.52.02.DVR.mp4 - Exists: True - Is file: True
|
|
||||||
Repo 2025.08.14 - 21.58.34.03.DVR.mp4 - Exists: True - Is file: True
|
|
||||||
Repo 2025.08.14 - 22.00.55.04.DVR.mp4 - Exists: True - Is file: True
|
|
||||||
|
|
||||||
Trying Path.iterdir():
|
|
||||||
Input directory contents (Path.iterdir):
|
|
||||||
Repo 2025.08.14 - 20.49.10.02.DVR.mp4 - Exists: True - Is file: True
|
|
||||||
Repo 2025.08.14 - 20.58.54.03.DVR.mp4 - Exists: True - Is file: True
|
|
||||||
Repo 2025.08.14 - 21.42.52.02.DVR.mp4 - Exists: True - Is file: True
|
|
||||||
Repo 2025.08.14 - 21.58.34.03.DVR.mp4 - Exists: True - Is file: True
|
|
||||||
Repo 2025.08.14 - 22.00.55.04.DVR.mp4 - Exists: True - Is file: True
|
|
||||||
Found real file in input: Repo 2025.08.14 - 20.49.10.02.DVR.mp4
|
|
||||||
Found real file in input: Repo 2025.08.14 - 20.58.54.03.DVR.mp4
|
|
||||||
Found real file in input: Repo 2025.08.14 - 21.42.52.02.DVR.mp4
|
|
||||||
Found real file in input: Repo 2025.08.14 - 21.58.34.03.DVR.mp4
|
|
||||||
Found real file in input: Repo 2025.08.14 - 22.00.55.04.DVR.mp4
|
|
||||||
Found real file in output: Repo 2025.08.14 - 20.49.10.02.DVR.mp4
|
|
||||||
Found real file in output: Repo 2025.08.14 - 20.58.54.03.DVR.mp4
|
|
||||||
Found real file in output: Repo 2025.08.14 - 21.42.52.02.DVR.mp4
|
|
||||||
Found real file in output: Repo 2025.08.14 - 21.58.34.03.DVR.mp4
|
|
||||||
Found real file in output: Repo 2025.08.14 - 22.00.55.04.DVR.mp4
|
|
||||||
@@ -5,6 +5,7 @@ import json
|
|||||||
import logging
|
import logging
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import shutil
|
import shutil
|
||||||
|
import time
|
||||||
|
|
||||||
# ANSI color codes
|
# ANSI color codes
|
||||||
class Colors:
|
class Colors:
|
||||||
@@ -30,7 +31,14 @@ def get_gpu_selection():
|
|||||||
log_dir = "logs"
|
log_dir = "logs"
|
||||||
os.makedirs(log_dir, exist_ok=True)
|
os.makedirs(log_dir, exist_ok=True)
|
||||||
log_file = os.path.join(log_dir, f"encode_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log")
|
log_file = os.path.join(log_dir, f"encode_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log")
|
||||||
logging.basicConfig(filename=log_file, level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
|
||||||
|
# Configure logging with Windows-safe settings
|
||||||
|
logging.basicConfig(
|
||||||
|
filename=log_file,
|
||||||
|
level=logging.INFO,
|
||||||
|
format='%(asctime)s - %(levelname)s - %(message)s',
|
||||||
|
filemode='w' # Explicitly set write mode
|
||||||
|
)
|
||||||
|
|
||||||
def get_file_info(input_file):
|
def get_file_info(input_file):
|
||||||
cmd = [
|
cmd = [
|
||||||
@@ -106,7 +114,9 @@ def encode_dvr(input_file, output_dir, gpu):
|
|||||||
# FFmpeg command with NVIDIA HEVC encoder and maximum quality
|
# FFmpeg command with NVIDIA HEVC encoder and maximum quality
|
||||||
cmd = [
|
cmd = [
|
||||||
'ffmpeg',
|
'ffmpeg',
|
||||||
'-v', 'verbose',
|
'-v', 'info', # Lower verbosity to reduce noise
|
||||||
|
'-stats', # Emit periodic stats
|
||||||
|
'-stats_period', '1.0', # Update stats every 1s (more stable)
|
||||||
'-i', str(input_path),
|
'-i', str(input_path),
|
||||||
'-c:v', 'hevc_nvenc',
|
'-c:v', 'hevc_nvenc',
|
||||||
'-gpu', gpu,
|
'-gpu', gpu,
|
||||||
@@ -130,22 +140,31 @@ def encode_dvr(input_file, output_dir, gpu):
|
|||||||
cmd.append(str(output_path))
|
cmd.append(str(output_path))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Run FFmpeg and capture output
|
# Run FFmpeg and capture combined output (avoid dual-pipe deadlocks on Windows)
|
||||||
process = subprocess.Popen(
|
process = subprocess.Popen(
|
||||||
cmd,
|
cmd,
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE,
|
stderr=subprocess.STDOUT,
|
||||||
universal_newlines=True
|
universal_newlines=True,
|
||||||
|
bufsize=1
|
||||||
)
|
)
|
||||||
|
|
||||||
# Log FFmpeg output in real-time
|
# Stream output line-by-line from a single pipe
|
||||||
while True:
|
for line in iter(process.stdout.readline, ''):
|
||||||
output = process.stderr.readline()
|
if not line:
|
||||||
if output == '' and process.poll() is not None:
|
|
||||||
break
|
break
|
||||||
if output:
|
text = line.strip()
|
||||||
logging.info(f"FFmpeg: {output.strip()}")
|
try:
|
||||||
print(f"{Colors.PURPLE}FFmpeg: {output.strip()}{Colors.ENDC}")
|
if text.startswith('frame=') or ' fps=' in text:
|
||||||
|
logging.info(f"Progress: {text}")
|
||||||
|
print(f"{Colors.PURPLE}Progress: {text}{Colors.ENDC}")
|
||||||
|
else:
|
||||||
|
logging.info(f"FFmpeg: {text}")
|
||||||
|
print(f"{Colors.GREEN}FFmpeg: {text}{Colors.ENDC}")
|
||||||
|
except (OSError, IOError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
process.wait()
|
||||||
|
|
||||||
if process.returncode == 0:
|
if process.returncode == 0:
|
||||||
# Get output file info
|
# Get output file info
|
||||||
|
|||||||
Reference in New Issue
Block a user