2017-06-30 13 views
5

Próbuję dodać funkcję offline do mojego odtwarzacza wideo HTML5. Próbuję zapisać pliki w systemie plików chrome jako blob, a następnie odczytać je z tego miejsca. Wierzę, że mam problem, w którym pliki nie są faktycznie zapisywane, tylko nazwa pliku. Ponieważ mój kod poniżej jest obecnie utworzony, działa, ale nadal tylko wtedy, gdy jest trwale podłączony do Internetu. Moim celem jest pobranie plików do trwałego katalogu w systemie plików, a następnie kontynuowanie gry, jeśli internet jest odłączony.Używanie systemu plików jako źródła filmów do odtwarzania offline

$(document).ready(function() { 


    var dir = "http://www.kevmoe.com/networks/gsplayer/"; 
    var fileextension = ".mp4"; 
    var srcfiles = $.ajax({ 
     //This will retrieve the contents of the folder if the folder is configured as 'browsable' 
     url: dir, 
     success: function(data) { 
      //List all .mp4 file names in the page 
      $(data).find("a:contains(" + fileextension + ")").each(function() { 
       var filename = $(this).attr("href").replace(window.location.host, "").replace("http://", ""); 

       $("#container").append("<div id='div1' class='video'><video id='video1' class='vidarray' preload='none' poster='bkg.png'><source src='" + filename + "' type='video/mp4'></video></div>"); 
       async: false; 


       window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; 

       window.requestFileSystem(window.PERSISTANT, 200000 * 1024 * 1024, initFS, errorHandler); 

       function initFS(fs) { 
        console.log('filesystem engaged'); // Just to check if everything is OK :) 
        // place the functions you will learn bellow here 
        function errorHandler(err) { 
         var msg = 'An error occured: '; 
        }; 

        function createDir(rootDir, folders) { 
         rootDir.getDirectory(folders[0], { 
          create: true 
         }, function(dirEntry) { 
          if (folders.length) { 
           createDir(dirEntry, folders.slice(1)); 
          } 
         }, errorHandler); 
        }; 

        createDir(fs.root, 'files/video/'.split('/')); 

        fs.root.getDirectory('video', {}, function(dirEntry) { 
         var dirReader = dirEntry.createReader(); 
         dirReader.readEntries(function(entries) { 
          for (var i = 0; i < entries.length; i++) { 
           var entry = entries[i]; 
           if (entry.isDirectory) { 
            console.log('Directory: ' + entry.fullPath); 
           } else if (entry.isFile) { 
            console.log('File: ' + entry.fullPath); 
           } 
          } 

         }, errorHandler); 
        }, errorHandler); 

        fs.root.getFile(filename, { 
         create: true, 
         exclusive: true 
        }, function(fileEntry) { 
         fileEntry.createWriter(function(fileWriter) { 
          var blob = new Blob([data], { 
           type: 'video/mp4' 
          }); 
          fileWriter.write(blob); 
         }, errorHandler); 

         console.log('file downloaded'); 
        }, errorHandler); 

        //Try to add an event listener for when all files are finished loading into file system. Then use another function to source the videos locally. 
        var dirReader = fs.root.createReader(); 
        var entries = []; 

        // Call the reader.readEntries() until no more results are returned. 

        dirReader.readEntries(function(results) { 

         //List all .mp4 file names in the page 
         $(results).find("a:contains(" + fileextension + ")").each(function() { 
          var filename = $(this).attr("href").replace(window.location.host, "").replace("http://", ""); 

          $("#container").append("<div id='div1' class='video'><video id='video1' class='vidarray' preload='none' poster='bkg.png'><source src='" + filename + "' type='video/mp4'></video></div>"); 
          async: false; 

         }, errorHandler); 
        }); 
       }; 

       function errorHandler() { 
        console.log('An error occured'); 
       }; 
      }); 


      var videos = $('.video'); 
      //handle ending of video 
      videos.find('video').on('ended', function() { 
       playNextVideo(videos); 
      }); 

      // start with the first one 
      playNextVideo(videos); 


      function playNextVideo(videoList) { 
       var activeVideo = videoList.filter('.active').removeClass('active'), // identify active video and remove active class 
        activeIndex = videoList.index(activeVideo), // get the active video index in the group 
        nextVideo = videoList.eq(activeIndex + 1), // get the next video in line 
        actualVideo; 

       // if there is no next video start from first 
       if (nextVideo.length == 0) nextVideo = videoList.first(); 

       // pause all videos 
       videoList.find('video').each(function() { 
        this.pause(); 
       }) 

       // get reference to next video element 
       actualVideo = nextVideo.find('video').get(0); 

       // add active class to next video 
       nextVideo.addClass('active'); 

       // load and play 
       actualVideo.volume = 0.04; 
       actualVideo.load(); 
       actualVideo.play(); 
      } 
     } 
    }); 
}); 
+0

