الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

كيفية تطوير منزل فيديوهات يويتيوب

بدأه محمد رضى في 25 يناير 2010 · 7 رد · 4,578 مشاهدة · في قسم الدروس والمواضيع المتميزة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم و رحمة الله تعالى و بركاته...

قبل أيام وجدت عددا من فيديوهات ناذرة على موقع اليوتيوب كنت أبحث عنها. و لتحميل نسخ منها على حاسوبي احتجت لتحميل و تجربة بعض البرامج المخصصة لهذا الغرض و كما تعلمون فموقع اليوتيوب لا يتيح عملية التحميل بل المشاهدة فقط. المهم بعد تجربة عدد من برامج التحميل فكرت في البحث عن كيفية تحميل الملفات و بعد اكتشافها تبادرت إلى ذهني فكرة عمل موضوع لأتشارك معكم نتيجة بحثي الصغير.

قبل المضي في الموضوع لا بد أن أنوه أنه و في أي لحظة, قد يصبح محتوى هذا الموضوع متجاوز و غير عملي لأن طريقة تحديد و إيجاد رابط ملف الفيديو يتم استخلاصه من الكود المصدر لصفحة اليوتيوب التي يظهر بداخلها الفيديو و أي تغيير أو تعديل في بنية كود صفحات الموقع تحيل الموضوع و البرنامج المرفق و الكود و المجهود إلى سلة المهملات.

post-207152-12643682561519_thumb.jpg

كيف أكتشف يدويا رابط ملف الفيديو بمساعدة فايرفوكس و فايربوغ؟

post-207152-12643682857499_thumb.jpg

عندما تفتح صفحة لمشاهدة فيديو على اليوتيوب يقوم كود جافاسكريبت بتهيئة مربع عرض الفيديوهات ببرامترات العرض, و من بين هذه البرامترات هناك رابط ملف الفيديو الذي يقوم مربع العرض بتحميله و عرض محتواه بالتوازي.

للوصول إلى رابط ملف الفيديو المختبئ داخل الكود المصدر لصفحة موقع اليوتيوب, سنستعمل المتصفح فايرفوكس و ملحقه الشهير فايربوغ. نبدأ بإظهار نافذة الفايربوغ ثم نقوم بإدخال عنوان صفحة الفيديو التي نريد عرضها. بعد انتهاء عملية تحميل الصفحة, سنلاحظ أن فايرفوكس ما زال يقوم بتحميل بيانات من خادم اليوتيوب! هذه البيانات هي بيانات ملف الفيديو التي نريد الوصول إليها. نقوم باختيار tab المسمى Network ثم اسفله سنجد زر مسمى Flash نقوم بالنقر عليه, نلاحظ لائحة بها عنصرين. العنصر الأول هو ملف كنترول مربع عرض فيديوهات اليوتيوب و الثاني و الذي هو ظالتنا هو رابط ملف الفيديو. للتأكد يمكننا النقر عليه بالزر الأيمن للفأرة و اختيار Copy adress من القائمة التي ستظهر ثم إدخال الرابط في شريط العنوان لتتم عملية تحميل ملف الفيديو من الخادم على الحاسوب.

كيف أكتشف يديويا رابط ملف الفيديو داخل كود هتمل صفحة اليوتيوب؟

رابط ملف فيديو اليوتيوب موجود كبارامتر لتهيئة مربع عرض الفيديو كما أسلفنا ذكره سابقا لكن هناك رابط مشابه له سهل الإيجاد و لكن يجب تعديله ليصبح طلب تحميل ملف الفيديو و ليس صورة preview للفيديو. الرابط يكون بشكل كهذا :

http://v3.lscache5.c.youtube.com/generate_204?ip=0.0.0.0&...

سنحتاج لتعديله ليصبح بالشكل التالي الذي يتيح لنا تحميل ملف الفيديو :

http://v3.lscache5.c.youtube.com/videoplayback?ip=0.0.0.0&...

لإيجاد رابط ملف الفيديو, قم بالنقر على الزر الأيمن للفأرة في أي مكان على صفحة يوتيوب ثم قم باختيار Page source code من القائمة ثم قم بالبحث عن مثلا [generate_204?ip] عند إيجاد النص قم بنسخ فقط الرابط ثم بعد لصقه على شريط العنوان, قم بتغيير المقطع generate_204 إلى videoplayback ثم انقر على الزر Enter ليتم تحميل ملف الفيديو.

