PDA

View Full Version : ضبط فیلم از دسکتاپ



Hamidreza Bozorg
سه شنبه 26 دی 1391, 11:53 صبح
اگه کسی بلده لطفا راهنماییم کنه
دارم کلافه میشم :افسرده:
میخوام یه برنامه ای بنویسم که از دسکتاپ فیلم برداری کنه بعدشم ذخیره کنه
لطفا اگه میدونید کمک کنید:گریه:
ممنون

shahryari
سه شنبه 26 دی 1391, 17:59 عصر
دارم کلافه میشم :افسرده:

:متفکر: ... حق داری کلافه بشی... واقعا
این لینک کمکت میکنه
http://forum.codecall.net/topic/46993-how-to-record-your-screen-and-saving-it-as-avi/#axzz2I6MqkGpM

Hamidreza Bozorg
سه شنبه 26 دی 1391, 20:16 عصر
:متفکر: ... حق داری کلافه بشی... واقعا
این لینک کمکت میکنه
http://forum.codecall.net/topic/46993-how-to-record-your-screen-and-saving-it-as-avi/#axzz2I6MqkGpM

دستتون درد نکنه:قلب:
شما در این زمینه تجربه ای دارید؟؟؟:متفکر:
ممنون میشم بیشتر کمکم کنید (حتی با یک سورس !!!):قلب:

Hamidreza Bozorg
چهارشنبه 27 دی 1391, 16:51 عصر
سایتی رو که گفتید دست و پا شکسته خوندمش (translate):چشمک:
بعدش پروژشو ساختم:تشویق:
کار میکنه اما یه نقصایی هم داره:افسرده:
یه جورایی خرابه !!!!؟؟:ناراحت::گریه:
پروژرو ضمیمه کردم تا اگه چیزی سردر آوردید بهم بگید ( در ضمن او سایت به دقت بخونید کمکتون میکنه):قلب:
منتظر هستم
ممنون

Hamidreza Bozorg
پنج شنبه 28 دی 1391, 21:00 عصر
ممنون از اینکه جواب دادید:عصبانی:
فهمیدم
چون حجم هر عکسی که از دسکتاپ میگیره حدود 100-150 کیلوبایت میشه و هر 10 عکس میشه یک ثانیه و رم کامپیوتر منم کم هست توی لود کردن تصاویر موقع نمایش فیلم ایراد داره!!!:متعجب:
باید بعد از گرفتن عکس حجمش رو کم کنم
کسی بلده
خواهشا اگه بلدید بهم بگید:گریه:
بعد از ساخت و تست پروژه رو میزارم تو همین تایپیک
ممنون

Hamidreza Bozorg
جمعه 29 دی 1391, 16:38 عصر
سایز عکس هارو که میکنم تو فایل avi نصف کردم
دیگه هنگ نمیکنه ولی متن ها دیگه واضح نیستن
شاید بخوام فیلم آموزشی ضبط کنم باید متن ها واضح باشه دیگه
باید یه روش پیدا کنم که فقط رو کیفیت عکس ها و رنگ ها تاثیر بذاره نه رو متن ها
هیچ کس در این مورد اطلاعاتی داره؟؟؟
لطفا کمک کنید :عصبانی++:

shahryari
جمعه 29 دی 1391, 19:02 عصر
با سلام
من فايل ضميمه شما را تست كردم به خوبي كار ميكند
اشكالش كجاست؟؟
سخت افزار شما پايين است؟؟
از برنامه استفاده كردم و فيلم هم ضبط كردم
الان هم دارم روش كار ميكنم كه كرسر ماوس هم نمايش داده بشه به همراه كليك و دابل كليك و ......

Hamidreza Bozorg
شنبه 30 دی 1391, 12:31 عصر
سخت افزار من که پایین هست اما مشکل من اینه که حجم فیلم ها بالاست
توی پخش فریم ها پرش دارن
باید با یک الگوریتمی حجم عکس هایی که میگیره رو کم کرد
اینجوری هر یک دقیقه فیلم 200 MB هست و این خیلی بده
حالا باید برنامه ای پیدا کرد که عکس هایی که میندازه حجمش پایین باشه
مثلا هر عکسی که از دسکتاپ میندازه بشه 20-30 کیلوبایت (jpg)
در صورتی که این برنامه حجم هر عکسش 150-100 کیلوبایته :متعجب: (bmp)
اگه تونستم برنامه ای پیدا کنم که بدون این که متن هارو غیر قابل خوندن کنه حجم عکس رو بیاره پایین حتما میزارم

