QB64.org Forum

Active Forums => Programs => Topic started by: Dav on May 09, 2020, 08:00:48 pm

Title: Working on a Audio+Video file format to use.
Post by: Dav on May 09, 2020, 08:00:48 pm
It's been a project of mine to come up with an audio/video file format for QB64 programs to use/play, so here's an idea I am working on for doing that.

For the audio, I noticed that _SNDPLAY can play .OGG files properly even with junk attached to the end of them.  For the compressed video, I used the new _DEFLATE command to compress screen grabs and attached those frames to the end of the OGG file.  The result is one file with audio and video that can be played back with a small amount of code.

Could a few of you test this code and see if the small video file I've attached plays OK for you?  If it works OK, then I can post a converter program to make your own video files to play with in QB64.  Thanks.

- Dav

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(640, 480, 32)
  2.  
  3.  
  4. b& = _SNDOPEN("fish2.dav"): _SNDLOOP b&
  5.  
  6. OPEN "fish2.dav" FOR BINARY AS #1
  7.  
  8.     'jump to where video data begins
  9.     SEEK 1, 14470
  10.  
  11.     FOR vid = 0 TO 55
  12.         framelen$ = INPUT$(4, 1)
  13.         frame$ = INPUT$(CVL(framelen$), 1)
  14.         frame$ = _INFLATE$(frame$)
  15.  
  16.         _MEMPUT m, m.OFFSET, frame$
  17.  
  18.         _LIMIT 30
  19.  
  20.         IF INKEY$ <> "" THEN EXIT DO
  21.  
  22.     NEXT
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  

Test file to use -->  [ This attachment cannot be displayed inline in 'Print Page' view ]  




 
Title: Re: Working on a Audio+Video file format to use.
Post by: SierraKen on May 09, 2020, 08:38:45 pm
This took awhile to compile to .exe for some reason, but after a minute or 2, it ran and worked great! I like the fish and the sounds.
The problem you might run into combining sound and video is computer lag slowing one or the other making them not lined up perfectly and in sync.
But this might be the very first BASIC language video program anyone has ever made, I've never seen any other like it before. I wish you luck on this. :)
Title: Re: Working on a Audio+Video file format to use.
Post by: bplus on May 09, 2020, 09:42:01 pm
Plays OK for me, what are you using for bait?
Title: Re: Working on a Audio+Video file format to use.
Post by: Dav on May 09, 2020, 11:37:43 pm
Thanks for testing.  I doubt real syncing audio and video can be done this way, but I have some ideas.  Maybe this will only be useful for small intros.  It's the only method so far I can figure out to have audio&video in one file (without extracting a bunch of image files to HD) while using QB64 commands to play it. 

- Dav
Title: Re: Working on a Audio+Video file format to use.
Post by: euklides on May 10, 2020, 04:47:57 am
Video works. No sound ?
Very interesting !!!
Title: Re: Working on a Audio+Video file format to use.
Post by: Petr on May 10, 2020, 05:04:48 am
Hi Dav,
This is really a very interesting solution. Maybe it would be a little better to place the audio-video boundary information (in the example shown, it is byte 14470) at the end of the file, then it will be possible to load it with the player. 32-bit images were used in the video, right? Of course, I had to dig into it a bit.
To synchronize audio and video - you can control the position of the sound via _SNDGETPOS in your concept. And also in your draft you can track the position of the frames, just add a frame counter to the loop. I think that's a perfect concept.

I forgot! Video + audio plays right for me!
Title: Re: Working on a Audio+Video file format to use.
Post by: TempodiBasic on May 10, 2020, 05:16:16 am
Hi Dav

Great!
It runs ok. I cannot understand if syncronization is ok or no if video is too short to hear/see a distortion between video and sound.

A combination of sound and video! It can be an internal video player for cutscene or little videohelp or moreover....
Title: Re: Working on a Audio+Video file format to use.
Post by: Petr on May 10, 2020, 05:51:56 am
So. I think the code will be better instead of bullshit. First, use the first program to upgrade the existing .dav file

Then use the second program to play the upgraded DAV file. The second program shows a simple video / audio synchronization (no _LIMIT)

Code: QB64: [Select]
  1. DIM ByteBorder AS LONG, FrameCounter AS LONG
  2. ByteBorder& = 14470& 'value, which return your DAV video maker
  3. FrameCounter = 55&
  4. OPEN "fish2.dav" FOR BINARY AS #1
  5. PUT #1, LOF(1) + 1, ByteBorder
  6. PUT #1, , FrameCounter
  7.  


Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(640, 480, 32)
  2. B& = _SNDOPEN("fish2.dav"): _SNDLOOP B&
  3.  
  4. OPEN "fish2.dav" FOR BINARY AS #1
  5. DIM framelen AS LONG, border AS LONG, FrameCount AS LONG
  6. SEEK #1, LOF(1) - 7
  7. GET #1, , border
  8. GET #1, , FrameCount
  9.     'jump to where video data begins
  10.     SEEK 1, border
  11.     FrameDelay = _SNDLEN(B&) / FrameCount
  12.     T! = TIMER + FrameDelay
  13.     vid = 0
  14.  
  15.     DO UNTIL vid = FrameCount
  16.         IF TIMER > T! THEN
  17.             GET #1, , framelen
  18.             fram$ = SPACE$(framelen)
  19.             GET #1, , fram$
  20.             frame$ = _INFLATE$(fram$)
  21.             _MEMPUT m, m.OFFSET, frame$
  22.             vid = vid + 1
  23.             T! = TIMER + FrameDelay
  24.         END IF
  25.         IF INKEY$ <> "" THEN EXIT DO
  26.     LOOP
  27.  

Good news for us is, that ogg file size does not affect the value returned by the _sndlen function.
Title: Re: Working on a Audio+Video file format to use.
Post by: Ashish on May 10, 2020, 08:03:13 am
This is awesome! Great job! :D

Here is my 3D twist to your program Dav :) (Need fish2.dav to run)
Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(640, 480, 32)
  2.  
  3. buffer& = _NEWIMAGE(_WIDTH, _HEIGHT, 32)
  4. REDIM SHARED m AS _MEM: m = _MEMIMAGE(buffer&)
  5.  
  6. b& = _SNDOPEN("fish2.dav"): _SNDLOOP b&
  7.  
  8. OPEN "fish2.dav" FOR BINARY AS #1
  9.  
  10.     'jump to where video data begins
  11.     SEEK 1, 14470
  12.  
  13.     FOR vid = 0 TO 55
  14.         framelen$ = INPUT$(4, 1)
  15.         frame$ = INPUT$(CVL(framelen$), 1)
  16.         frame$ = _INFLATE$(frame$)
  17.  
  18.         _MEMPUT m, m.OFFSET, frame$
  19.  
  20.         _LIMIT 30
  21.  
  22.         IF INKEY$ <> "" THEN EXIT DO
  23.  
  24.     NEXT
  25.  
  26.  
  27.  
  28.  
  29. SUB _GL ()
  30.     STATIC texture AS LONG, init, t
  31.     IF init = 0 THEN
  32.         _glGenTextures 1, _OFFSET(texture)
  33.         init = 1
  34.     END IF
  35.  
  36.     _glEnable _GL_TEXTURE_2D
  37.     _glClearColor 1, 1, 1, 1
  38.     '_glClear _GL_COLOR_BUFFER_BIT
  39.  
  40.     _glBindTexture _GL_TEXTURE_2D, texture
  41.     _glTexImage2D _GL_TEXTURE_2D, 0, _GL_RGBA, _WIDTH, _HEIGHT, 0, _GL_BGRA_EXT, _GL_UNSIGNED_BYTE, m.OFFSET
  42.  
  43.     'set out texture filtering
  44.     _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MAG_FILTER, _GL_LINEAR
  45.     _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MIN_FILTER, _GL_NEAREST
  46.  
  47.  
  48.     t = t + 1
  49.     _glRotatef t, 0.5, 1.5, 1
  50.  
  51.     _glBegin _GL_QUADS
  52.     _glTexCoord2f 0, 1
  53.     _glVertex2f -0.7, 0.7
  54.     _glTexCoord2f 1, 1
  55.     _glVertex2f 0.7, 0.7
  56.     _glTexCoord2f 1, 0
  57.     _glVertex2f 0.7, -0.7
  58.     _glTexCoord2f 0, 0
  59.     _glVertex2f -0.7, -0.7
  60.     _glEnd
  61.  
  62.     _glBindTexture _GL_TEXTURE_2D, 0
  63.     _glBegin _GL_LINE_LOOP
  64.  
  65.     _glVertex2f -0.7, 0.7
  66.  
  67.     _glVertex2f 0.7, 0.7
  68.  
  69.     _glVertex2f 0.7, -0.7
  70.  
  71.     _glVertex2f -0.7, -0.7
  72.     _glEnd
  73.  
  74.  
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
Title: Re: Working on a Audio+Video file format to use.
Post by: Dav on May 10, 2020, 09:20:31 am
That's cool, Ashish!  I really got to start looking into GL!