استعراض كود البرنامج المرفق :

لتسهيل استخدام ما اكتشفناه بسهولة, سنقوم بتحويله إلى برنامج صغير يقوم بتحميل ملف فيديو من خادم اليوتيوب عن طريق تحديد رابط الصفحة على مربع نص و الضغط على زر التحميل كما هو ظاهر في الصفحة أعلاه.

تعريفات :

لأننا سنقوم بتخصيص مسلك خاص لتنفيذ كود تحميل ملف الفيديو, سنحتاج لوسيلة للوصول إلى مربعات واجهة المستخدم لتغييرها لتتلائم و الوضع الحالي لعمل التطبيق. محاولة تغيير قيمة خاصية كائن تم إنشاؤه خارج المسلك ستؤدي إلى رفع استثناء و لهذا سنقوم بالمناداة على دوال تغيير قيم مثل هذه الكائنات عن طريق Delegate.

    ' إظهار مربع الحوار لاختيار و تأكيد اسم ملف الفيديو من داخل مسلك التحميل
    Private Delegate Function GetDestinationFileNameDelegate(ByVal name As String) As String
    ' الدالة التي تتم المناداة عليها عندما ينتهي مسلك التحميل من عملية التحميل
    Private Delegate Sub DownloadOperationEndedDelegate(ByVal msg As String)
    ' تغيير قيمة خاصية من مسلك آخر غير المسلك الرئيسي
    Private Delegate Sub SetPropertyValueDelegate(ByVal obj As Object, ByVal prop As String, ByVal value As Object)

توابث :

سنحتاج لبعض الثوابت لتسهيل عملية كتابة الكود. من بين هذ التوابث نص التعبير المنتظم الذي يمكننا من الوصول إلى رابط ملف الفيديو على الخادم و عنوان الفيديو.

    ' نص عنوان النافذة الرئيسية
    Private Const FormTitle As String = "منزل ملفات فيديو يوتيوب"
    ' تعبير منتظم للوصول إلى رابط ملف الفيديو من داخل الكود المصدر لصفحة اليوتيوب
    Private Const VideoFileRegEx As String = "img\.src\s=\s\'(.*?)\'\;"
    ' تعبير منتظم للحصول على اسم ملف الفيديو من داخل الكود المصدر لصفحة اليوتيوب
    Private Const VideoTitleRegEx As String = "\'VIDEO_TITLE\'(.*?)\'(.*?)\'\,"
    ' حجم البيانات التي تتم قراءتها من خادم اليوتيوب
    Private Const BufferSize As Integer = 1024

متغيرات عامة :

المتغير الأول المعرف على مستوى الفورم يمكننا من التحكم في المسلك الخاص بالتحميل. المتغير الثاني نهيئه على false و عند تغيير قيمته إلى true نكون قد أنهينا عمل المسلك الخاص بتنفيذ عملية التحميل.

    ' كائن المسلك الخاص بعملية التحميل
    Private DownloadThread As Threading.Thread
    ' انهاء عمل مسلك التحميل إذا true
    Private StopDownload As Boolean = False

تحميل محتوى صفحة اليوتيوب :

للوصول إلى رابط تحميل ملف الفيديو, نحتاج إلى تحميل كود المصدر لصفحة اليوتيوب التي يتم بداخلها عرض الفيديو.

    ' تحميل الكود المصدر لصفحة اليوتيوب 
    ' url : رابط صفحة اليوتيوب المراد تحميل ملف الفيديو المعروض عليها.
    Private Function RetrievePageContent(ByVal url As String) As String
        Dim page As String = ""
        ' ارسال استعلام طلب تحميل الصفحة إلى الخادم
        Dim req As HttpWebRequest = HttpWebRequest.Create(url)
        ' الحصول على الجواب من الخادم
        Dim res As HttpWebResponse = req.GetResponse()
        ' الوصول إلى دفق البيانات الآتية من الخادم
        Dim strm As New StreamReader(res.GetResponseStream())
        SetPropertyValue(DownloadProgressBar, "Style", ProgressBarStyle.Marquee)
        ' قراءة البيانات حتى نهايتها أو طلب ذلك من المستخدم عن طريق الزر رجوع
        While Not strm.EndOfStream AndAlso Not StopDownload
            ' قراءة محتوى الصفحة سطر بسطر
            page &= strm.ReadLine() & vbCrLf
        End While
        ' غلق دفق البيانات
        strm.Close()
        ' غلق جواب الخادم
        res.Close()

        ' إرجاع كود هتمل الصفحة
        Return page
    End Function

