dannyroxas commited on
Commit
65e1fbd
Β·
verified Β·
1 Parent(s): b9a284f

again changed videprocessing class and tab3

Browse files
Files changed (1) hide show
  1. app.py +177 -90
app.py CHANGED
@@ -443,43 +443,60 @@ class VideoProcessor:
443
  height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
444
  total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
445
 
446
- # Create temporary output file
447
- temp_output = tempfile.NamedTemporaryFile(suffix='.avi', delete=False) # Changed to .avi
448
  temp_output.close()
449
 
450
- # Try different codecs in order of compatibility
451
  codecs_to_try = [
452
- ('MJPG', '.avi'), # Motion JPEG - most compatible
453
- ('XVID', '.avi'), # XVID
454
- ('mp4v', '.mp4'), # MPEG-4
455
- ('DIV3', '.avi'), # DivX
456
- (0, '.avi') # Uncompressed (fallback)
 
 
 
457
  ]
458
 
459
  out = None
460
  output_path = None
 
461
 
462
  for codec_str, ext in codecs_to_try:
463
  try:
464
  # Update output filename with appropriate extension
465
- output_path = temp_output.name.replace('.avi', ext)
 
 
 
466
 
467
  if codec_str == 0:
468
- # Uncompressed fallback
469
  fourcc = 0
470
  print("Using uncompressed video (larger file size)")
471
  else:
472
  fourcc = cv2.VideoWriter_fourcc(*codec_str)
473
- print(f"Trying codec: {codec_str}")
474
 
475
- out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
 
476
 
477
  if out.isOpened():
478
- print(f"Successfully opened video writer with codec: {codec_str}")
479
- break
480
- else:
481
  out.release()
482
- out = None
 
 
 
 
 
 
 
 
 
 
483
  except Exception as e:
484
  print(f"Failed with codec {codec_str}: {e}")
485
  if out:
@@ -488,11 +505,12 @@ class VideoProcessor:
488
  continue
489
 
490
  if out is None or not out.isOpened():
491
- raise Exception("Could not open video writer with any codec")
 
 
492
 
493
  # Process frames
494
  frame_count = 0
495
- processed_frames = []
496
 
497
  while True:
498
  ret, frame = cap.read()
@@ -510,13 +528,11 @@ class VideoProcessor:
510
  styled_array = np.array(styled_frame)
511
  bgr_frame = cv2.cvtColor(styled_array, cv2.COLOR_RGB2BGR)
512
 
513
- # Write frame
514
- out.write(bgr_frame)
515
-
516
- # Also keep frames in memory for fallback
517
- if len(processed_frames) < 300: # Limit to prevent memory issues
518
- processed_frames.append(bgr_frame.copy())
519
 
 
520
  frame_count += 1
521
 
522
  if progress_callback and frame_count % 10 == 0:
@@ -527,34 +543,17 @@ class VideoProcessor:
527
  out.release()
528
 
529
  # Verify the output file
530
- if not os.path.exists(output_path) or os.path.getsize(output_path) == 0:
531
- print("Output file is empty or doesn't exist")
532
-
533
- # Try to create a simple video from frames as fallback
534
- if processed_frames:
535
- print("Attempting fallback: creating video from frames")
536
- fallback_path = tempfile.NamedTemporaryFile(suffix='_fallback.mp4', delete=False).name
537
-
538
- # Try creating with the most basic settings
539
- fourcc = cv2.VideoWriter_fourcc(*'mp4v')
540
- out_fallback = cv2.VideoWriter(fallback_path, fourcc, fps, (width, height))
541
-
542
- if out_fallback.isOpened():
543
- for frame in processed_frames:
544
- out_fallback.write(frame)
545
- out_fallback.release()
546
-
547
- if os.path.exists(fallback_path) and os.path.getsize(fallback_path) > 0:
548
- os.unlink(output_path)
549
- return fallback_path
550
-
551
  return None
552
 
553
- print(f"Video saved to: {output_path}")
554
  print(f"File size: {os.path.getsize(output_path) / 1024 / 1024:.2f} MB")
 
 
555
 
556
- # Clean up original temp file if we used a different extension
557
- if output_path != temp_output.name:
558
  try:
559
  os.unlink(temp_output.name)
560
  except:
