"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > لماذا يفشل خادم الويب GoLang الخاص بي في عرض مقاطع فيديو MP4 كبيرة الحجم؟

لماذا يفشل خادم الويب GoLang الخاص بي في عرض مقاطع فيديو MP4 كبيرة الحجم؟

تم النشر بتاريخ 2024-11-08
تصفح:365

Why does my GoLang webserver fail to serve large MP4 videos?

خادم ويب GoLang HTTP يخدم فيديو MP4

التحدي

تم إنشاء خادم ويب باستخدام GoLang الذي يخدم HTML / JS / CSS والصور. عندما حاول الخادم توفير ملف فيديو MP4، فشل تحميل الفيديو، ولم يظهر سوى عناصر التحكم في الفيديو.

التحقيق

عند فحص ملفات الفيديو، تم اكتشاف أن الفيديو الأصغر يعمل أثناء الفيديو الأكبر لم يفعل ذلك. كانت المشكلة متعلقة بحجم الفيديو وسلوك التخزين المؤقت الافتراضي للمتصفح.

دعم طلب النطاق:

بالنسبة لمقاطع الفيديو الأكبر من حجم معين، يتطلب المتصفح الخادم لدعم طلبات النطاق (عرض المحتوى الجزئي). يسمح هذا للمتصفح بجلب جزء الفيديو المطلوب فقط للتشغيل، مما يمنع تحميل الملف بأكمله في الذاكرة.

في هذه الحالة، لم يتم تكوين كود GoLang للتعامل مع طلبات النطاق. التنفيذ المقدم ببساطة يخدم الملف بأكمله كاستجابة واحدة. ونتيجة لذلك، لم يتمكن المتصفح من تشغيل مقطع الفيديو الأكبر حجمًا.

الحل

لحل المشكلة، تم اتباع الخطوات التالية:

    استخدم http.FileServe():
  1. يعالج أسلوب http.FileServe() طلبات النطاق بشكل افتراضي. باستخدام هذه الطريقة لخدمة ملف الفيديو، كان الخادم قادرًا على توفير محتوى جزئي للمتصفح.
  2. تكوين معالجة طلب النطاق المخصص:
  3. بدلاً من ذلك ، إذا لم يكن http.FileServe() مفضلاً، فيمكن تنفيذ معالجة طلب النطاق المخصص. يتضمن ذلك تعيين الرؤوس التالية في الاستجابة:

قبول النطاقات: بايت
  • طول المحتوى (حجم الملف)
  • نطاق المحتوى (بايت النطاق المطلوب)
استخدم رمز حالة HTTP 206:
  1. بالنسبة لطلبات النطاق، يجب على الخادم إرجاع رمز حالة HTTP لمحتوى جزئي 206 بدلاً من 200 موافق.
التنفيذ

نطاق مخصص تم تنفيذ معالجة الطلب بالطريقة التالية:

func (vh *viewHandler)servHTTP(w) http.ResponseWriter، r *http.Request) { المسار := r.URL.Path[1:] البيانات، خطأ:= ioutil.ReadFile(string(path)) إذا أخطأت == لا شيء { سلسلة نوع المحتوى var إذا strings.HasSuffix(path, ".mp4") { نوع المحتوى = "فيديو/mp4" الحجم: = ثنائي.الحجم (البيانات) إذا كان الحجم > 0 { البايتات المطلوبة := r.Header.Get("النطاق") w.Header().Add("قبول النطاقات"، "بايت") w.Header().Add("طول المحتوى"، strconv.Itoa(size)) w.Header().Add("Content-Range", "bytes " requestBytes[6:len(requestedBytes)] strconv.Itoa(size-1) "/" strconv.Itoa(size)) ث.WriteHeader(206) } } آخر { w.Header().Add("نوع المحتوى"، نوع المحتوى) ث.الكتابة (البيانات) } } آخر { سجل.Println("خطأ!") ث.WriteHeader(404) w.Write([]byte("404 - " http.StatusText(404))) }

func (vh *viewHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    path := r.URL.Path[1:]
    data, err := ioutil.ReadFile(string(path))

    if err == nil {

        var contentType string

        if strings.HasSuffix(path, ".mp4") {
            contentType = "video/mp4"
            size := binary.Size(data)
            if size > 0 {
                requestedBytes := r.Header.Get("Range")
                w.Header().Add("Accept-Ranges", "bytes")
                w.Header().Add("Content-Length", strconv.Itoa(size))
                w.Header().Add("Content-Range", "bytes " requestedBytes[6:len(requestedBytes)] strconv.Itoa(size-1) "/" strconv.Itoa(size))
                w.WriteHeader(206)
            }
        } else {
            w.Header().Add("Content-Type", contentType)
            w.Write(data)
        }
    } else {
        log.Println("ERROR!")
        w.WriteHeader(404)
        w.Write([]byte("404 - "   http.StatusText(404)))
    }
}

للتأكد من تكرار الفيديو، تمت إضافة المنطق التالي:

if contentType == "video /mp4" { http.ServeFile (ث، ص، المسار) } آخر { w.Header().Add("نوع المحتوى"، نوع المحتوى) ث.الكتابة (البيانات)

يستخدم هذا http.ServeFile() لمقاطع فيديو MP4، والذي يتعامل مع التكرار بشكل صحيح.
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3