دالة DownloadVideoFromYoutube :

هذه الدالة تقوم بتحميل محتوى صفحة اليوتيوب ثم عن طريق التعابير المنتظمة, تقوم بالوصول إلى رابط تحميل ملف الفيديو و عنوانه و أخيرا تقوم بتحميل ملف الفيديو.

    ' الدالة التي يتم تنفيذ كودها في مسلك خاص لتحميل ملف الفيديو من اليوتيوب
    Private Sub DownloadVideoFromYoutube()
        SetPropertyValue(Me, "Text", "الوصول إلى عنوان الملف...")
        ' تحميل كود مصدر الصفحة التي تظهر الفيديو
        Dim page As String = RetrievePageContent(URLTextBox.Text)
        SetPropertyValue(Me, "Text", "تحديد اسم الملف...")
        ' تحديد السطر الموجود فيه رابط ملف الفيديو من صفحة هتمل
        Dim mth As Match = Regex.Match(page, VideoFileRegEx)
        If mth.Groups.Count < 2 Then
            Me.Invoke(New DownloadOperationEndedDelegate(AddressOf DownloadOperationEnded), New Object() {"خطأ أثناء تحديد اسم ملف الفيديو..."})
            Return
        End If
        ' تحديد رابط ملف الفيديو و تعديله لطلب تحميل ملف الفيديو
        Dim hostFile As String = mth.Groups(1).Value
        hostFile = Regex.Replace(hostFile, "youtube.com(.*?)\?", "youtube.com/videoplayback?")
        ' تحديد اسم ملف الفيديو من 
        Dim localFile As String = Regex.Split(page, VideoTitleRegEx)(2)
        ' طلب تأكيد اسم ملف الفيديو من المستخدم
        If Not StopDownload Then localFile = Me.Invoke(New GetDestinationFileNameDelegate(AddressOf GetDestinationFileName), New Object() {localFile})
        ' الغاء العملية إذا اختار المستخدم ذلك
        If localFile = "" Then
            If Not StopDownload Then Me.Invoke(New DownloadOperationEndedDelegate(AddressOf DownloadOperationEnded), New Object() {""})
            Return
        End If
        SetPropertyValue(Me, "Text", "جاري تحميل ملف الفيديو...")
        ' ارسال طلب التحميل للخادم
        Dim req As HttpWebRequest = HttpWebRequest.Create(hostFile)
        ' الوصول إلى جواب الخادم
        Dim res As HttpWebResponse = req.GetResponse()
        ' الحصول على دفق بيانات ملف الفيديو الآتية من الخادم
        Dim hStrm As Stream = res.GetResponseStream()
        ' تهيئة مربع تطور عملية التحميل
        SetPropertyValue(DownloadProgressBar, "Style", ProgressBarStyle.Continuous)
        SetPropertyValue(DownloadProgressBar, "Minimum", 0)
        SetPropertyValue(DownloadProgressBar, "Maximum", CType(res.ContentLength, Integer))
        SetPropertyValue(DownloadProgressBar, "Value", 0)
        ' حجم البيانات الاجمالي الذي تم تحميله
        Dim n As Integer = 0
        ' حجم البيانات الحالي الذي تمت قراءته في آخر قراءة
        Dim i As Integer = 0
        ' المخزن المؤقت للبيانات المحملة من الخادم قبل كتابتها في ملف الفيديو على الحاسوب
        Dim buf(BufferSize) As Byte
        ' فتح دفق بيانات إلى نسخة ملف البيانات على الحاسوب
        Dim lStrm As Stream = File.OpenWrite(localFile)
        ' تحميل البيانات و نسخها على الملف حتى نهاية دفق الخادم أو طلب الانهاء من المستخدم
        While Not StopDownload
            ' قراءة البيانات المحملة من الخادم
            i = hStrm.Read(buf, 0, BufferSize)
            ' كتابتها على النسخة على الحاسوب
            lStrm.Write(buf, 0, i)
            n += i
            SetPropertyValue(DownloadProgressBar, "Value", n)
            ' نهاية عملية النسخ إذا لم تتم عملية القراءة 
            If i <= 0 Then Exit While
        End While
        ' غلق نسخة الملف
        lStrm.Close()
        ' غلق دفق البيانات من الخادم
        hStrm.Close()
        ' غلق جواب الخادم
        res.Close()
        ' إعلام المستخدم بنهاية عملية التحميل
        Media.SystemSounds.Exclamation.Play()
        SetPropertyValue(Me, "Text", "انتهى تحميل ملف الفيديو...")
        Me.Invoke(New DownloadOperationEndedDelegate(AddressOf DownloadOperationEnded), New Object() {"تم تحميل ملف الفيديو."})
    End Sub

