التوقيت:

من الإضافات المهمة للتطبيق إضافة طول الملف و الوقت الحالي للتشغيل بالدقيقة والثانية

ولإضافة ذلك نحتاج إلى إستخدام خاصية CurrentPosition في كائنات تشغيل الصوت والفيديو

أو GetPosition() في كائن تشغيل ملفات الريل

حيث ان هذه الخصائص ترجع قيمة من نوع رقم تحدد الثانية الحالية التي يتم تشغيلها في الملف

فمثلاً إذا اعادت الخاصية CurrentPosition القيمة 120 فمعنى هذا أنه يتم الآن تشغيل الثانية رقم 120 في الملف

وإذا أعادت الخاصية GetPosition() القيمة 50000 فمعنى ذلك أنه يتم الآن تشغيل الثانية رقم 50 في ملف الريل

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

أما كائن تشغيل الريل فيرجع القيمة بالملي ثانية و يجب قسمتها على 1000 كي نحولها إلى ثانية

الحصول على طول الملف :

هناك خاصية أخرى عرفناها في دروس سابقة وهو خاصية Duration في كائن مشغل الصوت والفيديو

والتي ترجع قيمة من نوع رقم تمثل طول الملف بالثواني

مثلاً التعليمة التالي :


كود:
ap.Duration

لو كان ناتجها 195 فهذا يعني أن طول الملف 195 ثانية

والتعليمة :


كود:
rp.GetLength()

لو كان ناتجها 195000 فهذا يعني أن طول الملف 195000 ملي ثانية أي 195 ثانية "بالقسمة على 1000"

لأن rp هو كائن مشغل ملفات الريل و يرجع القيمة بالملي ثانية لذلك وجب القسمة على 1000 لتحويلها إلى ثانية

ولكنا نريد كتابة الوقت بالدقيقية و الثانية

وعند تحويل 195 إلى دقائق تصبح ثلاث دقائق و 15 ثانية

أي بهذه الصيغة :


كود:
3:15

نحتاج إلى معادلة رياضية لتحويل الصيغة من ثواني إلى دقائق وثواني

إيجاد الدقائق :

لإيجاد الدقائق في كائن مشغلا الصوت أو الفيديو نقسم عدد الثواني على 60 ثم نحول الناتج إلى عدد صحيح حتى يتم إزالة الكسور العشرية

فمثلاً لو قيمنا 195 على 60 سيكون الناتج 3.25 و هو عدد حقيقي لكنا نريد فقط عدد الدقائق و هو 3 وبالتالي فتحويل العدد الحقيقي إلى صحيح

يتكفل بإزالة الكسر 25 ويصبح الناتج 3


كود:
int m;m=vp.Duration/60;

السطر الأول تعريف للمتغير m من نوع رقم والذي سيحمل عدد الدقائق

والسطر الثاني إسناد طول الملف مقسوما على 60 للتحويله إلى دقائق

ولأنا نريد فقط الدقائق دون الكسور سنستخدم دالة جديدة Math.Floor والتي تحذف الكسر وترجع فقط العدد الصحيح

هذه الدالة لها مدخل من نوع رقم Double ودالتي Duration في كائنات الصوت والفيديو ترجع Double أيضاً


كود:
int m;m =Convert.ToInt32(Math.Floor(vp.Duration/60));

وبنفس الطريقة لكائن تشغيل الصوت :


كود:
int m;m =Convert.ToInt32(Math.Floor(ap.Duration/60));

أما كائن مشغل ملفات الريل فيجب كما قلنا أن نقسم الناتج على 1000 لتحويله إلى ثواني ثم نقسمع على 60 لتحويله إلى دقائق

وكما نعلم في الرياضيات فإن :


كود:
x/y/z=x/y*z

وبالتالي بدل من كتابة كود التحويل هذا :


كود:
rp.GetLength()/1000/60

يمكن كتابته هكذا :


كود:
rp.GetLength()/60000

لأن 60 * 1000 = 60000

وأيضاً دالة GetLength في كائن مشغل الريل لا ترجع قيمة من نوع Double وهذا يسبب مشكلة في التعامل مع الدالة Math.Floor

لأنه يجب أن تستقبل مدخل من نوع Double

وبالتالي يجب تحويل ناتج الدالة GetLength إلى Double :

ويصبح كود التحويل كاملاً هكذا :


كود:
int m;m = Convert.ToInt32(Math.Floor(Convert.ToDouble(rp.Get Length()/60000)));

إيجاد الثواني :

نقصد هنا بالثواني الكسر المتبقي من قسمة الثواني على 60

ولإستنتاج المعادلة الرياضية المستخدمة لإيجاد الثواني سنقسم عدد الثواني 195 إلى أربعة أقسام:


كود:
60 + 60 + 60 + 15

الثلاثة الحدود الأولي تمثل الثلاث الدقائق التي أستخرجناها من معادلة إيجاد الدقائق وبقي 15 تمثل عدد الثواني المتبقية

يجب لإيجاد الثواني المتبقية أن نستبعد الثواني التي تم تحويلها إلى دقائق

ان أننا نقوم بطرح الثواني التي تم تحويلها إلى دقائق من عدد الثواني الإجمال :


كود:
195 - (60 + 60 + 60 ) = 15

بهذه المعادلة إستطعنا إيجاد الثواني المتبقية , ولكن البرنامج كيف يصيغ ما بين الأقواس

لنحول المعادلة قليلاً :


كود:
195 - (60 * 3) = 15

ركز على رقم 3 بين الأقواس , أليس هو عدد الدقائق m الذي أوجدناه في الفرقة السابقة ؟

وبالتالي يمكن كتابة المعادلة هكذا :


كود:
195 - (60 * m) = 15

إذاً يمكن إيجاد عدد الثواني المتبقية من خلال طرح عدد الدقائق مضروباً في 60 من العدد الإجمالي للثواني

ففي كائن تشغيل الفيديو ستكون تعليمة إيجاد الثواني المتبقية هكذا :


كود:
vp.Duration-(60 * m)

وبالتحويل إلى العدد الصحيح تصبح :


كود:
Convert.ToInt32(vp.Duration-(60 * m))

إذاً لإيجاد الثواني المتبقية :


كود:
int s;s =Convert.ToInt32(vp.Duration-(60 * m));

وفي كائن تشغيل الصوت :


كود:
int s;s =Convert.ToInt32(ap.Duration-(60 * m));

وفي كائن تشغيل ملفات الريل :


كود:
int s;s =Convert.ToInt32(rp.GetLength()/1000-(60 * m));

لإيجاد الوقت الحالي :

المعادلتين السابقة كانت لإيجاد طول الملف بالدقيقة والثانية

ونحتاج إلى معادلات أخرى لإيجاد الموقع الذي يتم تشغيله حالياً بالدقيقة والثانية

وهي نفس المعادلات السابقة بإستثناء إستبدال Duration بـ CurrentPosition

في كائنات تشغيل الصوت والفيديو

وإستبدال GetLength بـ GetPosition في كائن تشغيل ملفات الريل

حيث أن CurrentPosition و GetPosition ترجع رقم الثانية التي يتم تشغيلها الآن

أو عدد الثواني التي تم تشغيلها , وبالتالي فيمكن حساب الدقائق والثواني

من خلال تطبيق المعادلات السابقة على عدد الثواني التي تم تشغيلها

مثلاً لإيجاد الدقيقة التي يتم تشغيلها حالياً في كائن مشغل الفيديو :


كود:
int m;m =Convert.ToInt32(Math.Floor(vp.CurrentPosition/60));

وفي كائن مشغل الصوت :

كود:
int m;m =Convert.ToInt32(Math.Floor(ap.CurrentPosition/60));

وفي كائن مشغل ملفات الريل :

كود:
int m;m = Convert.ToInt32(Math.Floor(Convert.ToDouble(rp.Get Position()/60000)));

ولإيجاد الثانية التي يتم تشغيلها حالياً في كائن مشغل الفيديو :

كود:
int s;s =Convert.ToInt32(vp.CurrentPosition-(60 * m));

وفي كائن مشغل الصوت :

كود:
int s;s =Convert.ToInt32(ap.CurrentPosition-(60 * m));

وفي كائن مشغل ملفات الريل :

كود:
int s;s =Convert.ToInt32(rp.GetPosition()/1000-(60 * m));

التطبيق :

إفتح تطبيق الدرس السابق , وأضف متغير محلي من نوع نص يمثل طول الملف بالدقيقة والثانية وليكن length



إنسخ هذا الإجراء إلى الكود وتأكد أنه خارج أي إجراء آخر :

كود:
void SetLength() { try { int m = 0; int s = 0; if (type == "V") { m = Convert.ToInt32(Math.Floor(vp.Duration / 60)); s = Convert.ToInt32(vp.Duration - (60 * m)); } else if (type == "A") { m = Convert.ToInt32(Math.Floor(ap.Duration / 60)); s = Convert.ToInt32(ap.Duration - (60 * m)); } else if (type == "R") { m = Convert.ToInt32(Math.Floor(Convert.ToDouble(rp.Get Length() / 60000))); s = Convert.ToInt32((rp.GetLength() / 1000) - (60 * m)); } length = Convert.ToString(m) + ":" + Convert.ToString(s); } catch { } }

الإجراء السابق SetLength وظيفته إيجاد طول الملف بالدقيقة و الثانية و إسنادة إلى المتيغر المحلي length