h_a_m_i_d
شنبه 30 دی 1391, 13:16 عصر
با سلام دوست عزیز اینقدر هم الکی نیست که برنامه های ضبط فیلم از صفحه با ترکیب چند تکنولوژی میتونن به این نتیجه دست پیدا کنن مطمین باشید اگه به این سادگی ها بود هرکس یک نرم افزار خودش میساخت
البته قصد جسارت ندارم فقط نظرم رو گفتم
1-میتونین عکس قبلی را با عکس بعدی مقایسه کنید اگه برابر بود دیگه لازم نیست از صفحتون عکس بگیرین و الکی سخت افزار رو اشغال کنید و حجم هم میاد پایین
2-میتونین پیکسل در میان یک پیکسل را پاک کنید

Hamidreza Bozorg
شنبه 30 دی 1391, 13:20 عصر
یکی از دوستان (Mr Sidou (http://barnamenevis.org/member.php?257212-Mr-Sidou)) برام یه پیام داد که لینک یه سورس بود
باتشکر از ایشان من این سورس رو میزارم اینجا
تازه با قابلیت اینکه موس غیب نمیشه و موقع چپ کلید و راست کلید یه دایره رنگی میاد و ...

اما مشکل حجمش برطرف نشده

98653

Hamidreza Bozorg
شنبه 30 دی 1391, 14:34 عصر
این سورس رو از CodeProject دانلود کردم
باید سورس جالبی باشه اما ارور میده اگر عزیزان تونستند درستش کنن ، فایل درست شده رو بزارن تو تایپیک

ممنون

98660

Hamidreza Bozorg
یک شنبه 01 بهمن 1391, 13:48 عصر
اینجا می خوام اون سایتی که در بالا آقای shahryari (http://barnamenevis.org/member.php?246498-shahryari) قرار دادند رو به فارسی بنویسم :

معنی (حدودی):


در این آموزش ما می خواهیم بفهمیم چگونه می توان از صفحه دسکتاپ ضیط کرد و آن را با پسوند AVI. ذخیره کرد
یه خورده پیچیده است اما فقط شما می فهمید چگونه می توان استفاده کرد از کلاس AVIWriter و AVI و لازم نیست که بدانید چگونه کار می کند


اول نیاز داریم تا ایمپورت کنیم چند چیز را :


Imports System.Drawing.Imaging

Imports System.Runtime.InteropServices




حالا باید کلاس AVI را اضافه کنیم :


Public Class Avi

Public Const StreamtypeVIDEO As Integer = 1935960438
Public Const OF_SHARE_DENY_WRITE As Integer = 32
Public Const BMP_MAGIC_COOKIE As Integer = 19778



<StructLayout(LayoutKind.Sequential, Pack:=1)> _
Public Structure RECTstruc
Public left As UInt32
Public top As UInt32
Public right As UInt32
Public bottom As UInt32
End Structure

<StructLayout(LayoutKind.Sequential, Pack:=1)> _
Public Structure BITMAPINFOHEADERstruc
Public biSize As UInt32
Public biWidth As Int32
Public biHeight As Int32
Public biPlanes As Int16
Public biBitCount As Int16
Public biCompression As UInt32
Public biSizeImage As UInt32
Public biXPelsPerMeter As Int32
Public biYPelsPerMeter As Int32
Public biClrUsed As UInt32
Public biClrImportant As UInt32
End Structure

<StructLayout(LayoutKind.Sequential, Pack:=1)> _
Public Structure AVISTREAMINFOstruc
Public fccType As UInt32
Public fccHandler As UInt32
Public dwFlags As UInt32
Public dwCaps As UInt32
Public wPriority As UInt16
Public wLanguage As UInt16
Public dwScale As UInt32
Public dwRate As UInt32
Public dwStart As UInt32
Public dwLength As UInt32
Public dwInitialFrames As UInt32
Public dwSuggestedBufferSize As UInt32
Public dwQuality As UInt32
Public dwSampleSize As UInt32
Public rcFrame As RECTstruc
Public dwEditCount As UInt32
Public dwFormatChangeCount As UInt32
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=64)> _
Public szName As UInt16()
End Structure



'Initialize the AVI library
<DllImport("avifil32.dll")> _
Public Shared Sub AVIFileInit()
End Sub

'Open an AVI file
<DllImport("avifil32.dll", PreserveSig:=True)> _
Public Shared Function AVIFileOpen(ByRef ppfile As Integer, ByVal szFile As [String], ByVal uMode As Integer, ByVal pclsidHandler As Integer) As Integer
End Function

'Create a new stream in an open AVI file
<DllImport("avifil32.dll")> _
Public Shared Function AVIFileCreateStream(ByVal pfile As Integer, ByRef ppavi As IntPtr, ByRef ptr_streaminfo As AVISTREAMINFOstruc) As Integer
End Function

'Set the format for a new stream
<DllImport("avifil32.dll")> _
Public Shared Function AVIStreamSetFormat(ByVal aviStream As IntPtr, ByVal lPos As Int32, ByRef lpFormat As BITMAPINFOHEADERstruc, ByVal cbFormat As Int32) As Integer
End Function

'Write a sample to a stream
<DllImport("avifil32.dll")> _
Public Shared Function AVIStreamWrite(ByVal aviStream As IntPtr, ByVal lStart As Int32, ByVal lSamples As Int32, ByVal lpBuffer As IntPtr, ByVal cbBuffer As Int32, ByVal dwFlags As Int32, _
ByVal dummy1 As Int32, ByVal dummy2 As Int32) As Integer
End Function

'Release an open AVI stream
<DllImport("avifil32.dll")> _
Public Shared Function AVIStreamRelease(ByVal aviStream As IntPtr) As Integer
End Function

'Release an open AVI file
<DllImport("avifil32.dll")> _
Public Shared Function AVIFileRelease(ByVal pfile As Integer) As Integer
End Function

'Close the AVI library
<DllImport("avifil32.dll")> _
Public Shared Sub AVIFileExit()
End Sub

End Class




این کلاس از مقداری dll برای ساخت فایل avi استفاده می کند
با افزودن این کلاس ما قادر به ساخت فایل های avi هستیم


حالا باید کلاس AVIWriter رو اضافه کنیم
در اینجا در حال تعریف متغیر ها هستیم


Public Class AviWriter
Private aviFile As Integer = 0
Private aviStream As IntPtr = IntPtr.Zero
Private frameRate As UInt32 = 0
Private countFrames As Integer = 0
Private width As Integer = 0
Private height As Integer = 0
Private stride As UInt32 = 0
Private fccType As UInt32 = Avi.StreamtypeVIDEO
Private fccHandler As UInt32 = 1668707181
Private strideInt As Integer
Private strideU As UInteger
Private heightU As UInteger
Private widthU As UInteger



در اینجا کلاس OpenAVI را اضافه می کنیم


Public Sub OpenAVI(ByVal fileName As String, ByVal frameRate As UInt32)
Me.frameRate = frameRate

Avi.AVIFileInit()


Dim OpeningError As Integer = Avi.AVIFileOpen(aviFile, fileName, 4097, 0)
If OpeningError <> 0 Then
Throw New Exception("Error in AVIFileOpen: " + OpeningError.ToString())
End If
End Sub

ورودی اول این کلاس (fileName) ، نام فایل avi هست و دومی (frameRate) ، نرخ فریم فیلم است
در این کلاس اگر در بازکردن فایل مشکلی پیش بیاید با ارور مواجه خواهیم شد


حالا تعریف کلاس AddFrame را شروع می کنیم


Public Sub AddFrame(ByVal bmp As Bitmap)

bmp.RotateFlip(RotateFlipType.RotateNoneFlipY)

Dim bmpDat As BitmapData = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.[ReadOnly], PixelFormat.Format24bppRgb)

ورودی ان کلاس یک فایل bmp است که در اینجا به عنوان فریم یاد شده
در اینجا باید عکسمان به صورت وارونه به فایل Avi اضافه شود ( که در اینجا خود نویسنده هم گفته که نمیدونه )
سپس یک متغیر تعریف می کنیم و آن را به حافظه منتقل می کنیم
حالا کد های زیر را اضافه کنید


If countFrames = 0 Then
Dim bmpDatStride As UInteger = bmpData.Stride
Me.stride = DirectCast(bmpDatStride, UInt32)
Me.width = bmp.Width
Me.height = bmp.Height
CreateStream()
End If

در اینجا بعد از بررسی اینکه فریم جاری اولین فریم بود فریم را به فایل avi اضافه کرده و سایز فایل avi را برابر با سایز فایل bmp ما قرار می دهد
و بعد کلاس CreateStream رو فراخوانی می کند
حال خطوط زیر را اضافه کنید


strideInt = stride
Dim writeResult As Integer = Avi.AVIStreamWrite(aviStream, countFrames, 1, bmpData.Scan0, DirectCast((strideInt * height), Int32), 0, _
0, 0)

If writeResult <> 0 Then
Throw New Exception("Error in AVIStreamWrite: " + writeResult.ToString())
End If

در اینجا فایل bmp ما همراه با dll وارد فایل avi می شوند
و بعد اگر writeResult برابر صفر بود نشان دهنده این است که کار می کند
و حالا کد زیر را وارد نمایید :


bmp.UnlockBits(bmpData)
System.Math.Max(System.Threading.Interlocked.Incre ment(countFrames), countFrames - 1)
End Sub


در اینجا ما حذف می کنیم فایل bitmap را از حافظه و یک مقدار countFrames را افزایش می دهیم


پس از اینکه کلاس قبلی به پایان رسید حال کلاس CreateStream را اضافه می کنیم


Private Sub CreateStream()
Dim strhdr As New Avi.AVISTREAMINFOstruc()
strhdr.fccType = fccType
strhdr.fccHandler = fccHandler
strhdr.dwScale = 1
strhdr.dwRate = frameRate
strideU = stride
heightU = height
strhdr.dwSuggestedBufferSize = DirectCast((stride * strideU), UInt32)
strhdr.dwQuality = 10000

heightU = height
widthU = width
strhdr.rcFrame.bottom = DirectCast(heightU, UInt32)
strhdr.rcFrame.right = DirectCast(widthU, UInt32)
strhdr.szName = New UInt16(64) {}

بنابراین ما مقراری از متغیرها ، مجموعه کیفیت ، اندازه و نوع جریان و غیره را تعریف نمودیم
در حال حاضر جریان ایجاد می کنیم :


Dim createResult As Integer = Avi.AVIFileCreateStream(aviFile, aviStream, strhdr)
If createResult <> 0 Then
Throw New Exception("Error in AVIFileCreateStream: " + createResult.ToString())
End If

حالا کد زیر :


Dim bi As New Avi.BITMAPINFOHEADERstruc()
Dim bisize As UInteger = Marshal.SizeOf(bi)
bi.biSize = DirectCast(bisize, UInt32)
bi.biWidth = DirectCast(width, Int32)
bi.biHeight = DirectCast(height, Int32)
bi.biPlanes = 1
bi.biBitCount = 24

strideU = stride
heightU = height
bi.biSizeImage = DirectCast((strideU * heightU), UInt32)

در اینجا فرمت تصویر جریان را قرار می دهیم

حال در اینجا فرمت جریان را تنظیم می کنیم :


Dim formatResult As Integer = Avi.AVIStreamSetFormat(aviStream, 0, bi, Marshal.SizeOf(bi))
If formatResult <> 0 Then
Throw New Exception("Error in AVIStreamSetFormat: " + formatResult.ToString())
End If
End Sub



حال یک sub دیگر از کلاس AVIWriter مانده است :


Public Sub Close()
If aviStream <> IntPtr.Zero Then
Avi.AVIStreamRelease(aviStream)
aviStream = IntPtr.Zero
End If
If aviFile <> 0 Then
Avi.AVIFileRelease(aviFile)
aviFile = 0
End If
Avi.AVIFileExit()
End Sub
End Class

در اینجا باعث می شود که جریان ساخت فایل avi به پایان رسد


الان من خواهم نشان دهم که چگونه می توان از دسکتاپ فیلم ضبط نمود ، بسیار ساده :

اول باید یک تایمر به اسم bmpTimer و یک کلید به اسم StartButton اضافه نمود
حال بازه زمانی (interval) تایمر را برابر 100 قرار دهید (چون من می خواهم فیلم ساخته شده 10 فریم بر ثانیه باشد)

حال دو متغیر اضافه می کنیم به کلاس فرم


Private screenBimaps(99) As Bitmap
Private currentBitmap As Integer = 0


اولی آرایه ای است که می تواند 100 عکس را در خود ذخیره کند (10 ثانیه)
دومی نشان دهنده شماره فریم جاری است


هنگامی که کاربر بر روی دکمه کلیک کرد :


Private Sub StartButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StartButton.Click
If StartButton.Text = "Start" Then
currentBitmap = 0
StartButton.Text = "Stop"
bmpTimer.Enabled = True
Else
CreateFile()
StartButton.Text = "Start"
bmpTimer.Enabled = False
End If
End Sub

در کد بالا اگر فیلمی در حال ضبط نباشد ، ضبط شروع می شود و اگر در حال ضبط باشد ، متوقف می شود


این کد هم برای هنگامی که تایمر فعال می شود :


Private Sub bmpTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bmpTimer.Tick
If currentBitmap < 100 Then
Dim w As Integer = Screen.PrimaryScreen.WorkingArea.Width
Dim h As Integer = Screen.PrimaryScreen.WorkingArea.Height
Dim bmp As New Bitmap(w, h)
Using gr As Graphics = Graphics.FromImage(bmp)
gr.CopyFromScreen(0, 0, 0, 0, bmp.Size)
End Using
screenBimaps(currentBitmap) = bmp
currentBitmap += 1
Else
CreateFile()
StartButton.Text = "Start"
bmpTimer.Enabled = False
End If
End Sub

در اینجا حد اکثر 100 عکس را می توان در فایل avi ضبط نمود
در اینجا فایل bmp را می سازد و سایز عکس برابر صفحه نمایش قرار داده و از صفحه نمایش عکس انداخته و درون فایل bmp می ریزد و 100 فایل bmp را در آرایه screenBitmap می ریزد و پس از آنکه تمام عکس ها گرفته شد کلاس CreateFile را فراخوانی می کند.


حالا کلاس screenBitmap را می سازیم :


Private Sub CreateFile()
Dim Writer As New AviWriter

Writer.OpenAVI("C:\Test.Avi", 10)
For Frame As Integer = 0 To currentBitmap - 1
Writer.AddFrame(screenBimaps(Frame))
Next
Writer.Close()
End Sub

در این کلاس شما بسیار از تنظیمات را می توانید انجام دهید همچون آدرس ذخیره فایل و نرخ فریم فیلم و ایستادن ضبط و ...
پایان
خوب امید وارم که این مقاله بهت کمک کرده باشه که کلیات ضبط فبلم رو بفهمید
تنها مشکل این کلاس این است که فیلم هارو با حجم بالا ضبط می کنه

در نهایت سورس کامل این مقاله رو دوباره میزارم
اگر روشی برای کم کردن حجم فایل پیدا کردید توی تایپیک بزارید تا این کلاس کامل بشه
با تشکر

98728

Hamidreza Bozorg
شنبه 12 اسفند 1391, 23:38 عصر
بلخره درستش کردم
بعد از دو هفته ، درستش کردم!!!

1-مشکل حجم پایین اومده
2-موس هم معلومه
3-میتونی با هر کدکی (Codec) که خواستی ذخیره کنید

تنها مشکلی که داره اینه که یه خورده سرعت میاد پایین و بیشتر از 5 فریم در ثانیه نمی تونه ذخیره کنه.

حالا من سورس رو پایین گذاشتم

اگه برای سرعتش راه حلی پیدا کردید لطفا به منم بگید.