Peter, Interesting -  Thanks!  I was hoping for something like that - and saving info to a header is something I was working on too (screen width,height, fps). Yes it is 32bit screen images because I used _LOADIMAGE to load a series of BMP images (though the BMPS's were 256 color ones).  Because of that the 256 color video (now 32 bit) is much larger than it needs to be.    I recently found a thread about loading 256 images and think I can implement it (here (https://www.qb64.org/forum/index.php?topic=1252.0)).  256 color videos is what I was aiming for because of file size - _DEFLATE doesn't seem to compress busy screen images too great.  A 3 second video can become several MB's in 32-bit, so a 256 color video will be more usable to me.

I made another short video of someone talking, and the video and audio syncs well in that.   I'll work on it some more and post something more here when I can.  Thanks for the encouragement all.

- Dav
Title: Re: Working on a Audio+Video file format to use.
Post by: FellippeHeitor on May 10, 2020, 09:42:30 am
Great idea and concept, Dav. Thanks for sharing. I'll be watching this thread closely ❤️
Title: Re: Working on a Audio+Video file format to use.
Post by: Dav on May 10, 2020, 10:43:00 am
Thanks, Fellippe.  I was able to make a 640x480, 256 color video this morning.  The file size was reduced from 3.7MB to 2.6MB.  Not as great reduction as I hoped, but it something at least.  I had to go old school to load a 256 BMP onto the screen.  Glad I saved my old Qbasic code!  Here that is for your amusement...

Code: QB64: [Select]
  1.  
  2. SCREEN _NEWIMAGE(640, 480, 256)
  3.  
  4. Load256BMP("image.bmp")
  5.  
  6. SUB Load256BMP (file$)
  7.     'Loads uncompressed 256 color 640x480 BMP into QB64
  8.     'NOTE: DOES NOT VALIDATE OR ERROR CHECK BMP file.
  9.     '      THE CORRECT BMP IS ASSUMED.
  10.  
  11.     OPEN file$ FOR BINARY AS #11
  12.  
  13.     SEEK #11, 55 'skip header to pallette data
  14.  
  15.     OUT 968, 0
  16.     FOR c% = 1 TO 256 'load & out pallette to screen
  17.         A$ = INPUT$(4, 11)
  18.         OUT 969, ASC(MID$(A$, 3, 1)) \ 4
  19.         OUT 969, ASC(MID$(A$, 2, 1)) \ 4
  20.         OUT 969, ASC(MID$(A$, 1, 1)) \ 4
  21.     NEXT
  22.  
  23.     FOR y% = 479 TO 0 STEP -1 'do 480 rows
  24.         A$ = INPUT$(640, 11) 'load a row of 640 pixels.
  25.         FOR x% = 0 TO 639
  26.             PSET (x%, y%), ASC(MID$(A$, x% + 1, 1)) 'plot pixel
  27.         NEXT
  28.     NEXT
  29.  
  30.     CLOSE 11
Title: Re: Working on a Audio+Video file format to use.
Post by: Dav on May 10, 2020, 06:09:05 pm
Ok, here's a demo that shows where it's at right now, and also fully shows how you can make your own audio/video files.  I like how Petr did what he did, but I haven't implemented that yet.  I have saved the needed info to the end of the video file.   I decided to abandon 256 mode for now, couldn't get the palette to be consistent in different screen sizes for some reason. I'll go back to that later down the road.

The demo attachment  here creates a GIANT.DAV animation out of a sequence of images and .OGG file and then plays it back.  Btw, I called them .DAV files not because of my name, but for _DEFLATE+AUDIO+VIDEO files is what they are.

Lots of room for improvement here, like option to NOT have audio, just video.  I'm posting this now as is because I won't have much time to work on it this week.

 Deflate/Audio/Video GIANT demo -->  

(NOTE: Run GIANTMAKE.BAS first to create the GIANT.DAV video file)

- Dav
Title: Re: Working on a Audio+Video file format to use.
Post by: FellippeHeitor on May 10, 2020, 06:11:41 pm
Quote
Btw, I called them .DAV files not because of my name, but for _DEFLATE+AUDIO+VIDEO files is what they are.

... not JUST because of your name, you mean ☺️

Looking forward to compiling this one. I'll get back to you shortly.
Title: Re: Working on a Audio+Video file format to use.
Post by: bplus on May 10, 2020, 06:25:01 pm
Ok, here's a demo that shows where it's at right now, and also fully shows how you can make your own audio/video files.  I like how Petr did what he did, but I haven't implemented that yet.  I have saved the needed info to the end of the video file.   I decided to abandon 256 mode for now, couldn't get the palette to be consistent in different screen sizes for some reason. I'll go back to that later down the road.

The demo attachment  here creates a GIANT.DAV animation out of a sequence of images and .OGG file and then plays it back.  Btw, I called them .DAV files not because of my name, but for _DEFLATE+AUDIO+VIDEO files is what they are.

Lots of room for improvement here, like option to NOT have audio, just video.  I'm posting this now as is because I won't have much time to work on it this week.

 Deflate/Audio/Video GIANT demo -->  

(NOTE: Run GIANTMAKE.BAS first to create the GIANT.DAV video file)

- Dav

Works for me with some .\ added. Cool!
Title: Re: Working on a Audio+Video file format to use.
Post by: SMcNeill on May 10, 2020, 06:56:26 pm
Here's a trick you might use to keep sound synced -- Only play it one second at a time, using _SNDLIMIT and _SNDSETPOS to keep it on track.

For example, let's say you record 10 seconds of video at 30FPS...

At frame 0, set_SNDLIMIT 1.0 and then_SNDSETPOS to the 0 second mark, before using _SNDPLAY.
At frame 30, _SNDSETPOS to the 1 second mark, before calling _SNDPLAY.
At Frame (Counter MOD 30 = 0),  SNDSETPOS to (Counter \ 30 + 1), before using _SNDPLAY.

Sound would always be synced per second then, which should keep things from ever getting very distorted for the video.

Title: Re: Working on a Audio+Video file format to use.
Post by: FellippeHeitor on May 10, 2020, 09:18:47 pm
Really cool job, Dav.

One suggestion I have is to also store the width and height of the original frames. That way, should you want to turn this into a library, it'd be easier to have a set of methods that do not require the user to know the size beforehand. Anything close to this pseudocode:

Code: QB64: [Select]
  1. giant& = loadDAV("GIANT.DAV")
  2.  
  3. playDAV giant&
  4.  
  5.     putDAV giant&, _MOUSEX, _MOUSEY
  6.  

These remarks come from my experiment adapting Zom-B's GIF player, which is originally a standalone (http://www.qb64.org/wiki/GIF_Images) like your GIANTPLAY.BAS here, to play along with InForm. The methods I devised from his player are as you can see here: https://github.com/FellippeHeitor/InForm/blob/development/InForm/extensions/gifplay.bm (https://github.com/FellippeHeitor/InForm/blob/development/InForm/extensions/gifplay.bm) and I ended up having it even load multiple GIFs at once, for simultaneous - and timed - playback.

PS: If you Ctrl+F and look for "Dav" in the GitHub page I'm linking, you'll find your BIN2BAS unpack code there ;-)
Title: Re: Working on a Audio+Video file format to use.
Post by: Dav on May 10, 2020, 11:29:31 pm
Thanks, Fellippe.  Yes, that's a good suggestion.   Thanks for the animated .GIF link.  Looks like a well done piece of work.  Glad BIN2BAS is of use to somebody.

Curiosity gets me experimenting, so I was playing around with _DEFLATE, and found that double deflating often resulted smaller file sizes.  Not always, but a lot of times.  For instance, I did this in the GIANTMAKE program and it shaved of almost 200k in file size in the generated GIANT.DAV animation.:

 'Compress screen image data 
frame$ = _DEFLATE$(frame$)
frame$ = _DEFLATE$(frame$)  'Do it twice!

Of course you will have to double the _INFLATE call when playing the new file back, but I found it interesting that compression can be a even more by double deflating.

EDIT: Steve --- thanks for the good suggestions...

- Dav
Title: Re: Working on a Audio+Video file format to use.
Post by: Dav on May 11, 2020, 05:53:02 pm

Well, I decided to go back to a previous method and format, leaving _DEFLATE behind (but I can use what I learned in other projects).

This method, although it results in a TEMP file creation during playback, I think is better than the _DEFLATE one because you can actually make videos longer than 5 seconds without taking HUGE HD space.