@@ -566,6 +565,74 @@ class VideoProcessor:
566
  print(f"Error processing video: {e}")
567
  traceback.print_exc()
568
  return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
569
 
570
  # ===========================
571
  # MAIN STYLE TRANSFER SYSTEM
@@ -1911,6 +1978,7 @@ with tab2:
1911
  # TAB 3: Video Processing
1912
  # TAB 3: Video Processing
1913
  # TAB 3: Video Processing
 
1914
  with tab3:
1915
  st.header("🎬 Video Processing")
1916
 
@@ -1971,29 +2039,23 @@ with tab3:
1971
  )
1972
 
1973
  if output_path and os.path.exists(output_path):
1974
- # Read the video file immediately and store bytes in session state
1975
  try:
1976
  with open(output_path, 'rb') as f:
1977
  video_bytes = f.read()
1978
 
1979
  # Determine file extension
1980
- file_ext = os.path.splitext(output_path)[1]
1981
 
1982
  # Store in session state
1983
  st.session_state['video_result_bytes'] = video_bytes
1984
  st.session_state['video_result_ext'] = file_ext
1985
  st.session_state['video_result_available'] = True
 
1986
 
1987
- # Convert to MP4 if needed for web playback
1988
- if file_ext.lower() != '.mp4':
1989
- st.info(f"Video saved as {file_ext} format. Converting for web playback...")
1990
-
1991
- # For non-MP4, we'll provide download but may have playback issues
1992
- st.warning("Note: Video playback may not work for non-MP4 formats. Use the download button to save the file.")
1993
-
1994
- st.success("Video processing complete!")
1995
 
1996
- # Clean up the output file after reading
1997
  try:
1998
  os.unlink(output_path)
1999
  except:
@@ -2002,7 +2064,7 @@ with tab3:
2002
  st.error(f"Failed to read processed video: {str(e)}")
2003
  st.session_state['video_result_available'] = False
2004
  else:
2005
- st.error("Failed to process video. Please check the format and try again.")
2006
  st.session_state['video_result_available'] = False
2007
 
2008
  # Cleanup input file
@@ -2021,12 +2083,37 @@ with tab3:
2021
  if st.session_state.get('video_result_available', False) and 'video_result_bytes' in st.session_state:
2022
  try:
2023
  file_ext = st.session_state.get('video_result_ext', '.mp4')
 
2024
 
2025
- # Try to display video if it's MP4
2026
- if file_ext.lower() == '.mp4':
2027
- st.video(st.session_state['video_result_bytes'])
 
 
 
 
 
2028
  else:
2029
- st.info(f"Video format ({file_ext}) may not be playable in browser. Please download the file.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2030
 
2031
  # Always provide download button
2032
  mime_types = {
@@ -2034,47 +2121,47 @@ with tab3:
2034
  '.avi': 'video/x-msvideo',
2035
  '.mov': 'video/quicktime'
2036
  }
2037
- mime_type = mime_types.get(file_ext.lower(), 'video/mp4')
2038
 
2039
- st.download_button(
2040
- label="πŸ“₯ Download Processed Video",
2041
- data=st.session_state['video_result_bytes'],
2042
- file_name=f"styled_video_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}{file_ext}",
2043
- mime=mime_type
2044
- )
2045
 
2046
- # Info about the video
2047
- file_size_mb = len(st.session_state['video_result_bytes']) / (1024 * 1024)
2048
- st.info(f"Video size: {file_size_mb:.2f} MB ({file_ext} format)")
 
 
 
 
 
2049
 
2050
- # Codec info
2051
- st.caption("πŸ’‘ If video doesn't play, download it and use a local video player.")
 
 
 
 
 
 
 
2052
 
2053
- # Clear button to free memory
2054
- if st.button("πŸ—‘οΈ Clear Result", key="clear_video_result"):
2055
- del st.session_state['video_result_bytes']
2056
- if 'video_result_ext' in st.session_state:
2057
- del st.session_state['video_result_ext']
2058
- st.session_state['video_result_available'] = False
2059
- st.rerun()
2060
 
2061
  except Exception as e:
2062
  st.error(f"Error displaying video: {str(e)}")
2063
 
2064
- # Fallback: just provide download if display fails
2065
  if 'video_result_bytes' in st.session_state:
2066
- file_ext = st.session_state.get('video_result_ext', '.mp4')
2067
  st.download_button(
2068
- label="πŸ“₯ Download Processed Video (Display Error)",
2069
  data=st.session_state['video_result_bytes'],
2070
- file_name=f"styled_video_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}{file_ext}",
2071
  mime="application/octet-stream"
2072
  )
2073
- else:
2074
- st.error("Video data not available")
2075
 
2076
  elif st.session_state.get('video_result_available', False):
2077
- st.warning("Video data not found in session. Please process the video again.")
2078
  if st.button("Clear State"):
2079
  st.session_state['video_result_available'] = False
2080
  st.rerun()
 
443
  height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
444
  total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
445
 
446
+ # Create temporary output file - always start with mp4
447
+ temp_output = tempfile.NamedTemporaryFile(suffix='.mp4', delete=False)
448
  temp_output.close()
449
 
450
+ # Try different codecs - prioritize MP4-compatible ones
451
  codecs_to_try = [
452
+ ('mp4v', '.mp4'), # MPEG-4 - most compatible MP4 codec
453
+ ('MP4V', '.mp4'), # Alternative case
454
+ ('FMP4', '.mp4'), # Another MPEG-4 variant
455
+ ('DIVX', '.mp4'), # DivX (sometimes works with MP4)
456
+ ('XVID', '.avi'), # If MP4 fails, try AVI
457
+ ('MJPG', '.avi'), # Motion JPEG - fallback
458
+ ('DIV3', '.avi'), # DivX3
459
+ (0, '.avi') # Uncompressed (last resort)
460
  ]
461
 
462
  out = None
463
  output_path = None
464
+ used_codec = None
465
 
466
  for codec_str, ext in codecs_to_try:
467
  try:
468
  # Update output filename with appropriate extension
469
+ if ext == '.mp4':
470
+ output_path = temp_output.name
471
+ else:
472
+ output_path = temp_output.name.replace('.mp4', ext)
473
 
474
  if codec_str == 0:
 
475
  fourcc = 0
476
  print("Using uncompressed video (larger file size)")
477
  else:
478
  fourcc = cv2.VideoWriter_fourcc(*codec_str)
479
+ print(f"Trying codec: {codec_str} for {ext}")
480
 
481
+ # Create writer with specific parameters
482
+ out = cv2.VideoWriter(output_path, fourcc, fps, (width, height), isColor=True)
483
 
484
  if out.isOpened():
485
+ # Test write a black frame to ensure it really works
486
+ test_frame = np.zeros((height, width, 3), dtype=np.uint8)
487
+ out.write(test_frame)
488
  out.release()
489
+
490
+ # Re-open for actual writing
491
+ out = cv2.VideoWriter(output_path, fourcc, fps, (width, height), isColor=True)
492
+ if out.isOpened():
493
+ used_codec = codec_str
494
+ print(f"βœ“ Successfully using codec: {codec_str} with {ext}")
495
+ break
496
+
497
+ out.release()
498
+ out = None
499
+
500
  except Exception as e:
501
  print(f"Failed with codec {codec_str}: {e}")
502
  if out:
 
505
  continue
506
 
507
  if out is None or not out.isOpened():
508
+ # Last resort: save frames as images and create video differently
509
+ print("Standard codecs failed. Trying alternative approach...")
510
+ return self._process_with_frame_saving(cap, style_configs, blend_mode, fps, width, height, total_frames, progress_callback)
511
 
512
  # Process frames
513
  frame_count = 0
 
514
 
515
  while True:
516
  ret, frame = cap.read()
 
528
  styled_array = np.array(styled_frame)
529
  bgr_frame = cv2.cvtColor(styled_array, cv2.COLOR_RGB2BGR)
530
 
531
+ # Ensure frame is correct size and type
532
+ if bgr_frame.shape[:2] != (height, width):
533
+ bgr_frame = cv2.resize(bgr_frame, (width, height))
 
 
 
534
 
535
+ out.write(bgr_frame)
536
  frame_count += 1
537
 
538
  if progress_callback and frame_count % 10 == 0:
 
543
  out.release()
544
 
545
  # Verify the output file
546
+ if not os.path.exists(output_path) or os.path.getsize(output_path) < 1000:
547
+ print(f"Output file is too small or doesn't exist (size: {os.path.getsize(output_path) if os.path.exists(output_path) else 0} bytes)")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
548
  return None
549
 
550
+ print(f"Video successfully saved to: {output_path}")
551
  print(f"File size: {os.path.getsize(output_path) / 1024 / 1024:.2f} MB")
552
+ print(f"Format: {os.path.splitext(output_path)[1]}")
553
+ print(f"Codec used: {used_codec}")
554
 
555
+ # Clean up original temp file if different
556
+ if output_path != temp_output.name and os.path.exists(temp_output.name):
557
  try:
558
  os.unlink(temp_output.name)
559
  except:
 
565
  print(f"Error processing video: {e}")
566
  traceback.print_exc()
567
  return None
568
+
569
+ def _process_with_frame_saving(self, cap, style_configs, blend_mode, fps, width, height, total_frames, progress_callback):
570
+ """Alternative processing method: save frames then combine"""
571
+ try:
572
+ print("Using frame-saving fallback method...")
573
+ temp_dir = tempfile.mkdtemp()
574
+ frame_count = 0
575
+ frame_paths = []
576
+
577
+ # Process and save frames
578
+ while True:
579
+ ret, frame = cap.read()
580
+ if not ret:
581
+ break
582
+
583
+ # Process frame
584
+ rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
585
+ pil_frame = Image.fromarray(rgb_frame)
586
+ styled_frame = self.system.blend_styles(pil_frame, style_configs, blend_mode)
587
+
588
+ # Save frame
589
+ frame_path = os.path.join(temp_dir, f"frame_{frame_count:06d}.png")
590
+ styled_frame.save(frame_path)
591
+ frame_paths.append(frame_path)
592
+
593
+ frame_count += 1
594
+ if progress_callback and frame_count % 10 == 0:
595
+ progress = frame_count / total_frames
596
+ progress_callback(progress, f"Processing frame {frame_count}/{total_frames}")
597
+
598
+ cap.release()
599
+
600
+ if not frame_paths:
601
+ return None
602
+
603
+ # Try to create video from frames
604
+ output_path = tempfile.NamedTemporaryFile(suffix='.mp4', delete=False).name
605
+
606
+ # Read first frame to get size
607
+ first_frame = cv2.imread(frame_paths[0])
608
+ h, w = first_frame.shape[:2]
609
+
610
+ # Try simple mp4v codec
611
+ fourcc = cv2.VideoWriter_fourcc(*'mp4v')
612
+ out = cv2.VideoWriter(output_path, fourcc, fps, (w, h))
613
+
614
+ if out.isOpened():
615
+ for frame_path in frame_paths:
616
+ frame = cv2.imread(frame_path)
617
+ out.write(frame)
618
+ out.release()
619
+
620
+ # Clean up frames
621
+ shutil.rmtree(temp_dir)
622
+
623
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 1000:
624
+ print(f"Successfully created video using frame-saving method")
625
+ return output_path
626
+
627
+ # Clean up
628
+ shutil.rmtree(temp_dir)
629
+ return None
630
+
631
+ except Exception as e:
632
+ print(f"Frame-saving method failed: {e}")
633
+ if 'temp_dir' in locals() and os.path.exists(temp_dir):
634
+ shutil.rmtree(temp_dir)
635
+ return None
636
 
637
  # ===========================
638
  # MAIN STYLE TRANSFER SYSTEM
 
1978
  # TAB 3: Video Processing
1979
  # TAB 3: Video Processing
1980
  # TAB 3: Video Processing
1981
+ # TAB 3: Video Processing
1982
  with tab3:
1983
  st.header("🎬 Video Processing")
1984
 
 
2039
  )