حيث إستخدمنا جملة شرط ثلاثية لفحص نوع الملف

و أدمجنا معادلتي إيجاد الدقائق والثواني في مكان واحد لكل نوع كما شرحنا في الدرس

وفي السطر الأخير من كود جملة try حولنا الدقائق إلى نص , ثم أضفنا إليها : و الثواني بعد تحويلها أيضاً إلى نص

حيث ان المتغير length سيحمل قيمة من نوع نص تمثل طول الملف بهذه الصيغة :


كود:
3:15

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

وبالتالي فإن إجراء تحميل الملف LoadFile هو المكان المناسب لإستدعاء

إذهب إلى كود التطبيق و أضف تعليمة الإستدعاء التالية في نهاية إجراء تحميل الملف :


كود:
SetLength();

حيث يصبح إجراء تحميل الملف هكذا :


كود:
void LoadFile(string Path) { StopFile(); ap=null;//تصفير الصوت vp=null;//تصفير الفيديو this.Controls.Add(rp);//تصفير الريل rp.Visible=false;//أخفاء مظهر الريل try { vp = Video.FromFile(Path); vp.Owner = this.panel1; panel1.Width = 400; panel1.Height = 300; type="V"; } catch { try { ap = Audio.FromFile(Path); type="A"; } catch { try { rp.SetSource(Path); type="R"; } catch { MessageBox.Show("الرجاء إختيار ملف صالح"); type="N"; } } } SetLength(); }

عند تحميل أي ملف سيتم تحميل المتغير length قيمة نصية تمثل طول الملف بالثواني والدقائق

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

ولكن قبله نحتاج إلى مكان على النافذة نكتب عليه طول الملف و الوقت الحالي للتشغيل

حيث سيكون بعذة الصيغة :


كود:
1:25/3:15

بإفتراض أن طول الملف هو 3 دقئق و 15 ثانية والوقت الحالي للتشغيل هو الدقيقة الأولى والثانية الخامسة والعشرين

إفتح نافذة التصميم و إسحب كاشن اللافته Label إلى النافذة :



ثم إختره وغير خاصية Name إلى len و غير خاصية Text إلى :


كود:
0:0/0:0

والآن إذهب إلى الكود وأنسخ هذا الإجراء وتأكد من أنه خارج أي إجراء آخر :

كود:
void SetPosition() { try { int m = 0; int s = 0; if (type == "V") { m = Convert.ToInt32(Math.Floor(vp.CurrentPosition / 60)); s = Convert.ToInt32(vp.CurrentPosition - (60 * m)); } else if (type == "A") { m = Convert.ToInt32(Math.Floor(ap.CurrentPosition / 60)); s = Convert.ToInt32(ap.CurrentPosition - (60 * m)); } else if (type == "R") { m = Convert.ToInt32(Math.Floor(Convert.ToDouble(rp.Get Position() / 60000))); s = Convert.ToInt32((rp.GetPosition() / 1000) - (60 * m)); } len.Text = Convert.ToString(m) + ":" + Convert.ToString(s) + " / " + length; } catch { } }


الإجراء السابق SetPosition يقوم بإيجاد الوقت الحالي للتشغيل بالدقيقة والثانية

في السطر الأخر من جملة try حولنا الدقيقة التي يتم تشغيلها إلى نص ثم أضفنا إليها ":"

ثم أضفنا إليها الثانية التي يتم تشغيلها حالياً , ثم أضفنا إليها "/" ثم طول الملف الذي أوجدناه في الإجراء SetLength

بقي أن نجد المكان المناسب لإستدعاء هذا الإجراء

فالمفروض أن نستدعي الإجراء كل ثانية أي أنا نحتاج إلى مؤقت Timer ولكن يوجد لدينا مؤقت من الدروس السابق

لذلك سنستخدمه عوضاً عن إضافة مؤقت جديد

إذهب إلى كود المؤقت timer1 من خلال النقر مزدوجا على كائن الموقت timer1 من نافذة التصميم

وأضف تعلمية الإستدعاء التاليه في آخر كود المؤقت :


كود:
SetPosition();

حيث يصبح كود المؤقت هكذا :


كود:
void Timer1Tick(object sender, System.EventArgs e) { try { if (trackBar1.Maximum == 0) { SetTrackBar(); } if (type=="V") { trackBar1.Value=Convert.ToInt32(vp.CurrentPosition ); } else if (type=="A") { trackBar1.Value= Convert.ToInt32(ap.CurrentPosition); } else if (type=="R") { trackBar1.Value=Convert.ToInt32(rp.GetPosition()); } SetPosition(); } catch { } }

الواجب:

أرسل التطبيق

.نهاية الدرس السادس عشر.

..