This QBV format (QB64 VIDEO) packs a JPG image series to the OGG insead of _DEFLATE/_MEMIMAGE screen caps.  The result is longer videos with much smaller file size than _DEFLATE could ever do.

Please test the new attached demo.  It builds a 42 second audio/video clip of me playing amazing grace on piano and trumpet. The plus side to this method is video file size is small - only 2.2MB.  The downside is that a temp file of every frame has to be created in the current directory.

Download QB64 Video format Demo - >  [ This attachment cannot be displayed inline in 'Print Page' view ]  

- Dav

Title: Re: Working on a Audio+Video file format to use.
Post by: bplus on May 11, 2020, 10:20:23 pm
Dang that's good! Trumpet and piano at same time, I've never seen that before.

Yeah, OK that's amazing!
Title: Re: Working on a Audio+Video file format to use.
Post by: Petr on May 12, 2020, 01:33:00 pm
Very nice, Dav!
Title: Re: Working on a Audio+Video file format to use.
Post by: Dav on May 15, 2020, 07:40:56 pm
I'm pleased to annouce a finished product, sort of, something worth releasing into programs I think.

QBMAKE v0.10.  Make/Play your own Audio/Video QBV files to use in your QB64 programs, with only a single small SUB to add to your code.  Can make videos with or without audio.  The Player SUB can set x/y position of video on screen, resize screen to fit the video size, zoom video size if wanted, and pause/resume playback with space bar.

The download has two BAS files: QBVMAKE.BAS and QBVPLAY.BAS, and files to make a small demo QBV file.  Run QBVMAKE first to make the BIRD.QBV video so you can see it work.  You can read in the source code how to make your own QBV videos easily.  I recommend the free VirtualDUB program to export AVI videos into a series of .JPG images so you can make your QBV files.

Btw, I tried using Steve's _SNDLIMIT/_SNDSETPOS trick to keep the FPS on track - which did work - but it results in a very small click between frames.  Not bad, but enough to not use it for now.  I'll work on eliminating the click for the next release.

Anyway, here's the finished project kit.  I'll post the BAS program here for reference, but you will need the .ZIP download to use them.

- Dav

DOWNLOAD QBVMAKE v0.10 -->   


QBVMAKE.BAS
Code: QB64: [Select]
  1. '===========
  2. 'QBVMAKE.BAS v0.10
  3. '===========
  4. 'Makes .QBV Audio/Video files for QB64.
  5. 'Uses .jpg image sequences and .ogg sound files.
  6. 'Coded by Dav, MAY/2020
  7.  
  8. 'QBVMAKE makes a .QBV audio/video file using a sequence
  9. 'of .jpg images and uses an .OGG sound file to add audio.
  10. 'This way you can make and use video files in you projects.
  11.  
  12. 'This demo builds a video called BIRD.QBV in the current
  13. 'directory.  It will then play the video.  This is only an
  14. 'example so you can see how to make your own .QBV video.
  15.  
  16. 'NOTE: YOU WILL HAVE TO ADAPT THIS CODE FOR YOUR FILES
  17.  
  18. '===========================================================
  19.  
  20. ' SET YOUR OWN QBV INFORMATION IN THIS AREA.....
  21. ' The following are my demo file settings.
  22. ' You will need to replace them with your own.
  23.  
  24. QBV$ = "bird.qbv" '<<<--- NAME OF YOUR QBV TO MAKE
  25.  
  26. 'Point to your image sequence location below and prefix
  27. 'My images are saved like, bird000.jpg.....
  28. source$ = ".\qbvmake-demo\bird" '<<<---- YOUR IMAGE DIRECTORY
  29.  
  30. OGG$ = ".\qbvmake-demo\bird.ogg" '<<<--- Name of you .OGG file
  31.  
  32. '------
  33.  
  34. 'NOW SET YOUR VIDEO INFO BELOW...
  35.  
  36. Audio = 1 '<<<--- SET TO 1 IF ADDING AUDIO, 0 IF NO AUDIO
  37. fps = 15 'My demo video has 15 frames per second
  38. frames = 165 'My video has 165 images in the sequence
  39. vidwidth = 512 'The width of my video image files
  40. vidheight = 288 'The height of my video image files
  41.  
  42. '==============================================================
  43.  
  44. 'Now here we start making the QBV file....
  45.  
  46. OPEN QBV$ FOR OUTPUT AS #1
  47.  
  48. 'If adding audio, copy it first...
  49. IF Audio = 1 THEN
  50.     OPEN OGG$ FOR BINARY AS #3
  51.     SL = LOF(3) ''Length of OGG sound file...
  52.     'save it to QBV file
  53.     A$ = INPUT$(SL, 3): PRINT #1, A$;: CLOSE #3
  54.     SL = 0 'No audio size at all
  55.  
  56. 'Now we same the jpg images to the .QBV file.
  57. 'We start at frame 0, because image sequences start at 0 usually.
  58. 'This is set to use 0000 series numbers (ie: bird0000.jpg)
  59. 'If yours are different, you will have to adjust the code.
  60.  
  61. 'Go through images...
  62. FOR t = 0 TO frames - 1
  63.  
  64.     'load a .jpg image file (a frame)
  65.     tag$ = LTRIM$(STR$(t))
  66.     IF LEN(tag$) = 3 THEN tag$ = "0" + tag$
  67.     IF LEN(tag$) = 2 THEN tag$ = "00" + tag$
  68.     IF LEN(tag$) = 1 THEN tag$ = "000" + tag$
  69.     f$ = source$ + tag$ + ".jpg"
  70.  
  71.     OPEN f$ FOR BINARY AS 7
  72.     'Grab it, CLOSE it
  73.     frame$ = INPUT$(LOF(7), 7): CLOSE 7
  74.  
  75.     'Get size of frame
  76.     framelen$ = MKL$(LEN(frame$))
  77.  
  78.     'Save it's length to file
  79.     PRINT #1, framelen$;
  80.  
  81.     'Now save the frame data to file
  82.     PRINT #1, frame$;
  83.  
  84.     CLS
  85.     PRINT "============="
  86.     PRINT "QBVMAKE v0.10"
  87.     PRINT "============="
  88.     PRINT
  89.     PRINT "Making .QBV file: "; UCASE$(QBV$)
  90.     IF Auido$ = "0" THEN OGG$ = "(no audio)"
  91.     PRINT "Using audio file: "; OGG$
  92.     PRINT "Adding frame"; t + 1; "of"; frames; "..."
  93.  
  94.  
  95. 'Now we add a Footer to the end of the .QBV file.
  96. 'This will save all the .QBV settings information.
  97.  
  98. 'Set what version of .QBV file this is.
  99. PRINT #1, "QBV0.10";
  100.  
  101. 'Set if QBV has audio of not.
  102. IF Audio = 1 THEN
  103.     PRINT #1, "1";
  104.     PRINT #1, "0";
  105.  
  106. 'Save the width of video
  107. PRINT #1, MKI$(vidwidth);
  108.  
  109. 'Save the height of video
  110. PRINT #1, MKI$(vidheight);
  111.  
  112. 'Now, save the OGG file size to the end in MKL format
  113. PRINT #1, MKL$(SL);
  114.  
  115. 'Now save number of frames in MKI format
  116. PRINT #1, MKI$(frames);
  117.  
  118. 'Now save FPS to file in MKI format
  119. PRINT #1, MKI$(fps);
  120.  
  121.  
  122. PRINT "Done!"
  123. PRINT "Press any key to playback...."
  124. A$ = INPUT$(1)
  125.  
  126. '============================================================
  127.  
  128. 'Now lets play back the video we just made....
  129.  
  130. SCREEN _NEWIMAGE(512, 288, 32) 'Open a 32 bit screen first
  131.  
  132. 'Open the demo file bird.qbv below.....
  133. 'set x/y pos, Zoom x2, resize screen to fit vid, loop option
  134. PlayQBV "bird.qbv", 0, 0, 2, 1, 1
  135.  
  136.  
  137. '=============================================================
  138.  
  139. SUB PlayQBV (file$, x, y, zoom, fit, loopit)
  140.     'file$ = QBV file to play
  141.     'x = x position on screen
  142.     'y = y position on screen
  143.     'zoom factor of video, 1 is regular size,
  144.     '     2 is double size, etc...
  145.     'fit = fit video to match your current screen resolution
  146.     'loopit = Loop video or not. 1 is loop, 0 is play once.
  147.  
  148.     FF = FREEFILE
  149.  
  150.     OPEN file$ FOR BINARY AS FF
  151.  
  152.     'Get info saved at end of file
  153.     SEEK FF, LOF(FF) - 19
  154.  
  155.     Ver$ = INPUT$(7, FF) 'Version of QBV video format
  156.     Audio$ = INPUT$(1, FF) 'Audio setting
  157.     vidwidth = CVI(INPUT$(2, FF)) 'Width of video
  158.     vidheight = CVI(INPUT$(2, FF)) 'Height of video
  159.     VidData = CVL(INPUT$(4, FF)) 'Place in file Video data starts
  160.     frames = CVI(INPUT$(2, FF)) 'How many frames in file
  161.     fps = CVI(INPUT$(2, FF)) 'How many fps
  162.  
  163.     IF Audio$ = "1" THEN
  164.         b& = _SNDOPEN(file$) 'Open sound file
  165.     END IF
  166.  
  167.     'Set screen based on vid setting...
  168.     IF fit = 1 THEN
  169.         SCREEN _NEWIMAGE(vidwidth * zoom, vidheight * zoom, 32)
  170.     END IF
  171.  
  172.     DO
  173.         SEEK FF, VidData + 1
  174.  
  175.         IF Audio$ = "1" THEN _SNDPLAY b&
  176.  
  177.         FOR vid = 1 TO frames
  178.             framelen$ = INPUT$(4, FF)
  179.  
  180.             frame$ = INPUT$(CVL(framelen$), FF)
  181.  
  182.             'make a temp jpg on disk
  183.             FFF = FREEFILE
  184.             OPEN "_tmp_qbv_frame_.jpg" FOR OUTPUT AS FFF
  185.             PRINT #FFF, frame$;
  186.             CLOSE FFF
  187.  
  188.             'load it
  189.             frm& = _LOADIMAGE("_tmp_qbv_frame_.jpg")
  190.             'erase it
  191.             KILL "_tmp_qbv_frame_.jpg"
  192.  
  193.             _PUTIMAGE (x, y)-(x + (vidwidth * zoom), x + (vidheight * zoom)), frm&
  194.             _FREEIMAGE frm&
  195.  
  196.             _LIMIT fps
  197.  
  198.             'A little keyboad control if you want.
  199.             'If you don't want, comment this out....
  200.             SELECT CASE UCASE$(INKEY$)
  201.                 CASE IS = " "
  202.                     IF Audio$ = "1" THEN _SNDPAUSE b&
  203.                     pa$ = INPUT$(1)
  204.                     IF Audio$ = "1" THEN _SNDPLAY b&
  205.                 CASE IS = CHR$(27): EXIT DO 'ESC key exits
  206.             END SELECT
  207.  
  208.         NEXT
  209.  
  210.         IF loopit <> 1 THEN EXIT DO
  211.  
  212.     LOOP
  213.  
  214.     CLOSE FF
  215.  
  216.     IF Audio$ = "1" THEN _SNDSTOP b&
  217.  
  218.  


