OpusGang / awsmfunc

awesome VapourSynth functions
MIT License
18 stars 4 forks source link

Specifying more than 20 frames (40 frames) results in .png files becoming "Video" (When using awsmfunc.ScreenGen()) #13

Closed jessielw closed 2 years ago

jessielw commented 2 years ago
General
Complete name                            : 01a_source.png
CompleteName_Last                        : 40a_source.png
Format                                   : PNG
Format/Info                              : Portable Network Graphic
File size                                : 101 MiB

Video
Format                                   : PNG
Format/Info                              : Portable Network Graphic
Compression                              : Deflate
Width                                    : 1 280 pixels
Height                                   : 692 pixels
Display aspect ratio                     : 1.85:1
Color space                              : RGB
Bit depth                                : 8 bits
Compression mode                         : Lossless
Stream size                              : 101 MiB (100%)
quietvoid commented 2 years ago

Please include your script.

jessielw commented 2 years ago

Here is a simplified version of the script. I can reproduce it here everytime!

import re
import subprocess

import vapoursynth as vs
from vapoursynth import core
core = vs.core
import awsmfunc
from random import randint, randrange, sample
import pathlib

core.std.LoadPlugin(r"C:\Users\jlw_4\Desktop\TEST\SubText.dll")
core.std.LoadPlugin(r"C:\Users\jlw_4\Desktop\TEST\libimwri.dll")
core.std.LoadPlugin(r"C:\Users\jlw_4\Desktop\TEST\libvslsmashsource.dll")

source_file = core.lsmas.LWLibavSource(r"\\Jlwserver\e\Downloads\VIDEO.mkv")
encode_file = core.lsmas.LWLibavSource(r"VIDEO.mp4")

num_source_frames = len(source_file)

# Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline,
# StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV,
# Encoding
sub_style_1080p = "sans-serif,22,&H000ac7f5,&H00000000,&H00000000,&H00000000,""0,0,0,0,100,100,0,0,1,1,0,7,10,10,10,1"

b_frames = []
while len(b_frames) < 30:
    random_frame = randint(5000, num_source_frames - 5000)
    if encode_file.get_frame(random_frame).props['_PictType'].decode() == 'B':
        b_frames.append(random_frame)
print(b_frames)

src = core.sub.Subtitle(clip=source_file, text='Source', style=sub_style_1080p)
enc = awsmfunc.FrameInfo(clip=encode_file, title='Encode', style=sub_style_1080p)
awsmfunc.ScreenGen([src, enc], frame_numbers=b_frames, folder=r"C:\Users\jlw_4\Desktop\FOLDER\image_working_folder", suffix=["a_source", "b_encode"])

Reproduced with both vsfpng and vs-imwri

If I directly loop through these modules and create images I don't have this issue. (However that's without subtitles, resizing, etc)

quietvoid commented 2 years ago

I can't reproduce any issue. To me it looks like the MediaInfo you posted comes from using mediainfo on the output folder.

Also, you seem to be misusing the folder argument, which is positional and expected to be after the clip array. Not too sure why it still works, though.

jessielw commented 2 years ago

image

Media info. I found an issue in the module

Changing this here fixes the issue

image

jessielw commented 2 years ago

Specifically the overwrite=True is the issue. So this is an issue with the fpng/imwri dlls and not your module

jessielw commented 2 years ago

Overwrite Off image

Overwrite On image

quietvoid commented 2 years ago

The only known issue is that some Windows users have issues with overwrite=True erroring by default. It's because of the missing %d in the output path, but it seems to randomly affect Windows users only.

So the fallback rewrites the output, in this case to %d{suffix}.png. It's possible that substitution is incorrect with some numbers.

jessielw commented 2 years ago

If overwrite is set to True and I do more then 22 photos. Some of the photos start to become Video, only in the media info. Setting this to False allows me to create as many photos as I want with no issues.

Is it possible to just add an argument to make overwrite optional?

quietvoid commented 2 years ago

That wouldn't solve the issue.