2040
 
2041
  if output_path and os.path.exists(output_path):
2042
+ # Read the video file immediately
2043
  try:
2044
  with open(output_path, 'rb') as f:
2045
  video_bytes = f.read()
2046
 
2047
  # Determine file extension
2048
+ file_ext = os.path.splitext(output_path)[1].lower()
2049
 
2050
  # Store in session state
2051
  st.session_state['video_result_bytes'] = video_bytes
2052
  st.session_state['video_result_ext'] = file_ext
2053
  st.session_state['video_result_available'] = True
2054
+ st.session_state['video_is_mp4'] = (file_ext == '.mp4')
2055
 
2056
+ st.success(f"βœ… Video processing complete! Format: {file_ext.upper()}")
 
 
 
 
 
 
 
2057
 
2058
+ # Clean up files
2059
  try:
2060
  os.unlink(output_path)
2061
  except:
 
2064
  st.error(f"Failed to read processed video: {str(e)}")
2065
  st.session_state['video_result_available'] = False
2066
  else:
2067
+ st.error("Failed to process video. Please try a different video or reduce the resolution.")
2068
  st.session_state['video_result_available'] = False
2069
 
2070
  # Cleanup input file
 
2083
  if st.session_state.get('video_result_available', False) and 'video_result_bytes' in st.session_state:
2084
  try:
2085
  file_ext = st.session_state.get('video_result_ext', '.mp4')
2086
+ video_bytes = st.session_state['video_result_bytes']
2087
 
2088
+ # File info
2089
+ file_size_mb = len(video_bytes) / (1024 * 1024)
2090
+
2091
+ # Try to display video
2092
+ if st.session_state.get('video_is_mp4', False):
2093
+ # For MP4, should work in browser
2094
+ st.video(video_bytes)
2095
+ st.success(f"βœ… Video ready! Size: {file_size_mb:.2f} MB")
2096
  else:
2097
+ # For non-MP4, show info and download
2098
+ st.info(f"Video format ({file_ext}) may not play in browser. Please download to view.")
2099
+
2100
+ # Show preview image if possible
2101
+ try:
2102
+ # Try to extract a frame for preview
2103
+ temp_preview = tempfile.NamedTemporaryFile(delete=False, suffix=file_ext)
2104
+ temp_preview.write(video_bytes)
2105
+ temp_preview.close()
2106
+
2107
+ cap = cv2.VideoCapture(temp_preview.name)
2108
+ ret, frame = cap.read()
2109
+ if ret:
2110
+ # Convert frame to RGB and display
2111
+ rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
2112
+ st.image(rgb_frame, caption="Video Preview (First Frame)", use_column_width=True)
2113
+ cap.release()
2114
+ os.unlink(temp_preview.name)
2115
+ except:
2116
+ pass
2117
 
2118
  # Always provide download button
2119
  mime_types = {
 
2121
  '.avi': 'video/x-msvideo',
2122
  '.mov': 'video/quicktime'
2123
  }
2124
+ mime_type = mime_types.get(file_ext, 'application/octet-stream')
2125
 
2126
+ col_dl1, col_dl2 = st.columns(2)
 
 
 
 
 
2127
 
2128
+ with col_dl1:
2129
+ st.download_button(
2130
+ label=f"πŸ“₯ Download Video ({file_ext.upper()})",
2131
+ data=video_bytes,
2132
+ file_name=f"styled_video_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}{file_ext}",
2133
+ mime=mime_type,
2134
+ use_container_width=True
2135
+ )
2136
 
2137
+ with col_dl2:
2138
+ if st.button("πŸ—‘οΈ Clear Result", use_container_width=True):
2139
+ del st.session_state['video_result_bytes']
2140
+ st.session_state['video_result_available'] = False
2141
+ if 'video_result_ext' in st.session_state:
2142
+ del st.session_state['video_result_ext']
2143
+ if 'video_is_mp4' in st.session_state:
2144
+ del st.session_state['video_is_mp4']
2145
+ st.rerun()
2146
 
2147
+ # Info about playback
2148
+ if not st.session_state.get('video_is_mp4', False):
2149
+ st.caption("πŸ’‘ For best compatibility, download and use VLC or another video player.")
 
 
 
 
2150
 
2151
  except Exception as e:
2152
  st.error(f"Error displaying video: {str(e)}")
2153
 
2154
+ # Emergency download button
2155
  if 'video_result_bytes' in st.session_state:
 
2156
  st.download_button(
2157
+ label="πŸ“₯ Download Video (Error occurred)",
2158
  data=st.session_state['video_result_bytes'],
2159
+ file_name=f"styled_video_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.mp4",
2160
  mime="application/octet-stream"
2161
  )
 
 
2162
 
2163
  elif st.session_state.get('video_result_available', False):
2164
+ st.warning("Video data not found. Please process the video again.")
2165
  if st.button("Clear State"):
2166
  st.session_state['video_result_available'] = False
2167
  st.rerun()