QBVPLAY.BAS
Code: QB64: [Select]
  1. '===========
  2. 'QBVPLAY.BAS v0.10
  3. '===========
  4. 'Plays .QBV Audio/Video files.
  5. 'Coded by Dav, MAY/2020
  6.  
  7. SCREEN _NEWIMAGE(512, 288, 32)
  8.  
  9. 'Open file piano.qbv below.....
  10. 'set x/y pos, Zoom x2, resize screen to fit vid, loop it
  11. PlayQBV "bird.qbv", 0, 0, 2, 1, 1
  12.  
  13. SUB PlayQBV (file$, x, y, zoom, fit, loopit)
  14.     'file$ = QBV file to play
  15.     'x = x position on screen
  16.     'y = y position on screen
  17.     'zoom factor of video, 1 is regular size,
  18.     '     2 is double size, etc...
  19.     'fit = fit video to match your current screen resolution
  20.     'loopit = Loop video or not. 1 is loop, 0 is play once.
  21.  
  22.     FF = FREEFILE
  23.  
  24.     OPEN file$ FOR BINARY AS FF
  25.  
  26.     'Get info saved at end of file
  27.     SEEK FF, LOF(FF) - 19
  28.  
  29.     Ver$ = INPUT$(7, FF) 'Version of QBV video format
  30.     Audio$ = INPUT$(1, FF) 'Audio setting
  31.     vidwidth = CVI(INPUT$(2, FF)) 'Width of video
  32.     vidheight = CVI(INPUT$(2, FF)) 'Height of video
  33.     VidData = CVL(INPUT$(4, FF)) 'Place in file Video data starts
  34.     frames = CVI(INPUT$(2, FF)) 'How many frames in file
  35.     fps = CVI(INPUT$(2, FF)) 'How many fps
  36.  
  37.     IF Audio$ = "1" THEN
  38.         b& = _SNDOPEN(file$) 'Open sound file
  39.     END IF
  40.  
  41.     'Set screen based on vid setting...
  42.     IF fit = 1 THEN
  43.         SCREEN _NEWIMAGE(vidwidth * zoom, vidheight * zoom, 32)
  44.     END IF
  45.  
  46.     DO
  47.         SEEK FF, VidData + 1
  48.  
  49.         IF Audio$ = "1" THEN _SNDPLAY b&
  50.  
  51.         FOR vid = 1 TO frames
  52.             framelen$ = INPUT$(4, FF)
  53.  
  54.             frame$ = INPUT$(CVL(framelen$), FF)
  55.  
  56.             'make a temp jpg on disk
  57.             FFF = FREEFILE
  58.             OPEN "_tmp_qbv_frame_.jpg" FOR OUTPUT AS FFF
  59.             PRINT #FFF, frame$;
  60.             CLOSE FFF
  61.  
  62.             'load it
  63.             frm& = _LOADIMAGE("_tmp_qbv_frame_.jpg")
  64.             'erase it
  65.             KILL "_tmp_qbv_frame_.jpg"
  66.  
  67.             _PUTIMAGE (x, y)-(x + (vidwidth * zoom), x + (vidheight * zoom)), frm&
  68.             _FREEIMAGE frm&
  69.  
  70.             _LIMIT fps
  71.  
  72.             'A little keyboad control if you want.
  73.             'If you don't want, comment this out....
  74.             SELECT CASE UCASE$(INKEY$)
  75.                 CASE IS = " "
  76.                     IF Audio$ = "1" THEN _SNDPAUSE b&
  77.                     pa$ = INPUT$(1)
  78.                     IF Audio$ = "1" THEN _SNDPLAY b&
  79.                 CASE IS = CHR$(27): EXIT DO 'ESC key exits
  80.             END SELECT
  81.  
  82.         NEXT
  83.  
  84.         IF loopit <> 1 THEN EXIT DO
  85.  
  86.     LOOP
  87.  
  88.     CLOSE FF
  89.  
  90.     IF Audio$ = "1" THEN _SNDSTOP b&
  91.  
  92.  





Title: Re: Working on a Audio+Video file format to use.
Post by: SierraKen on May 15, 2020, 09:44:33 pm
That's REALLY awesome Dav!! Great job! If you want, check out what I added to the player. People can add text within the video itself if they wish. Probably even graphics but I haven't tried that yet. It's using also the _DISPLAY command so things don't flash.  Here is my little mod. I put --------- lines between the 2 areas I added lines at (one line of code in both areas.) Tell me what you think. 

