Page 1 of 2

Is there an easy way to add text to an mp4 video

Posted: Wed Jan 08, 2014 11:46 pm
by normeus
I need to add some text to a few mp4 videos I looked at OpenCV and it looks great but it is huge. I just want to add stuff like "kitchen" or "bedroom 12/23/2014" on the actual video.

If I have to do it using OpenCV then I will. Has anyone tried something similar with anything else ( any other smaller library)


Norm.

Re: Is there an easy way to add text to an mp4 video

Posted: Thu Jan 09, 2014 1:54 am
by idle
if it's on windows yes it should be easy enough to do via AVIFIL32.DLL
There should be some code floating around on the forum

Writing bmp to video
http://www.purebasic.fr/english/viewtop ... 16&t=15466

If you can't find any code to grab the frame from a video
There's the old NeHe opengl tutorials about rendering video to a texture
http://nehe.gamedev.net/tutorial/playin ... ngl/23001/

Re: Is there an easy way to add text to an mp4 video

Posted: Thu Jan 09, 2014 6:15 pm
by JHPJHP
Hi normeus,

Yes OpenCV is quite large, but it can be broken down for smaller tasks
- DLLs are for Vista and above... if your using XP download the complete package and extract the appropriate version
-- opencv_core248.dll
-- opencv_core248.lib
-- opencv_highgui248.dll
-- opencv_highgui248.lib

The example adds text to the webcam view, but it can be easily modified to work with an MP4.
- see cv_mov_hough.pb example

NB*: Combined Constants, Structures, Functions, and Procedures into the main file... also included a compiled executable.
- cv_*.pb examples use an OpenCV window, but for a more dynamic interface the pb_*.pb examples embed the OpenCV frame into a PureBasic window

Let me know if this works for you - Cheers!

Re: Is there an easy way to add text to an mp4 video

Posted: Thu Jan 09, 2014 8:57 pm
by normeus
Thank you idle, it is windows 7 and it has to run on windows 8.