jessielw commented 2 years ago

I'm assuming the error is coming from this block of code here?

image

jessielw commented 2 years ago

Simply adding &d as you said originally. Does solve the problem.

image

I'll wait on your solution though

quietvoid commented 2 years ago

No, it happens on the imwri call to save the image. The fallback is where there's except vs.Error: Though if the output file names are correct (using the image count and not the frame number), it's not hit.

jessielw commented 2 years ago

I just generated 200 photos with the default settings. I put a print statement for top and bottom.

                try:
                    encoder_final.write_frame(rgb_clip, num, final_path, fpng_compression)
                    print('top')
                except vs.Error:
                    print('bottom')
                    new_path = folder_path.joinpath(f'%d{suffix}.png').resolve()
                    encoder_final.write_frame(rgb_clip, num, new_path, fpng_compression)

All 200 photos went through the first part of the try block

This is the result

General
Complete name                            : 01b_encode.png
CompleteName_Last                        : 100b_encode.png
Format                                   : PNG
Format/Info                              : Portable Network Graphic
File size                                : 124 MiB

Video
Format                                   : PNG
Format/Info                              : Portable Network Graphic
Compression                              : Deflate
Width                                    : 1 280 pixels
Height                                   : 720 pixels
Display aspect ratio                     : 16:9
Color space                              : RGB
Bit depth                                : 8 bits
Compression mode                         : Lossless
Stream size                              : 124 MiB (100%)
quietvoid commented 2 years ago

Right. There's no issue with VS.

What's happening is that when you use overwrite=True, the file names follow the correct sequence from 01..30. When using overwrite=False, the image names always use the frame number (and use the fallback).

So the confusion is caused by MediaInfo using the sequence and saying that it's a video.

jessielw commented 2 years ago

What would you recommend. Is this something that you can fix in the module?

jessielw commented 2 years ago

Also, ffmpeg defines the images as a video track as well

quietvoid commented 2 years ago

There's nothing to fix, the files are images.

Also, ffmpeg defines the images as a video track as well

According to what command? It doesn't for me.

jessielw commented 2 years ago

They are images. However, something is wrong with them.

image

quietvoid commented 2 years ago

There's nothing wrong with them. ffprobe always says Video: png

As for MediaInfo, it only says Video when:

There's nothing more to do here.

jessielw commented 2 years ago

You definitely have more knowledge of this subject then myself. I appreciate you looking into this for me!

So, what works best for my use case and also keeps the weird video thing from happening is simply adding %d to the suffix in the call.

awsmfunc.ScreenGen([src, enc], frame_numbers=b_frames, folder=folder", suffix=["a_source_%d", "b_encode_%d"])

I appreciate you helping me come up with a solution and hope this helps anyone else that might come across this issue.

quietvoid commented 2 years ago

There isn't really a use for the mediainfo of an image, so I'm not sure what your goal is and why this is an issue.

jessielw commented 2 years ago

I'm using pymediainfo to get the width/height from a list of images for an image viewer.

image

As I scroll the images this is checked each time. Having a mix of video/image tracks to get this, would cause many try/except blocks to prevent error.

quietvoid commented 2 years ago

You could try changing the working directory to be inside the images folder before requesting the mediainfo.

jessielw commented 2 years ago

Currently I just added the frame numbers to prevent the weird error what ever we should call it. Then I am just simply renaming the files after they are generated to strip off the un-needed info.

image

example: 01a_source__000000 rename 01a_source

jessielw commented 2 years ago

Scratch that, the frame numbers have to stay. Simply removing them causes them to be "video" and keeping them there allows them to be "Image"

quietvoid commented 2 years ago

Like I said, if the mediainfo is taken from the directory, the images shouldn't be considered a sequence.

jessielw commented 2 years ago

Ah now I understand! So allowing them to have the unique frame numbers keeps them from being a sequence?

quietvoid commented 2 years ago

Yes.

jessielw commented 2 years ago

Anyways, thanks for the help man. You're a beast!