Code: QB64: [Select]
  1. '===========
  2. 'QBVPLAY.BAS v0.10
  3. '===========
  4. 'Plays .QBV Audio/Video files.
  5. 'Coded by Dav, MAY/2020
  6.  
  7. SCREEN _NEWIMAGE(512, 288, 32)
  8.  
  9. 'Open file piano.qbv below.....
  10. 'set x/y pos, Zoom x2, resize screen to fit vid, loop it
  11. PlayQBV "bird.qbv", 0, 0, 2, 1, 1
  12.  
  13. SUB PlayQBV (file$, x, y, zoom, fit, loopit)
  14.     'file$ = QBV file to play
  15.     'x = x position on screen
  16.     'y = y position on screen
  17.     'zoom factor of video, 1 is regular size,
  18.     '     2 is double size, etc...
  19.     'fit = fit video to match your current screen resolution
  20.     'loopit = Loop video or not. 1 is loop, 0 is play once.
  21.  
  22.     FF = FREEFILE
  23.  
  24.     OPEN file$ FOR BINARY AS FF
  25.  
  26.     'Get info saved at end of file
  27.     SEEK FF, LOF(FF) - 19
  28.  
  29.     Ver$ = INPUT$(7, FF) 'Version of QBV video format
  30.     Audio$ = INPUT$(1, FF) 'Audio setting
  31.     vidwidth = CVI(INPUT$(2, FF)) 'Width of video
  32.     vidheight = CVI(INPUT$(2, FF)) 'Height of video
  33.     VidData = CVL(INPUT$(4, FF)) 'Place in file Video data starts
  34.     frames = CVI(INPUT$(2, FF)) 'How many frames in file
  35.     fps = CVI(INPUT$(2, FF)) 'How many fps
  36.  
  37.     IF Audio$ = "1" THEN
  38.         b& = _SNDOPEN(file$) 'Open sound file
  39.     END IF
  40.  
  41.     'Set screen based on vid setting...
  42.     IF fit = 1 THEN
  43.         SCREEN _NEWIMAGE(vidwidth * zoom, vidheight * zoom, 32)
  44.     END IF
  45.  
  46.     DO
  47.         SEEK FF, VidData + 1
  48.  
  49.         IF Audio$ = "1" THEN _SNDPLAY b&
  50.  
  51.         FOR vid = 1 TO frames
  52.             framelen$ = INPUT$(4, FF)
  53.  
  54.             frame$ = INPUT$(CVL(framelen$), FF)
  55.  
  56.             'make a temp jpg on disk
  57.             FFF = FREEFILE
  58.             OPEN "_tmp_qbv_frame_.jpg" FOR OUTPUT AS FFF
  59.             PRINT #FFF, frame$;
  60.             CLOSE FFF
  61.  
  62.             'load it
  63.             frm& = _LOADIMAGE("_tmp_qbv_frame_.jpg")
  64.             'erase it
  65.             KILL "_tmp_qbv_frame_.jpg"
  66.             '---------------------------------------
  67.             _DISPLAY
  68.             '---------------------------------------
  69.             _PUTIMAGE (x, y)-(x + (vidwidth * zoom), x + (vidheight * zoom)), frm&
  70.             _FREEIMAGE frm&
  71.  
  72.             _LIMIT fps
  73.  
  74.             'A little keyboad control if you want.
  75.             'If you don't want, comment this out....
  76.             SELECT CASE UCASE$(INKEY$)
  77.                 CASE IS = " "
  78.                     IF Audio$ = "1" THEN _SNDPAUSE b&
  79.                     pa$ = INPUT$(1)
  80.                     IF Audio$ = "1" THEN _SNDPLAY b&
  81.                 CASE IS = CHR$(27): EXIT DO 'ESC key exits
  82.             END SELECT
  83.             '---------------------------------
  84.             LOCATE 10, 10: PRINT "Welcome"
  85.             '---------------------------------
  86.         NEXT
  87.  
  88.         IF loopit <> 1 THEN EXIT DO
  89.  
  90.     LOOP
  91.  
  92.     CLOSE FF
  93.  
  94.     IF Audio$ = "1" THEN _SNDSTOP b&
  95.  
  96.  
  97.  
Title: Re: Working on a Audio+Video file format to use.
Post by: SierraKen on May 15, 2020, 09:55:21 pm
Yep graphics works too. :) Just put graphics commands next to where I put the PRINT command. I was thinking too that I bet it also could be used with other apps or games combining action inside the video. You could do an IF/THEN statement of a wide range of RGB colors to compare it with the bird using the POINT command in order to do things like feeding the bird with the mouse. There's limitless potential using videos inside games and apps if you think about it. :)
Title: Re: Working on a Audio+Video file format to use.
Post by: Dav on May 16, 2020, 12:37:58 am
Thanks, Ken! I can use all the help and suggestions! I completely forgot about _DISPLAY. Thanks for trying it all out and posting your additions.

I think this kind of utility can be useful for games - for creating intros/credits, cut scenes. I've been thinking of making a little story book app, was trying to figure out how to show a nice page turn effect. Now I can render the effect in an external video program and convert it to a QBV file to use.

- Dav
Title: Re: Working on a Audio+Video file format to use.
Post by: SierraKen on May 16, 2020, 12:07:33 pm
Welcome Dav. Another type of game people could make with this is something like the old 80's arcade game Dragon's Lair where the whole game is a bunch of videos. You control your guy with a sword and if you move at the wrong time, he dies. If you move at the right time, he passes the level. So let's say you want 20 levels. It would take around 3 videos per level. One video as the opening sequence, one video if he wins, the other video if he loses. So it would take 60 small videos for a 20 level game. Of course for a better game, you would have more game play in each level and more videos. The arcade game had some kind of laser disc inside it that played the videos as you played the game. It was in cartoon format but still really fun. If anyone is interested, here is the full game-play of the game:
https://www.youtube.com/watch?v=bRU0TaJq2eA
 (https://www.youtube.com/watch?v=bRU0TaJq2eA)
Title: Re: Working on a Audio+Video file format to use.
Post by: Dav on May 16, 2020, 12:36:09 pm
Wow Ken---we are still on the same wave length! Having the same dragons lair thought last night I started watching a video walk through on YouTube and then re-downloaded the game to my iPad.  I can't tell you how many quarters I spent playing that game long ago. And space ace too. Yes, a game like that is very possible in qb64 with this utility. 

- Dav
Title: Re: Working on a Audio+Video file format to use.
Post by: SierraKen on May 16, 2020, 02:37:49 pm
LOL Dav, awesome. Yeah there's a Dragon's Lair for PC's too now that you can get from Steam. I haven't bought it though myself. I remember the name Space Ace, cool. :)
Title: Re: Working on a Audio+Video file format to use.
Post by: SierraKen on May 16, 2020, 04:09:00 pm
I just added something else for you. When playing the video and someone presses "T" or "t" it will show the seconds of the video on the bottom left corner of the screen. When people press "T" or "t" again, it will disappear. When the video loops back to the start, it goes back to 0. I put my code in your main LOOP in the Sub. Near DO I put 2 lines: TIMER ON and start = TIMER. Then in your SELECT CASE I put code for the user to press T or t. Then using a variable for off and on, right after the SELECT CASE, I put the TIMER code. This should be useful for people wanting to stay on track with the length of the video. At first I tried to add minutes and hours, but I couldn't figure it out with the TIMER always changing, so I just kept it with seconds. I also put the seconds in that specific corner because when the digits keep adding up, they move to the right and I didn't want people to lose sight of it on the right side, so I went with the left. Oh one more thing, I used _PRINTSTRING so it stays on the bottom with any size video people make using your (vidheight * zoom) variables. I subtracted 15 pixels from them to be seen clearly. Enjoy. :)

Code: QB64: [Select]
  1. '===========
  2. 'QBVPLAY.BAS v0.10
  3. '===========
  4. 'Plays .QBV Audio/Video files.
  5. 'Coded by Dav, MAY/2020
  6. 'Modification with video timer by pressing T added by Sierraken on May 16, 2020.
  7.  
  8. SCREEN _NEWIMAGE(512, 288, 32)
  9.  
  10. 'Open file piano.qbv below.....
  11. 'set x/y pos, Zoom x2, resize screen to fit vid, loop it
  12. PlayQBV "bird.qbv", 0, 0, 2, 1, 1
  13.  
  14. SUB PlayQBV (file$, x, y, zoom, fit, loopit)
  15.     'file$ = QBV file to play
  16.     'x = x position on screen
  17.     'y = y position on screen
  18.     'zoom factor of video, 1 is regular size,
  19.     '     2 is double size, etc...
  20.     'fit = fit video to match your current screen resolution
  21.     'loopit = Loop video or not. 1 is loop, 0 is play once.
  22.  
  23.     FF = FREEFILE
  24.  
  25.     OPEN file$ FOR BINARY AS FF
  26.  
  27.     'Get info saved at end of file
  28.     SEEK FF, LOF(FF) - 19
  29.  
  30.     Ver$ = INPUT$(7, FF) 'Version of QBV video format
  31.     Audio$ = INPUT$(1, FF) 'Audio setting
  32.     vidwidth = CVI(INPUT$(2, FF)) 'Width of video
  33.     vidheight = CVI(INPUT$(2, FF)) 'Height of video
  34.     VidData = CVL(INPUT$(4, FF)) 'Place in file Video data starts
  35.     frames = CVI(INPUT$(2, FF)) 'How many frames in file
  36.     fps = CVI(INPUT$(2, FF)) 'How many fps
  37.  
  38.     IF Audio$ = "1" THEN
  39.         b& = _SNDOPEN(file$) 'Open sound file
  40.     END IF
  41.  
  42.     'Set screen based on vid setting...
  43.     IF fit = 1 THEN
  44.         SCREEN _NEWIMAGE(vidwidth * zoom, vidheight * zoom, 32)
  45.     END IF
  46.  
  47.     DO
  48.         SEEK FF, VidData + 1
  49.  
  50.         IF Audio$ = "1" THEN _SNDPLAY b&
  51.         TIMER ON
  52.         start = TIMER
  53.  
  54.         FOR vid = 1 TO frames
  55.             framelen$ = INPUT$(4, FF)
  56.  
  57.             frame$ = INPUT$(CVL(framelen$), FF)
  58.  
  59.             'make a temp jpg on disk
  60.             FFF = FREEFILE
  61.             OPEN "_tmp_qbv_frame_.jpg" FOR OUTPUT AS FFF
  62.             PRINT #FFF, frame$;
  63.             CLOSE FFF
  64.  
  65.             'load it
  66.             frm& = _LOADIMAGE("_tmp_qbv_frame_.jpg")
  67.             'erase it
  68.             KILL "_tmp_qbv_frame_.jpg"
  69.             _DISPLAY
  70.             _PUTIMAGE (x, y)-(x + (vidwidth * zoom), x + (vidheight * zoom)), frm&
  71.             _FREEIMAGE frm&
  72.  
  73.             _LIMIT fps
  74.  
  75.             'A little keyboad control if you want.
  76.             'If you don't want, comment this out....
  77.             SELECT CASE UCASE$(INKEY$)
  78.                 CASE IS = " "
  79.                     IF Audio$ = "1" THEN _SNDPAUSE b&
  80.                     pa$ = INPUT$(1)
  81.                     IF Audio$ = "1" THEN _SNDPLAY b&
  82.                 CASE IS = CHR$(27): EXIT DO 'ESC key exits
  83.                 CASE IS = "T", "t"
  84.                     ti = ti + 1
  85.                     IF ti > 1 THEN ti = 0
  86.             END SELECT
  87.             IF ti = 1 THEN
  88.                 t = TIMER
  89.                 sec = INT(t - start)
  90.                 sec$ = STR$(sec)
  91.                 _PRINTSTRING (0, (vidheight * zoom) - 15), sec$
  92.             END IF
  93.         NEXT
  94.  
  95.         IF loopit <> 1 THEN EXIT DO
  96.  
  97.     LOOP
  98.  
  99.     CLOSE FF
  100.  
  101.     IF Audio$ = "1" THEN _SNDSTOP b&
  102.  
  103.  
  104.  