JHPJHP, thank you. I modified "cv_mov_hough.pb" since it was opening an mp4 file to begin with. It is not saving the file ( I don't know how to do it yet ) but it is a start.
replace this line:

Code: Select all

    *capture = cvCreateFileCapture("G:\home-mov-0005.mp4") ;norm added
with your own mp4 file and location

here is the code:

Code: Select all

IncludeFile "includes/cv_functions.pbi"

Global lpPrevWndFunc

#CV_WINDOW_NAME = "PureBasic Interface to OpenCV"
;#CV_DESCRIPTION = "Finds circles in grayscale image frames using the Hough transform on a movie file."
#CV_DESCRIPTION = "add text to a movie file / save it?"
font2.CvFont
cvInitFont(@font2, #CV_FONT_HERSHEY_SIMPLEX , 0.5, 1.0, #Null, 1, #CV_AA)



Procedure WindowCallback(hWnd, Msg, wParam, lParam)
  Shared ExitCV.b

  Select Msg
    Case #WM_COMMAND
      Select wParam
        Case 10
          ExitCV = #True
      EndSelect
    Case #WM_DESTROY
      ExitCV = #True
  EndSelect
  ProcedureReturn CallWindowProc_(lpPrevWndFunc, hWnd, Msg, wParam, lParam)
EndProcedure

ProcedureC CvMouseCallback(event, x, y, flags, *param.USER_INFO)
  Select event
    Case #CV_EVENT_RBUTTONDOWN
      DisplayPopupMenu(0, *param\uValue)
  EndSelect
EndProcedure

Repeat
  nCreate + 1
    *capture = cvCreateFileCapture("G:\home-mov-0005.mp4") ;norm added
Until nCreate = 5 Or *capture

If *capture
  cvNamedWindow(#CV_WINDOW_NAME, #CV_WINDOW_AUTOSIZE)
  window_handle = cvGetWindowHandle(#CV_WINDOW_NAME)
  *window_name = cvGetWindowName(window_handle)
  lpPrevWndFunc = SetWindowLongPtr_(window_handle, #GWL_WNDPROC, @WindowCallback())

  If CreatePopupImageMenu(0, #PB_Menu_ModernLook)
    MenuItem(10, "Exit")
  EndIf
  hWnd = GetParent_(window_handle)
  ExtractIconEx_("shell32.dll", 1, #Null, @phiconSmall, 1)
  SendMessage_(hWnd, #WM_SETICON, 0, phiconSmall)
  wStyle = GetWindowLongPtr_(hWnd, #GWL_STYLE)
  SetWindowLongPtr_(hWnd, #GWL_STYLE, wStyle & ~(#WS_MAXIMIZEBOX | #WS_MINIMIZEBOX | #WS_SIZEBOX))
  cvMoveWindow(#CV_WINDOW_NAME, 20, 20)
  ToolTip(window_handle, #CV_DESCRIPTION)
  FrameWidth = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH)
  FrameHeight = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT)
  *gray.IplImage = cvCreateImage(FrameWidth, FrameHeight, #IPL_DEPTH_8U, 1)
  *storage = cvCreateMemStorage(0)
  *element.CvPoint3D32f
  *image.IplImage
  *param.USER_INFO = AllocateMemory(SizeOf(USER_INFO))
  *param\uValue = window_handle
  cvSetMouseCallback(*window_name, @CvMouseCallback(), *param)

  Repeat
    *image = cvQueryFrame(*capture)

    If *image
      cvPutText(*image, "Attic 01/09/2014", 30, 350, @font2, 255, 0, 0, 0) ; norm added
      cvPutText(*image, "Attic 01/09/2014", 32, 350, @font2, 255, 255, 255, 0) ; norm added
      cvClearMemStorage(*storage)
      cvShowImage(#CV_WINDOW_NAME, *image)
      keyPressed = cvWaitKey(10)
    Else
      Break
    EndIf
  Until keyPressed = 27 Or ExitCV
  FreeMemory(*param)
  cvReleaseMemStorage(@*storage)
  cvReleaseImage(@*gray)
  cvDestroyWindow(#CV_WINDOW_NAME)
  cvReleaseCapture(@*capture)
EndIf
also don't forget to change the text that is displayed on the screen by changing these lines:

Code: Select all

      cvPutText(*image, "Attic 01/09/2014", 30, 350, @font2, 255, 0, 0, 0) ; norm added
      cvPutText(*image, "Attic 01/09/2014", 32, 350, @font2, 255, 255, 255, 0) ; norm added
I really don't want to display anything just get the file, add text and save the file. I will post some code when I figure this out

Norm.

Re: Is there an easy way to add text to an mp4 video

Posted: Thu Jan 09, 2014 9:08 pm
by JHPJHP
Hi normeus,

Concerning:
... It is not saving the file ...
See the example: cv_cam_capture_2b.pb

Also you need/should remove the following bits of code from the example your creating:

Code: Select all

FrameWidth = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH)
FrameHeight = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT)
*gray.IplImage = cvCreateImage(FrameWidth, FrameHeight, #IPL_DEPTH_8U, 1)
*storage = cvCreateMemStorage(0)
*element.CvPoint3D32f
...
cvClearMemStorage(*storage)
...
cvReleaseMemStorage(@*storage)
cvReleaseImage(@*gray)
NB*: Also be aware of the playing speed (FPS), affected by the following:
- keyPressed = cvWaitKey(10)
- cvCreateVideoWriter (currently set to 7 in cv_cam_capture_2b.pb example)
-- CV_FOURCC("M", "S", "V", "C") is a Macro and will need to be included: /includes/cv_macros.pbi (may need to change the codec for .mp4)

Re: Is there an easy way to add text to an mp4 video

Posted: Thu Jan 09, 2014 10:14 pm
by JHPJHP
Hi normeus,

I decided to create an example... I may add it to the OpenCV package tonight (after more testing with setting changes) if I can keep the size under control:
- converts .mp4 to .avi (2 MB to 80 MB) :shock:

Code: Select all

IncludeFile "includes/cv_functions.pbi"

Global lpPrevWndFunc

#CV_WINDOW_NAME = "PureBasic Interface to OpenCV"
#CV_DESCRIPTION = "Adds text to a movie file and saves it as an AVI."

Procedure WindowCallback(hWnd, Msg, wParam, lParam)
  Shared ExitCV.b

  Select Msg
    Case #WM_COMMAND
      Select wParam
        Case 10
          ExitCV = #True
      EndSelect
    Case #WM_DESTROY
      ExitCV = #True
  EndSelect
  ProcedureReturn CallWindowProc_(lpPrevWndFunc, hWnd, Msg, wParam, lParam)
EndProcedure

ProcedureC CvMouseCallback(event, x, y, flags, *param.USER_INFO)
  Select event
    Case #CV_EVENT_RBUTTONDOWN
      DisplayPopupMenu(0, *param\uValue)
  EndSelect
EndProcedure

Repeat
  nCreate + 1
  *capture = cvCreateFileCapture("movies/ball.mp4")
Until nCreate = 5 Or *capture

If *capture
  cvNamedWindow(#CV_WINDOW_NAME, #CV_WINDOW_AUTOSIZE)
  window_handle = cvGetWindowHandle(#CV_WINDOW_NAME)
  *window_name = cvGetWindowName(window_handle)
  lpPrevWndFunc = SetWindowLongPtr_(window_handle, #GWL_WNDPROC, @WindowCallback())

  If CreatePopupImageMenu(0, #PB_Menu_ModernLook)
    MenuItem(10, "Exit")
  EndIf
  hWnd = GetParent_(window_handle)
  ExtractIconEx_("shell32.dll", 1, #Null, @phiconSmall, 1)
  SendMessage_(hWnd, #WM_SETICON, 0, phiconSmall)
  wStyle = GetWindowLongPtr_(hWnd, #GWL_STYLE)
  SetWindowLongPtr_(hWnd, #GWL_STYLE, wStyle & ~(#WS_MAXIMIZEBOX | #WS_MINIMIZEBOX | #WS_SIZEBOX))
  cvMoveWindow(#CV_WINDOW_NAME, 20, 20)
  ToolTip(window_handle, #CV_DESCRIPTION)

  If FileSize("../Videos") <> -2 : CreateDirectory("../Videos") : EndIf

  sVideo.s = "../Videos/ball.avi"
  size.CvSize
  size\width = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH)
  size\height = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT)
  *writer = cvCreateVideoWriter(sVideo, CV_FOURCC("M", "S", "V", "C"), 30, @size, 0)

  If *writer
    x = 20
    font.CvFont
    cvInitFont(@font, #CV_FONT_HERSHEY_SCRIPT_COMPLEX, 1.5, 1.5, #Null, 1, #CV_AA)
    *image.IplImage
    *param.USER_INFO = AllocateMemory(SizeOf(USER_INFO))
    *param\uValue = window_handle
    cvSetMouseCallback(*window_name, @CvMouseCallback(), *param)

    Repeat
      *image = cvQueryFrame(*capture)

      If *image
        If x = 20 : adjust.b = #True : ElseIf x = 150 : adjust = #False : EndIf
        If adjust : x + 5 : Else : x - 5 : EndIf

        cvPutText(*image, "JHPJHP", x, 50, @font, 0, 0, 255, 0)
        cvWriteFrame(*writer, *image)
        cvShowImage(#CV_WINDOW_NAME, *image)
        keyPressed = cvWaitKey(1)
      Else
        Break
      EndIf
    Until keyPressed = 27 Or ExitCV
    FreeMemory(*param)
    cvReleaseVideoWriter(@*writer)
  EndIf
  cvDestroyWindow(#CV_WINDOW_NAME)
  cvReleaseCapture(@*capture)
EndIf

Re: Is there an easy way to add text to an mp4 video

Posted: Thu Jan 09, 2014 10:52 pm
by normeus
Thanks JHPJHP,

I need the quality to be the same as the input file. I am using an mp4 file from an iPhone:

Video: MPEG4 Video (H264) 480x360 29.91fps [Core Media Video]
Audio: AAC 44100Hz mono 64Kbps [Core Media Audio]

I haven't tried your sample but on mine the quality went down the hill.
I will try your sample.
I just figure I should post right away to thank you.

Norm.

Re: Is there an easy way to add text to an mp4 video

Posted: Thu Jan 09, 2014 11:39 pm
by JHPJHP
You're welcome...

I see that there is an audio component to your requirements, don't waste anymore time with OpenCV - it's "mainly a computer vision library" that supports a single video track, no audio.

You should probably look deeper into the links idle posted.

Re: Is there an easy way to add text to an mp4 video

Posted: Fri Jan 10, 2014 12:10 am
by normeus
Audio is not really needed it just comes with the video.

Is there a way to maintain the quality of the video even if the avi file is larger?

Norm.

Re: Is there an easy way to add text to an mp4 video

Posted: Fri Jan 10, 2014 12:26 am
by JHPJHP
Yes,

(original file 2.5 MB)

AVI Type 1 and Lossless Compression (455 MB):

Code: Select all

sVideo.s = "../Videos/ball.avi"
fps.d = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FPS)
size.CvSize
size\width = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH)
size\height = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT)
*writer = cvCreateVideoWriter(sVideo, #CV_FOURCC_DEFAULT, fps, @size, #False)
AVI Type 1 with negligible quality loss (227 MB):

Code: Select all

sVideo.s = "../Videos/ball.avi"
fps.d = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FPS)
size.CvSize
size\width = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH)
size\height = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT)
*writer = cvCreateVideoWriter(sVideo, CV_FOURCC("i", "Y", "U", "V"), fps, @size, #False)
AVI Type 1 with some quality loss (76 MB):

Code: Select all

sVideo.s = "../Videos/ball.avi"
fps.d = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FPS)
size.CvSize
size\width = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH)
size\height = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT)
*writer = cvCreateVideoWriter(sVideo, CV_FOURCC("M", "S", "V", "C"), fps, @size, #False)
AVI Type 1 with some quality loss (26.5 MB):

Code: Select all

sVideo.s = "../Videos/ball.avi"
fps.d = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FPS)
size.CvSize
size\width = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH)
size\height = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT)
*writer = cvCreateVideoWriter(sVideo, CV_FOURCC("C", "V", "I", "D"), fps, @size, #False)
NB*: Video may show at a different frame-rate then the original while recording, but should record / playback correctly.

NB**: OpenCV is also supported on Linux/MAC, Andriod, and iOS - possibly write the app for the required platform(s) and only pass the video?

Re: Is there an easy way to add text to an mp4 video

Posted: Fri Jan 10, 2014 12:50 am
by IdeasVacuum
Try experimenting with AVI codecs normeus, there are a lot out there for free.
Another possibility of course is to convert to AVI, no compression, add the text required, then compress the AVI to another format.

Re: Is there an easy way to add text to an mp4 video

Posted: Fri Jan 10, 2014 2:40 am
by JHPJHP
IdeasVacuum is definitely on to something... refer to my previous (updated) post.
- codec must be installed, use: #CV_FOURCC_PROMPT (-1) to see available list
- http://www.fourcc.org/codecs.php

Code: Select all

sVideo.s = "../Videos/ball.avi"
fps.d = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FPS)
size.CvSize
size\width = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH)
size\height = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT)
*writer = cvCreateVideoWriter(sVideo, #CV_FOURCC_PROMPT, fps, @size, #False)
Small update... set fps to fps.d (more accurate frame-rate).

Re: Is there an easy way to add text to an mp4 video

Posted: Mon Jan 13, 2014 6:17 am
by normeus
I downloaded this codec
http://www.ffmpeg.org/download.html

and now my 3 meg mp4 became an 8 meg AVI which is good enough for me. ( it was 134 meg before )

I have 5 videos which after I add text I would like to join together, am I able to create a transition with openCV?

I was thinking of just open next video for read and writing to same output file but that wont give me a transition.

Thank you,
Norm

Re: Is there an easy way to add text to an mp4 video

Posted: Mon Jan 13, 2014 8:14 am
by JHPJHP
Hi normeus,

It looks like that codec is defined as: CV_FOURCC("F", "F", "V", "1")
- http://www.fourcc.org/codecs.php
- so many to choose from, glad you found something that works
I was thinking of just open next video for read and writing to same output file but that wont give me a transition.
I think that's exactly how you should do it, remember you're working with frames; just build the transitions. Frames can be included as individual images, or modified from the two videos, etc.

Everything you should need can be found with the included examples, but if you're having any trouble I'll be happy to help.

Re: Is there an easy way to add text to an mp4 video

Posted: Mon Jan 13, 2014 7:44 pm
by normeus
Thanks JHPJHP,

I downloaded multiple codecs but the one that is giving me 8meg avi from 4 meg mp3 is this one:

http://ffdshow-tryout.sourceforge.net/download.php

the encoder quality is set to 95 with no visible distortion and it will show as "ffdshow Video Codec" on your computer

just in case any one is interested.

Norm.