abhiTronix / vidgear

A High-performance cross-platform Video Processing Python framework powerpacked with unique trailblazing features :fire:
https://abhitronix.github.io/vidgear
Apache License 2.0
3.36k stars 253 forks source link

[Question]: I edit individual frames, but the original unearthly video still ends up on YouTube. Why? #364

Closed nordost8 closed 1 year ago

nordost8 commented 1 year ago

Issue guidelines

Issue Checklist

Describe your Question

Hi, I would like to pad each frame of the video with an image (superimpose an image on each frame), I really need this to vizualization the audio (create smooth animation)

I started simple, but immediately ran into a problem :( I replace each frame with a different image (another frame). I see that everything is fine through cv2.imshow(). But my YouTube video still remains unchanged, as if I did not change the frames at all. Why the changed frames do not reach YouTube?

Terminal log output(Optional)

No response

Python Code(Optional)

import cv2
from vidgear.gears import CamGear
from vidgear.gears import WriteGear

VIDEO_SOURCE = "./source/outsmall.mp4" # mp4 video, codec="libx264", audio_codec="aac", 60fps 1920x1080
IMAGE_SOURCE = './source/images/my_image.png' # png 1920x1080

output_params = {
    "-i": VIDEO_SOURCE,
    "-acodec": "aac",
    "-ar": 44100,
    "-b:a": "128k",
    "-vcodec": "libx264",
    "-pix_fmt": "yuv420p",
    "-f": "flv",
    "-preset": "slow",
    "-r": 60,
    "-g": 60 * 4
}

# [WARNING]: Change your YouTube-Live Stream Key here:
YOUTUBE_STREAM_KEY = ""

writer = WriteGear(
    output="rtmp://a.rtmp.youtube.com/live2/{}".format(YOUTUBE_STREAM_KEY),
    logging=True,
    **output_params
)

stream = CamGear(source=VIDEO_SOURCE).start()
while True:
    fframe = stream.read()
    another_frame = cv2.imread(IMAGE_SOURCE, cv2.IMREAD_UNCHANGED)
    another_frame = cv2.resize(another_frame, (1920, 1080))

    if fframe is None:
        stream.stop()
        stream = CamGear(source=VIDEO_SOURCE).start()
        continue

    writer.write(another_frame)

VidGear Version

last

Python version

3.11.2

Operating System version

Windows 10

Any other Relevant Information?

No response

welcome[bot] commented 1 year ago

Thanks for opening this issue, a maintainer will get back to you shortly!

In the meantime:

abhiTronix commented 1 year ago

@rankovaZoria This makes no sense. WriteGear class doesn't know where the frames are coming from. It is in your code which is somehow feeding wrong frames to the write(). Kindly check your code again, if doubt put cv2.imshow() just before write() to see if correct frames are fed in.

nordost8 commented 1 year ago

@abhiTronix

I don't know how it happens, changed frames get into my YouTube-writer and it can be seen through cv2.imshow, but original frames still get to YouTube. I even recorded a video from the screen for you if you do not believe me or think that I made a mistake somewhere: https://youtu.be/86Cn6Tlu2tU

actual code:

import cv2
from vidgear.gears import CamGear
from vidgear.gears import WriteGear

VIDEO_SOURCE = "./source/outsmall.mp4"  # mp4 video, codec="libx264", audio_codec="aac", 60fps 1280x720
IMAGE_SOURCE = './source/my_image.jpg'  # jpg 1280x720

output_params = {
    "-i": VIDEO_SOURCE,
    "-acodec": "aac",
    "-ar": 44100,
    "-b:a": "128k",
    "-vcodec": "libx264",
    "-pix_fmt": "yuv420p",
    "-f": "flv",
    "-preset": "slow",
    "-r": 60,
    "-g": 60 * 2
}

# [WARNING]: Change your YouTube-Live Stream Key here:
YOUTUBE_STREAM_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXX"

writer = WriteGear(
    output="rtmp://a.rtmp.youtube.com/live2/{}".format(YOUTUBE_STREAM_KEY),
    logging=True,
    **output_params
)

stream = CamGear(source=VIDEO_SOURCE).start()

another_frame = cv2.imread(IMAGE_SOURCE)
another_frame = cv2.resize(another_frame, (1280, 720))

while True:
    fframe = stream.read() # <<< ORIGINAL FRAME

    if fframe is None:
        stream.stop()
        stream = CamGear(source=VIDEO_SOURCE).start()
        continue

    cv2.imshow('another_frame', another_frame)
    key = cv2.waitKey(1) & 0xFF
    if key == ord("q"):
        break
    writer.write(another_frame) # <<< MY ANOTHER FRAME

this example with source video and image: https://drive.google.com/file/d/1fWMNAu4DoTNQMyFRKa-FZ1Aryz3ht7FO/view?usp=sharing

abhiTronix commented 1 year ago

@rankovaZoria Do not put original key here.

abhiTronix commented 1 year ago

@rankovaZoria Can you try without audio source? like just image as input and no audio.

nordost8 commented 1 year ago

@abhiTronix it's old key.

abhiTronix commented 1 year ago

Try the solution once.

nordost8 commented 1 year ago

Should I make the source video without audio?

output_params = {
    "-i": VIDEO_SOURCE,
    "-vcodec": "libx264",
    "-pix_fmt": "yuv420p",
    "-f": "flv",
    "-preset": "slow",
    "-r": 60,
    "-g": 60 * 2
}

# [WARNING]: Change your YouTube-Live Stream Key here:
YOUTUBE_STREAM_KEY = ""

writer = WriteGear(
    output="rtmp://a.rtmp.youtube.com/live2/{}".format(YOUTUBE_STREAM_KEY),
    logging=True,
    **output_params
)

...

This also did not solve the problem

abhiTronix commented 1 year ago

@rankovaZoria Remove video source "-i": VIDEO_SOURCE, also.

nordost8 commented 1 year ago

@rankovaZoria Remove video source "-i": VIDEO_SOURCE, also.

But how? Without the specified video source, the stream on YouTube does not start and there will be an error: 14:44:59 :: WriteGear :: ERROR :: BrokenPipeError caught, Wrong values passed to FFmpeg Pipe. Kindly Refer Docs!

output_params = {
    "-vcodec": "libx264",
    "-pix_fmt": "yuv420p",
    "-f": "flv",
    "-preset": "slow",
    "-r": 60,
    "-g": 60 * 2
}

I want to change every frame of the video before it goes to youtube. And I need music(

abhiTronix commented 1 year ago

@rankovaZoria I don't think you know how FFmpeg works. But try first it through simple example: https://abhitronix.github.io/vidgear/v0.3.0-stable/gears/writegear/compression/usage/#bare-minimum-usage and see if passing your frames work, then try adding audio https://abhitronix.github.io/vidgear/v0.3.0-stable/help/writegear_ex/#using-writegears-compression-mode-to-add-external-audio-file-input-to-video-frames and then finally youtube video.

nordost8 commented 1 year ago

@rankovaZoria I don't think you know how FFmpeg works. But try first it through simple example: https://abhitronix.github.io/vidgear/v0.3.0-stable/gears/writegear/compression/usage/#bare-minimum-usage and see if passing your frames work, then try adding audio https://abhitronix.github.io/vidgear/v0.3.0-stable/help/writegear_ex/#using-writegears-compression-mode-to-add-external-audio-file-input-to-video-frames and then finally youtube video.

Sorry, perhaps you did not fully understand me? I already gave you a code example, it is almost completely identical to your examples. I even recorded a video for you. It is perfectly visible there that the frames are changing, this can be seen through cv2.imshow('another_frame', another_frame).

But the original video still ends up on YouTube. (I'm specifically interested only in streaming on YouTube)

I roughly understand how FFMPEG works, and from the description of your repository, I expected that your library would allow me to edit individual frames of a video, but it does not work, try it yourself. If you could provide me with a minimal code example where you edit a frame of a video before streaming it to YouTube, then I would be very grateful.

Also your comment in the example: # {do something with the frame here} Why is it written there if the frames do not change?

What's the point of this loop (while True) at all? If it does not allow me to work with frames and change them before sending them to YouTube?

nordost8 commented 1 year ago

And why did you remove the instructions for adding external audio? :)

abhiTronix commented 1 year ago

😂 It's not removed but moved to new address, due to new release. Anyways I'll not help unless you're willing to accept help gracefully.

nordost8 commented 1 year ago

I think you wouldn't have helped me anyway, considering you didn't respond to my last question where I explained everything and even provided a video showing that when streaming on YouTube, individual frames are not edited.

😂 It's not removed but moved to new address, due to new release. Anyways I'll not help unless you're willing to accept help gracefully.

nordost8 commented 5 months ago

I would like to apologize for my previous messages.

Is there currently an up-to-date minimal code that demonstrates the possibility of streaming modified video to YouTube? I have an original video, and I want to add a random number to each frame of the video and see this on my YouTube stream. Is it possible to do this with the given library? I remind you that the issue is specifically with YouTube, as everything works fine when recording to a file.