الدالة أسفله تتم المناداة عليها عندما ينقر المستخدم على زر التحميل.

    ' عند اختيار المستخدم زر التحميل
    Private Sub DownloadButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DownloadButton.Click
        ' منع المستخدم من اختيار زر التحميل وقت عملية التحميل
        DownloadButton.Enabled = False
        ' إنشاء كائن مسير المسلك الخاص بتحميل ملف الفيديو
        DownloadThread = New Threading.Thread(AddressOf DownloadVideoFromYoutube)
        ' تنفيذ كود مسلك التحميل
        DownloadThread.Start()
    End Sub

بعد تحميل كود المصدر لصفحة اليوتيوب و الوصول إلى رابط و عنوان ملف الفيديو, نحتاج من المستخدم إلى تأكيد عنوان و مسار نسخة ملف الفيديو على الحاسوب و لأن العملية تتم على مسلك آخر غير المسلك الرئيسي للتطبيق نحتاج لتنفيذ كود اختيار اسم و مسار الملف على دالة تتم المناداة عليها عن طريق Delegate GetDestinationFileNameDelegate :

    ' تتم المناداة على هذه الدالة للحصول على اسم نسخة ملف الفيديو عن طريق مربع الحوار 'افتح' من داخل
    ' مسلك آخر غير المسلك الرئيسي للتطبيق. المناداة على دوال إظهار مربعات الحوار مباشرة من مسلك التحميل
    ' سيؤدي إلى رفع استثناء أو تجميد التطبيق
    Private Function GetDestinationFileName(ByVal name As String) As String
        Dim sfd As New SaveFileDialog()
        With sfd
            .FileName = name
            .Filter = "Flash video files (*.flv)|*.flv"
            .DefaultExt = "flv"
            If .ShowDialog() = Windows.Forms.DialogResult.OK Then Return .FileName
        End With

        ' إرجاع نص فارغ في حالة اختيار المستخدم إلغاء عملية التحميل
        Return ""
    End Function

عند انتهاء الدالة DownloadVideoFromYoutube تقوم هذه الأخيرة بالمناداة على الدالة DownloadOperationEnded عن طريق Delegate DownloadOperationEndedDelegate ليتم تنفيذ الكود على المسلك الرئيسي للتطبيق حتى تقوم الدالة بإعلام المستخدم بانتهاء عملية التحميل و تهيئة واجهة المستخدم لوضع انتظار عملية تحميل أخرى.

    ' تتم المناداة على هذه الدالة لإعلام التطبيق بانتهاء مسلك التحميل مع تحديد رسالة بنتيجة
    ' العملية التي ستظهر للمستخدم
    Private Sub DownloadOperationEnded(ByVal msg As String)
        ' إظهار الرسالة
        If msg <> "" Then MsgBox(msg, MsgBoxStyle.Information, "نهاية عملية التحميل")
        ' تهيئة وضعية انتظار عملية تحميل أخرى
        StopDownload = False
        DownloadButton.Enabled = True
        Me.Text = FormTitle
        With DownloadProgressBar
            .Style = ProgressBarStyle.Continuous
            .Minimum = 0
            .Maximum = 0
            .Value = 0
        End With
        ' انهاء مسلك التحميل
        DownloadThread.Join(5000)
        DownloadThread.Abort()
        DownloadThread = Nothing
    End Sub