Title: Re: Working on a Audio+Video file format to use.
Post by: TempodiBasic on May 16, 2020, 06:16:35 pm
Dragon's Lair!!!!
It was one of the my preferite arcade game with its pseudo 3D graphic.
Some time ago I wrote a walktrough.

Wiki reference
 https://en.wikipedia.org/wiki/Dragon%27s_Lair_(1983_video_game) (https://en.wikipedia.org/wiki/Dragon%27s_Lair_(1983_video_game))

walktrough
https://www.youtube.com/watch?v=C-dg4J9_nes (https://www.youtube.com/watch?v=C-dg4J9_nes)
Title: Re: Working on a Audio+Video file format to use.
Post by: Ashish on May 17, 2020, 11:46:47 am
Nice work Dav! This could possibly be very useful for the game I'm working on for cutscenes and some graphics effects.
Is there is way to capture graphics animation of a program itself directly?
Title: Re: Working on a Audio+Video file format to use.
Post by: Petr on May 17, 2020, 04:00:16 pm
Hi Ashish :)

What you think about?  :)  Try Dav's player to this file:

Title: Re: Working on a Audio+Video file format to use.
Post by: Petr on May 17, 2020, 04:16:50 pm
Here is the source code that will create it all. It makes both an audio track and individual images, which then form a video. To do this, I used Steve's SaveImage library v. 2.0. The only thing I needed as third-party software for was a WAV to OGG converter, so I'm attaching OGG, but you can compare the two audio files (the included OGG and the one that makes the program) that they are the same. :)

Warning: I highly recommend trying this program in a new empty folder

Next is the attached audio source file, from which a background track is then created and files needed to work the SaveImage library.