Byłoby o pamięć podręczną przeglądarki wideo lokalnie rozwiązać swój problem lub czy nalegasz, aby został pobrany do określonego katalogu do użytku w trybie offline? Jeśli potrzebujesz go tylko do odtwarzania filmów offline [to pytanie stackoverflow] (https://stackoverflow.com/questions/34668291/html-video-in-browser-cache) może być pomocne dla Ciebie. –

+1

To może być tylko literówka, ale 'window.PERSISTANT' jest niezdefiniowany, podczas gdy' window.PERSISTENT' ma wartość 1. Jeśli nie jest (literówka), to prawdopodobnie piszesz do TYMCZASOWEGO zamiast PERSISTENT. – IronGeek

+0

Christopher. Próbowałem buforować, ale nie działało dla większych plików. – KevMoe

Odpowiedz

1

filesystem: protokołów przechowuje pliki w odniesieniu do tego samego pochodzenia jak document który żąda LocalFileSystem. To znaczy, jeśli JavaScript na Pytanie jest tworzony na przykład na http://example.org, ścieżka do LocalFileSystem powinna być tego samego pochodzenia co protokół http://example.org, a nie file:.

Jeśli próbujesz przechowywać pliki lub foldery, aby uzyskać dostęp do protokołu file:, w trybie offline, możesz utworzyć dokument .html, który będzie używany jako zakładka szablonu.

Odwiedź lokalny plik .html raz w trybie online, aby pobrać pliki i wypełnić LocalFileSystem. Jeśli navigator.onLine jest true, przejdź do http://example.org, w przeciwnym razie uzyskaj i przetwórz pliki i foldery przechowywane pod numerem LocalFileSystem.

Tworzenie listy jako JSON lub JavaScript Array aby zapisać listę plików do pobrania, zamiast analizowania .htmldocument lokalizacje plików.

Zapisz lokalny plik jako zakładkę. Uruchom Chromium, Chrome z flagą --allow-file-access-from-files, aby uzyskać dostęp do protokołu filesystem: z protokołu file: i file: przy protokole filesystem:, jeśli nie jest on podłączony do Internetu.

<!DOCTYPE html> 
<html> 
<head> 
    <title>LocalFileSystem Offline Videos Bookmark</title> 
</head> 
<body> 
<script> 

// location to visit if online 
const onLineURL = "https://lorempixel.com/" 
        + window.innerWidth 
        + "/" 
        + window.innerHeight + "/cats"; 

const props = { 
    requestedBytes: 1024 * 1024 * 20000, 
    folder: "videos", 
    // list of files to fetch for offline viewing 
    mediaList: [ 
    "http://mirrors.creativecommons.org/movingimages/webm/" 
    + "ScienceCommonsJesseDylan_240p.webm" 
    , "https://nickdesaulniers.github.io/netfix/demo/frag_bunny.mp4" 
    ] 
}; 

let grantedBytes = 0; 

function getLocalFileSystem ({requestedBytes = 0, mediaList=[], folder = ""}) { 
    if (!requestedBytes || !mediaList.length || !folder) { 
     throw new Error("requestedBytes: Number" 
        + " or mediaList: Array" 
        + " or folder: String not defined"); 
    }; 
    // do stuff with `filesystem:` URL 
    function processLocalFilePath(localPath) { 
     const video = document.createElement("video"); 
     document.body.appendChild(video); 
     video.controls = true; 
     video.src = localPath; 
    } 

    function errorHandler(err) { 
     console.log(err); 
    } 

    function writeFile(dir, fn, fp, localPath) { 
     console.log(dir, fn, fp, localPath); 
     dir.getFile(fn, {}, function(fileEntry) { 
      fileEntry.createWriter(function(fileWriter) { 
       fileWriter.onwriteend = function(e) { 
        // do stuff when file is written 
        console.log(e.type, localPath + " written"); 
        window.webkitResolveLocalFileSystemURL(localPath 
        , function(file) { 
         // file exists in LocalFileSystem 
         processLocalFilePath(localPath); 
        }, errorHandler) 
       }; 

       fileWriter.onerror = errorHandler; 
       fetch(fp).then(function(response) { 
        return response.blob() 
       }).then(function(blob) { 
        fileWriter.write(blob); 
       }).catch(errorHandler) 
      }, errorHandler); 
     }, errorHandler); 
    } 

    if (mediaList && mediaList.length) { 
     navigator.webkitTemporaryStorage.requestQuota(requestedBytes 
     , function(grantedBytes_) { 
      grantedBytes = grantedBytes_; 
      console.log("Requested bytes:", requestedBytes 
         , "Granted bytes:", grantedBytes); 
      window.webkitRequestFileSystem(window.TEMPORARY 
      , grantedBytes 
      , function(fs) { 

       const url = fs.root.toURL(); 

       mediaList.forEach(function(filename) { 

        const localPath = url + folder + "/" 
             + filename.split("/").pop(); 

        window.webkitResolveLocalFileSystemURL(localPath 
        , function(file) { 
         // file exists in LocalFileSystem 
         console.log(localPath + " exists at LocalFileSystem"); 
         processLocalFilePath(localPath) 

        }, function(err) { 
         console.log(err, localPath 
         + " not found in LocalFileSystem"); 
         // Exception is thrown if file 
         // or folder path not found 
         // create `folder` directory, get files 
         fs.root.getDirectory(folder, {} 
         , function(dir) { 
          writeFile(dir 
          , filename.split("/").pop() 
          , filename 
          , localPath); 
         }), 
         errorHandler 
        }) 
       }) 

      }) 
     }, errorHandler) 
    } 
} 

if (location.href !== onLineURL && navigator.onLine) { 
    location.href = onLineURL; 
} else { 
    getLocalFileSystem(props); 
} 

</script> 
</body> 
</html> 

Zobacz także


Alternatywnym rozwiązaniem mogłoby być wykorzystanie ServiceWorker

1

Twój użytkownik musi zezwolić Twojej aplikacji na przechowywanie danych lokalnie, zanim aplikacja będzie mogła korzystać z pamięci trwałej. Dlatego musisz najpierw poprosić o przydział. Ilość żądanych bajtów wynosi 200000 * 1024 * 1024 bajtów.

window.storageInfo.requestQuota(PERSISTENT, 200000 * 1024 * 1024, 
    function(grantedBytes) { 
     window.requestFileSystem(window.PERSISTENT, grantedBytes, onInitFs, errorHandler); 
    }, 
    errorHandler 
); 

MDN documentation

zauważyłem piszesz to dla Chrome here's how you manage the quota in Chrome

Powiązane problemy