لنتمكن من تغيير قيم مربعات التحكم من المسلك الخاص بتحميل ملف الفيديو, سنستفيد من خدمات الدالة SetPropertyValue التي تقوم بتنفيذ كودها في المسلك الرئيسي للتطبيق لتقوم بعملها.

    ' تتم المناداة على الدالة لتغيير محتوى خاصية كائن تم انشاؤه خارج مسلك التحميل
    ' محاولة تغيير قيمة خاصية كائن لا ينتمي إلى مسلك التحميل تؤدي إلى رفع اسثناء
    ' obj : الكائن المراد تغيير قيمة خاصيته
    ' prop : اسم الخاصية المراد تغيير قيمتها
    ' value : القيمة الجديدة للخاصية
    Private Sub SetPropertyValue(ByVal obj As Object, ByVal prop As String, ByVal value As Object)
        ' إذا, حاليا, الكود سيتم تنفيذه خارج المسلك الذي تم انشاء النموذج فيه...
        If Me.InvokeRequired Then
            ' تنفيذ كود الدالة داخل المسلك الذي انشئ فيه النموذج
            Me.Invoke(New SetPropertyValueDelegate(AddressOf SetPropertyValue), New Object() {obj, prop, value})
            ' خروج
            Return
        End If
        ' الوصول إلى نوع الكائن
        Dim t As Type = obj.GetType()
        ' الوصول إلى الخاصية
        Dim p As Reflection.PropertyInfo = t.GetProperty(prop, Reflection.BindingFlags.Instance Or Reflection.BindingFlags.Public)
        ' تغيير قيمتها
        p.SetValue(obj, value, Nothing)
    End Sub

و أخيرا, عندما يتم غلق التطبيق, نقوم بطلب التأكيد من المستخدم ثم نقوم بإنهاء عملية التحميل الجارية و ننهي التطبيق.

    ' عندما يغلق المستخدم نموذج التطبيق
    Private Sub UtubDownloaderForm_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
        ' طلب التأكيد
        Dim r As MsgBoxResult = MsgBoxResult.Yes
        If DownloadProgressBar.Value <> 0 Then r = MsgBox("هل تريد فعلا انهاء عملية التحميل الجارية؟", MsgBoxStyle.Question Or MsgBoxStyle.YesNo, "خروج")
        If r = MsgBoxResult.No Then
            ' إلغاء عملية التطبيق
            e.Cancel = True
            Return
        End If
        ' إنهاء عملية التحميل الحالية
        StopDownload = True
        ' إنهاء مسلك التحميل
        If Not DownloadThread Is Nothing Then
            DownloadThread.Join(5000)
            DownloadThread.Abort()
        End If
    End Sub

أعرف أنني قصرت في الشرح و لكن بالمقابل, أنا جاهز للإجابة على أي سؤال في الموضوع...

ستجدون في الملف المرفق مع هذا الموضوع مشروع صغير يمكن من تحميل ملفات الفيديو من اليوتيوب, به الكود الذي تم استعراضه في هذا الموضوع.

تحياتي...

utubdown.rar

1
#2

استاذ محمد رضى

بارك الله فيك عمل رائع جدا

#3

فكرة جميله جدا في الحصول على هذا الامر ... لكن ماذا عن ال API's التي توجد في موقع youtube ؟ اعتقد انها كفيله بهذا الامر

#4

بكل صراحة أخي النبهاني, بحثت في الموضوع لكنني لم أجد ما يشير إلى مسألة تنزيل الفيديوهات من اليوتيوب التي تثير الكثير من القيل و القال حول شرعيتها القانونية. كل ما وجدته يخص عرض الفيديوهات, البحث, التحميل إلى الخادم, زيادة التعليقات و غيرها...

للإشارة فقط, كود المشروع المرفق مع الدرس تم تعديله لزيادة التعرف الأوتوماتيكي على روابط موقع اليوتيوب عند نسخها إلى كليبورد النظام. هذا يعني أنه بعد تشغيل التطبيق, يكفي النقر على صورة فيديو أو رابط فيديو على موقع اليوتيوب و اختيار Copy link address ليتم ظهور التطبيق طالبا تأكيد عملية تحميل ملف الفيديو...