Code: QB64: [Select]
  1.  'example how record program screen to Dav's videoformat directly
  2. 'and greetings to Dav!
  3.  
  4. '$include:'saveimage.bi'
  5.  
  6. TYPE Snd
  7.     Left AS SINGLE
  8.     Right AS SINGLE
  9. REDIM SHARED OutputSound(-1) AS Snd
  10.  
  11. TYPE OtpSndHelper
  12.     Offset_Start AS LONG
  13.     Offset_End AS LONG
  14. REDIM SHARED OTP(1) AS OtpSndHelper
  15. DIM SHARED FrameCount AS LONG
  16.  
  17.  
  18. REM GOTO DOQBV
  19.  
  20.  
  21.  
  22. explo = WAVtoRAW("explosion.wav")
  23.  
  24.  
  25.  
  26.  
  27. SCREEN _NEWIMAGE(800, 600, 32)
  28. path$ = ENVIRON$("SYSTEMROOT") + "\Fonts\arialn.ttf"
  29. F = _LOADFONT(path$, 60, "monospace")
  30. s$ = "Nice work, Dav!"
  31. Sy = 300 - _FONTHEIGHT(F) / 2
  32. Sx = 400 - _PRINTWIDTH(s$) / 2
  33. Cx = _PRINTWIDTH(s$) / LEN(s$)
  34. REDIM VideoSoundTrack(0) AS Snd
  35. ScreenScanner = 1 / 15 '15 FPS
  36.  
  37.  
  38. Control = TIMER
  39. ON TIMER(ScreenScanner) GOSUB SaveScreen
  40. TimePos = 0
  41. FOR p = 1 TO LEN(s$)
  42.     COLOR _RGB32(RND * 255, RND * 255, RND * 127)
  43.     _PRINTSTRING (Sx + Cx * (p - 1), Sy), MID$(s$, p, 1)
  44.     IF MID$(s$, p, 1) <> CHR$(32) THEN
  45.         RAWCOPY explo, VideoSoundTrack(), TimePos
  46.         RAWPLAY explo
  47.         TimePos = TimePos + RAWLEN(explo) 'rawlen return sound lenght in seconds
  48.     END IF
  49.     DO UNTIL _SNDRAWLEN = 0: LOOP
  50.  
  51. PRINT "Total time:"; TIMER - Control; "15 FPS>>>>"; INT(15 * (TIMER - Control)); " frames"
  52. PRINT "Saving video sound track..."
  53.  
  54. SAVESOUND16S VideoSoundTrack(), "ForDav.wav" 'sound track for video is done (now just convert it to OGG)
  55.  
  56. PRINT "Converting BMPs to JPGs"
  57. FOR c = 0 TO FrameCount - 1
  58.     i = _LOADIMAGE(STR$(c) + ".bmp", 32)
  59.     Result = SaveImage(STR$(c) + ".jpg", i, 0, 0, _WIDTH(i), _HEIGHT(i))
  60.     LOCATE 4
  61.     PRINT "["; INT(c / (FrameCount - 1) * 100); "%]"
  62.     _FREEIMAGE i
  63.     KILL STR$(c) + ".bmp"
  64.  
  65.  
  66.  
  67. DOQBV:
  68. PRINT "Creating QBV"
  69.  
  70. 'here continue Dav's source:
  71.  
  72.  
  73.  
  74.  
  75. '===========
  76. 'QBVMAKE.BAS v0.10
  77. '===========
  78. 'Makes .QBV Audio/Video files for QB64.
  79. 'Uses .jpg image sequences and .ogg sound files.
  80. 'Coded by Dav, MAY/2020
  81.  
  82. 'QBVMAKE makes a .QBV audio/video file using a sequence
  83. 'of .jpg images and uses an .OGG sound file to add audio.
  84. 'This way you can make and use video files in you projects.
  85.  
  86. 'This demo builds a video called BIRD.QBV in the current
  87. 'directory.  It will then play the video.  This is only an
  88. 'example so you can see how to make your own .QBV video.
  89.  
  90. 'NOTE: YOU WILL HAVE TO ADAPT THIS CODE FOR YOUR FILES
  91.  
  92. '===========================================================
  93.  
  94. ' SET YOUR OWN QBV INFORMATION IN THIS AREA.....
  95. ' The following are my demo file settings.
  96. ' You will need to replace them with your own.
  97.  
  98. QBV$ = "ForDav.qbv" '<<<--- NAME OF YOUR QBV TO MAKE
  99.  
  100. 'Point to your image sequence location below and prefix
  101. 'My images are saved like, bird000.jpg.....
  102. source$ = _CWD$ '<<<---- YOUR IMAGE DIRECTORY
  103.  
  104. OGG$ = "ForDav.ogg" '<<<--- Name of you .OGG file
  105.  
  106. '------
  107.  
  108. 'NOW SET YOUR VIDEO INFO BELOW...
  109.  
  110. Audio = 1 '<<<--- SET TO 1 IF ADDING AUDIO, 0 IF NO AUDIO
  111. fps = 15 'My demo video has 15 frames per second
  112. frames = FrameCount - 1
  113. vidwidth = 801 'The width of my video image files
  114. vidheight = 601 'The height of my video image files
  115.  
  116. '==============================================================
  117.  
  118. 'Now here we start making the QBV file....
  119.  
  120. OPEN QBV$ FOR OUTPUT AS #1
  121.  
  122. 'If adding audio, copy it first...
  123. IF Audio = 1 THEN
  124.     OPEN OGG$ FOR BINARY AS #3
  125.     SL = LOF(3) ''Length of OGG sound file...
  126.     'save it to QBV file
  127.     A$ = INPUT$(SL, 3): PRINT #1, A$;: CLOSE #3
  128.     SL = 0 'No audio size at all
  129.  
  130. 'Now we same the jpg images to the .QBV file.
  131. 'We start at frame 0, because image sequences start at 0 usually.
  132. 'This is set to use 0000 series numbers (ie: bird0000.jpg)
  133. 'If yours are different, you will have to adjust the code.
  134.  
  135. 'Go through images...
  136. FOR t = 0 TO frames - 1
  137.  
  138.     'load a .jpg image file (a frame)
  139.     tag$ = LTRIM$(STR$(t))
  140.     IF LEN(tag$) = 3 THEN tag$ = "0" + tag$
  141.     IF LEN(tag$) = 2 THEN tag$ = "00" + tag$
  142.     IF LEN(tag$) = 1 THEN tag$ = "000" + tag$
  143.     '    f$ = source$ + tag$ + ".jpg"
  144.  
  145.     f$ = STR$(t) + ".jpg"
  146.  
  147.     OPEN f$ FOR BINARY AS 7
  148.     'Grab it, CLOSE it
  149.     frame$ = INPUT$(LOF(7), 7): CLOSE 7
  150.  
  151.     'Get size of frame
  152.     framelen$ = MKL$(LEN(frame$))
  153.  
  154.     'Save it's length to file
  155.     PRINT #1, framelen$;
  156.  
  157.     'Now save the frame data to file
  158.     PRINT #1, frame$;
  159.  
  160.     CLS
  161.     PRINT "============="
  162.     PRINT "QBVMAKE v0.10"
  163.     PRINT "============="
  164.     PRINT
  165.     PRINT "Making .QBV file: "; UCASE$(QBV$)
  166.     IF Auido$ = "0" THEN OGG$ = "(no audio)"
  167.     PRINT "Using audio file: "; OGG$
  168.     PRINT "Adding frame"; t + 1; "of"; frames; "..."
  169.  
  170.  
  171. 'Now we add a Footer to the end of the .QBV file.
  172. 'This will save all the .QBV settings information.
  173.  
  174. 'Set what version of .QBV file this is.
  175. PRINT #1, "QBV0.10";
  176.  
  177. 'Set if QBV has audio of not.
  178. IF Audio = 1 THEN
  179.     PRINT #1, "1";
  180.     PRINT #1, "0";
  181.  
  182. 'Save the width of video
  183. PRINT #1, MKI$(vidwidth);
  184.  
  185. 'Save the height of video
  186. PRINT #1, MKI$(vidheight);
  187.  
  188. 'Now, save the OGG file size to the end in MKL format
  189. PRINT #1, MKL$(SL);
  190.  
  191. 'Now save number of frames in MKI format
  192. PRINT #1, MKI$(frames);
  193.  
  194. 'Now save FPS to file in MKI format
  195. PRINT #1, MKI$(fps);
  196.  
  197.  
  198. PRINT "Done!"
  199. PRINT "Press any key to playback...."
  200. A$ = INPUT$(1)
  201.  
  202. '============================================================
  203.  
  204. 'Now lets play back the video we just made....
  205.  
  206. SCREEN _NEWIMAGE(800, 600, 32) 'Open a 32 bit screen first
  207.  
  208. 'Open the demo file bird.qbv below.....
  209. 'set x/y pos, Zoom x2, resize screen to fit vid, loop option
  210. PlayQBV "ForDav.qbv", 0, 0, 2, 1, 1
  211.  
  212.  
  213. '=============================================================
  214.  
  215.  
  216.  
  217. SaveScreen:
  218. SaveFullBMP (STR$(FrameCount) + ".bmp") 'JPG save is slow, therefore i use fastest saving method to BMP
  219. FrameCount = FrameCount + 1
  220.  
  221.  
  222. SUB PlayQBV (file$, x, y, zoom, fit, loopit) 'Dav's original SUB
  223.     'file$ = QBV file to play
  224.     'x = x position on screen
  225.     'y = y position on screen
  226.     'zoom factor of video, 1 is regular size,
  227.     '     2 is double size, etc...
  228.     'fit = fit video to match your current screen resolution
  229.     'loopit = Loop video or not. 1 is loop, 0 is play once.
  230.  
  231.     FF = FREEFILE
  232.  
  233.     OPEN file$ FOR BINARY AS FF
  234.  
  235.     'Get info saved at end of file
  236.     SEEK FF, LOF(FF) - 19
  237.  
  238.     Ver$ = INPUT$(7, FF) 'Version of QBV video format
  239.     Audio$ = INPUT$(1, FF) 'Audio setting
  240.     vidwidth = CVI(INPUT$(2, FF)) 'Width of video
  241.     vidheight = CVI(INPUT$(2, FF)) 'Height of video
  242.     VidData = CVL(INPUT$(4, FF)) 'Place in file Video data starts
  243.     frames = CVI(INPUT$(2, FF)) 'How many frames in file
  244.     fps = CVI(INPUT$(2, FF)) 'How many fps
  245.  
  246.     IF Audio$ = "1" THEN
  247.         b& = _SNDOPEN(file$) 'Open sound file
  248.     END IF
  249.  
  250.     'Set screen based on vid setting...
  251.     IF fit = 1 THEN
  252.         SCREEN _NEWIMAGE(vidwidth * zoom, vidheight * zoom, 32)
  253.     END IF
  254.  
  255.     DO
  256.         SEEK FF, VidData + 1
  257.  
  258.         IF Audio$ = "1" THEN _SNDPLAY b&
  259.  
  260.         FOR vid = 1 TO frames
  261.             framelen$ = INPUT$(4, FF)
  262.  
  263.             frame$ = INPUT$(CVL(framelen$), FF)
  264.  
  265.             'make a temp jpg on disk
  266.             FFF = FREEFILE
  267.             OPEN "_tmp_qbv_frame_.jpg" FOR OUTPUT AS FFF
  268.             PRINT #FFF, frame$;
  269.             CLOSE FFF
  270.  
  271.             'load it
  272.             frm& = _LOADIMAGE("_tmp_qbv_frame_.jpg")
  273.             'erase it
  274.             KILL "_tmp_qbv_frame_.jpg"
  275.  
  276.             _PUTIMAGE (x, y)-(x + (vidwidth * zoom), x + (vidheight * zoom)), frm&
  277.             _FREEIMAGE frm&
  278.  
  279.             _LIMIT fps
  280.  
  281.             'A little keyboad control if you want.
  282.             'If you don't want, comment this out....
  283.             SELECT CASE UCASE$(INKEY$)
  284.                 CASE IS = " "
  285.                     IF Audio$ = "1" THEN _SNDPAUSE b&
  286.                     pa$ = INPUT$(1)
  287.                     IF Audio$ = "1" THEN _SNDPLAY b&
  288.                 CASE IS = CHR$(27): EXIT DO 'ESC key exits
  289.             END SELECT
  290.  
  291.         NEXT
  292.  
  293.         IF loopit <> 1 THEN EXIT DO
  294.  
  295.     LOOP
  296.  
  297.     CLOSE FF
  298.  
  299.     IF Audio$ = "1" THEN _SNDSTOP b&
  300.  
  301.  
  302.  
  303.  
  304.  
  305. FUNCTION RAWLEN (handle)
  306.     RAWLEN = OTP(handle).Offset_End - OTP(handle).Offset_Start / 44100
  307.  
  308.  
  309. SUB SAVESOUND16S (arr() AS Snd, file AS STRING)
  310.  
  311.     TYPE head16
  312.         chunk AS STRING * 4 '       4 bytes  (RIFF)
  313.         size AS LONG '              4 bytes  (file size)
  314.         fomat AS STRING * 4 '       4 bytes  (WAVE)
  315.         sub1 AS STRING * 4 '        4 bytes  (fmt )
  316.         subchunksize AS LONG '      4 bytes  (lo / hi), $00000010 for PCM audio
  317.         format AS INTEGER '         2 bytes  (0001 = standard PCM, 0101 = IBM mu-law, 0102 = IBM a-law, 0103 = IBM AVC ADPCM)
  318.         channels AS INTEGER '       2 bytes  (1 = mono, 2 = stereo)
  319.         rate AS LONG '              4 bytes  (sample rate, standard is 44100)
  320.         ByteRate AS LONG '          4 bytes  (= sample rate * number of channels * (bits per channel /8))
  321.         Block AS INTEGER '          2 bytes  (block align = number of channels * bits per sample /8)
  322.         Bits AS INTEGER '           2 bytes  (bits per sample. 8 = 8, 16 = 16)
  323.         subchunk2 AS STRING * 4 '   4 bytes  ("data")  contains begin audio samples
  324.         lenght AS LONG '            4 bytes  Data block size
  325.     END TYPE '                     44 bytes  total
  326.     DIM H16 AS head16
  327.     ch = FREEFILE
  328.  
  329.     H16.chunk = "RIFF"
  330.     H16.size = 44 + UBOUND(arr) * 4 'two channels, it create 16 bit, stereo wav file, one sample use 2 bytes to one channel
  331.  
  332.     H16.fomat = "WAVE"
  333.     H16.sub1 = "fmt "
  334.     H16.subchunksize = 16
  335.     H16.format = 1
  336.     H16.channels = 2
  337.     H16.rate = 44100
  338.     H16.ByteRate = 44100 * 2 * 16 / 8
  339.     H16.Block = 4
  340.     H16.Bits = 16
  341.     H16.subchunk2 = "data"
  342.     H16.lenght = UBOUND(arr) * 4
  343.     IF _FILEEXISTS(file$) THEN KILL file$
  344.  
  345.     OPEN file$ FOR BINARY AS #ch
  346.     PUT #ch, , H16
  347.     DIM LeftChannel AS INTEGER, RightChannel AS INTEGER
  348.  
  349.     FOR audiodata = 0 TO UBOUND(arr)
  350.         LeftChannel = arr(audiodata).Left * 32768
  351.         RightChannel = arr(audiodata).Right * 32768
  352.  
  353.         PUT #ch, , LeftChannel
  354.         PUT #ch, , RightChannel
  355.     NEXT
  356.     CLOSE ch
  357.  
  358.  
  359. SUB RAWCOPY (handle, arr() AS Snd, position AS LONG)
  360.     SoundLenghtInBytes = OTP(handle).Offset_End - OTP(handle).Offset_Start
  361.     '    IF UBOUND(arr) < UBOUND(arr) + SoundLenghtInBytes + position THEN REDIM _PRESERVE arr(UBOUND(arr) + SoundLenghtInBytes + position) AS Snd
  362.     REDIM _PRESERVE arr(position + SoundLenghtInBytes) AS Snd
  363.     DIM rc AS LONG, OTPS AS LONG
  364.     OTPS = OTP(handle).Offset_Start
  365.     FOR rc = position TO position + SoundLenghtInBytes
  366.  
  367.         IF arr(rc).Left THEN OutLeft = (arr(rc).Left + OutputSound(OTPS).Left) ELSE OutLeft = OutputSound(OTPS).Left
  368.         IF arr(rc).Right THEN OutRight = (arr(rc).Right + OutputSound(OTPS).Right) ELSE OutRight = OutputSound(OTPS).Right
  369.  
  370.         IF OutLeft > .9 THEN OutLeft = .9
  371.         IF OutLeft < -.9 THEN OutLeft = -.9
  372.  
  373.         IF OutRight > .9 THEN OutRight = .9
  374.         IF OutRight < -.9 THEN OutRight = -.9
  375.  
  376.         arr(rc).Left = OutLeft
  377.         arr(rc).Right = OutRight
  378.  
  379.         '   arr(rc).Left = OutputSound(OTPS).Left
  380.         '   arr(rc).Right = OutputSound(OTPS).Right
  381.         OTPS = OTPS + 1
  382.     NEXT rc
  383.  
  384.  
  385. FUNCTION WAVtoRAW (file$) '                              Function load WAV file (this just 16bit, stereo format) and load it to array as RAW.
  386.     TYPE head
  387.         chunk AS STRING * 4 '       4 bytes  (RIFF)
  388.         size AS LONG '              4 bytes  (?E??)
  389.         fomat AS STRING * 4 '       4 bytes  (WAVE)
  390.         sub1 AS STRING * 4 '        4 bytes  (fmt )
  391.         subchunksize AS LONG '      4 bytes  (lo / hi), $00000010 for PCM audio
  392.         format AS STRING * 2 '      2 bytes  (0001 = standard PCM, 0101 = IBM mu-law, 0102 = IBM a-law, 0103 = IBM AVC ADPCM)
  393.         channels AS INTEGER '       2 bytes  (1 = mono, 2 = stereo)
  394.         rate AS LONG '              4 bytes  (sample rate, standard is 44100)
  395.         ByteRate AS LONG '          4 bytes  (= sample rate * number of channels * (bits per channel /8))
  396.         Block AS INTEGER '          2 bytes  (block align = number of channels * bits per sample /8)
  397.         Bits AS INTEGER '           2 bytes  (bits per sample. 8 = 8, 16 = 16)
  398.         subchunk2 AS STRING * 4 '   4 bytes  ("data")  contains begin audio samples
  399.     END TYPE '                     40 bytes  total
  400.     DIM H AS head
  401.     ch = FREEFILE
  402.  
  403.     IF _FILEEXISTS(file$) THEN OPEN file$ FOR BINARY AS #ch ELSE PRINT file$; " not found": SLEEP 2: SYSTEM
  404.     GET #ch, , H
  405.  
  406.     block = H.Block
  407.     RATE = H.rate
  408.     chan = H.channels
  409.     bits = H.Bits
  410.  
  411.     SEEK #ch, Find_data_area(file$)
  412.  
  413.     OTP_Size = UBOUND(otp)
  414.     OTP(OTP_Size).Offset_Start = UBOUND(outputsound) + 1
  415.  
  416.     DO WHILE NOT EOF(ch)
  417.         IF bits = 16 AND chan = 2 THEN
  418.             REDIM lefi AS INTEGER, righi AS INTEGER
  419.             GET #ch, , lefi
  420.             GET #ch, , righi
  421.             lef = lefi / 65536
  422.             righ = righi / 65536
  423.         END IF
  424.  
  425.         IF RATE > 44100 THEN frekvence = RATE ELSE frekvence = 44100
  426.  
  427.         oss = UBOUND(OutputSound)
  428.         REDIM _PRESERVE OutputSound(oss + (frekvence / RATE)) AS Snd
  429.  
  430.         FOR plll = 1 TO frekvence / RATE
  431.             OutputSound(oss + plll).Left = lef
  432.             OutputSound(oss + plll).Right = righ
  433.         NEXT plll
  434.  
  435.         DO WHILE _SNDRAWLEN > 0: LOOP: REM comment this
  436.     LOOP
  437.  
  438.     OTP(OTP_Size).Offset_End = UBOUND(outputsound)
  439.     REDIM _PRESERVE OTP(OTP_Size + 1) AS OtpSndHelper
  440.     CLOSE ch
  441.     WAVtoRAW = OTP_Size
  442.  
  443. SUB RAWPLAY (handle) '                                                      Play file content from RAW array (array OutputSounds)
  444.     FOR Playi = OTP(handle).Offset_Start TO OTP(handle).Offset_End
  445.         _SNDRAW OutputSound(Playi).Left, OutputSound(Playi).Right
  446.     NEXT
  447.  
  448. FUNCTION Find_data_area (handle$)
  449.     REDIM D AS STRING * 10024
  450.     ff = FREEFILE
  451.     OPEN handle$ FOR BINARY AS #ff
  452.     GET #ff, 1, D$
  453.     CLOSE #ff
  454.     Find_data_area = INSTR(1, D$, "data") + 8
  455.     D$ = ""
  456. '$include:'saveimage.bm'
  457.  
Title: Re: Working on a Audio+Video file format to use.
Post by: Dav on May 17, 2020, 08:28:51 pm
Thanks, Petr!  That very nice!

- Dav
Title: Re: Working on a Audio+Video file format to use.
Post by: Dav on May 24, 2020, 10:04:40 pm
Hey @SierraKen,  I was playing with your tweaked version with _DISPLAY added, I paused playback and minimized it, and discovered something very interesting I never noticed before with _DISPLAY.   If you minimize a QB64 program while automatic display is turned off (if under _DISPLAY)  then the program screen will be blank when you maximize it again, util the screen is updated again.  Here's a short example...

Code: QB64: [Select]
  1. PRINT "Minimize this and the screen will be blank when maximzing it again"
  2.  
  3.  

I have never accounted for this in any of my programs. Many of my games posted here, which use _DISPLAY a bunch,  go blank when I minimize them.  I need to adjust my code from here on to allow for this.

So in your version of QBVPLAY.BAS, I added an _AUTODISPLAY when hiting the pause key and the screen won't go blank when minimizing/maximizing while paused.


- Dav

Title: Re: Working on a Audio+Video file format to use.
Post by: Petr on May 25, 2020, 09:56:55 am

This problem can be solved:

Code: [Select]
PRINT "Minimize this and the screen will be blank when maximzing it again"
_DISPLAY
IF _SCREENICON = 0 THEN _AUTODISPLAY
SLEEP