الكود الجديد يعتمد على تايمر تقوم بالعمل كل ثانية و تراقب محتوى كليبورد النظام فإذا تم التعرف على رابط صحيح تقوم بعمل اللازم :

' آخر رابط تمت مراقبته على كليبورد النظام
Private LastUrl As String = ""

التعريف أعلاه عمومي على مستوى الفورم.

' دالة الحدث Tick للتايمر المكلفة بمراقبة كليبورد النظام للعمل أوتوماتيكيا عند تواجد رابط فيديو عليه
Private Sub UrlCheckerTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UrlCheckerTimer.Tick
    ' إذا كان التطبيق في حالة انتظار
    If DownloadButton.Enabled Then
        ' إذا كان هناك نص على كليبورد النظام
        If Clipboard.ContainsText() Then
            ' الوصول إلى محتوى كليبورد النظام
            Dim s As String = Clipboard.GetText()
            ' إذا لم تتم مراقبة محتوى الكليبورد الحالي
            If s <> LastUrl Then
                ' حفظ المحتوى الحالي تفادي لتكرار المراقبة
                LastUrl = s
                ' التأكد من صحة الرابط
                If s.IndexOf("http://www.youtube.com/watch?v=") = 0 Then
                    ' إظهار النافذة الرئيسية للمستخدم
                    Me.TopMost = True
                    Me.WindowState = FormWindowState.Normal
                    ' طلب تحميل الفيديو من الموقع
                    Dim r As MsgBoxResult = MsgBox("تم التعرف على عنوان صفحة يوتيوب في الكليبورد..." & vbCrLf & "هل تريد تحميل ملف الفيديو من الصفحة؟", MsgBoxStyle.YesNo Or MsgBoxStyle.Question, "تأكيد بدء التحميل...")
                    Me.TopMost = False
                    ' تحميل أوتوماتيكي
                    If r = MsgBoxResult.Yes Then
                        URLTextBox.Text = s
                        DownloadButton.PerformClick()
                    End If
                End If
            End If
        End If
    End If
End Sub

utubdown.rar

#5

بسم الله الرحمن الرحيم

جميل ورائع بارك الله فيك ونفع بك

وشيء جميل ان ترى الكود كاملا وبه تعليقات عند كل سطر

اللهم لا سهل الا ماجعلته سهلا، وانت تجعل الصعب ان شئت سهلا

83_45a7168be2ddb.jpg

#6

السلام عليكم و رحمة الله تعالى و بركاته...

كما سبق و أشرت إليه في أول هذا الموضوع...

اقتباس
قبل المضي في الموضوع لا بد أن أنوه أنه و في أي لحظة, قد يصبح محتوى هذا الموضوع متجاوز و غير عملي لأن طريقة تحديد و إيجاد رابط ملف الفيديو يتم استخلاصه من الكود المصدر لصفحة اليوتيوب التي يظهر بداخلها الفيديو و أي تغيير أو تعديل في بنية كود صفحات الموقع تحيل الموضوع و البرنامج المرفق و الكود و المجهود إلى سلة المهملات.

كما كان متوقعا فالمشروع المرفق مع هذا الموضوع لم يعد يعمل و يظهر رسالة تفيد بحدوث خطأ أثناء عملية التعرف على اسم ملف الفيديو المراد تنزيله من موقع اليوتيوب.

سأقوم إن شاء الله بتحديث المشروع و إرفاقه مع الشرح بالطبع...

تحياتي...

#7

آسف على التأخير في تحديث البرنامج و الموضوع مع أن عملية التحديث لم تتعدى الخمس دقائق!

المشروع المرفق مع هذا الرد يعمل جيدا على تحميل فيديوهات اليوتيوب. أكثر ما أخشى بعد هذا التأخير حدوث أي تحديث في صفحات اليوتيوب ما يستدعي تحديث الموضوع مرة أخرى :P

التحديث تم داخل الدالة DownloadVideoFromYoutube() و معلم عليه حتى يتم التعرف عليه من طرف متتبعي الموضوع.

بالطبع الموضوع لا يحتاج شروحات لأن التعديل أو التحديث تم على مستوى سطر واحد من الكود

utubdown.rar

#8

شكرااااااااااااا الله يعطيك العافيه

مواضيع مشابهة