1

I have a large sized video saved in my documents directory. I want to retrieve this video and remove it's first 5 bytes. For large video files of above 300 MB using [NSData(contentsOf: videoURL)] causing Memory issue error.

I have gone through Swift: Loading a large video file (over 700MB) into memory and found that we need to use [InputStream] and [OutputStream] or [NSFileHandle]for large files. How to use it?

Sample code is given below:

   let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
   let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
   let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
   if let dirPath = paths.first{
      let videoURL = URL(fileURLWithPath: dirPath).appendingPathComponent(filePath)
          do {
                let videoData = try NSData(contentsOf: videoURL)
                let mutabledata = videoData.mutableCopy() as! NSMutableData
                mutabledata.replaceBytes(in: NSRange(location: 0, length: 5), withBytes: nil, length: 0)
   }catch {
       print("Error Writing video: \(error)")
   }
Sona
  • 394
  • 3
  • 15

2 Answers2

0

This works for me for changing the first 4 bytes and I get no deprecation warnings.

let input = FileHandle(forWritingAtPath: "/tmp/test.in")!
input.write("12345".data(using: .utf8)!)
netdigger
  • 3,659
  • 3
  • 26
  • 49
  • Is this filesize is actual file data.count? If so, that cause my app to crash(Memory issue) at input.read(pointer, maxLength: filesize - toSkip) – Sona Sep 24 '19 at 10:14
  • This will write that specific data to the receiver right? @netigger – Sona Sep 25 '19 at 04:39
  • Yes, and replace whatever was there in the first place – netdigger Sep 25 '19 at 04:40
  • Reading to EOF causing crash for video of 400 MB. – Sona Sep 25 '19 at 04:54
  • Exactly what are you doing? I've tried myself to change the first 5 bytes of a 400MB file and that works great. – netdigger Sep 25 '19 at 07:47
  • As I said, I want to open a file(.mp4 file) saved in app's documents directory and to remove it's first 5 bytes. Then, I need to save this updated file (as .mp4) in app's directory. – Sona Sep 25 '19 at 07:54
  • I know you said that, but does the code I’ve written above crash for you? Or what is crashing? – netdigger Sep 25 '19 at 07:55
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/199942/discussion-between-zeona-and-netigger). – Sona Sep 25 '19 at 07:56
0

Solved this issue using InputStream/OutputStream.

I have used InputStream to read the video, removed its first 5 bytes using dropFirst() method of Array and saved the new data using OutputStream.write().

Sample code:

func read(stream : InpuStream){
        let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: totalLength)
        while stream.hasBytesAvailable {
            let length = self.inputStream.read(buffer, maxLength: totalLength)
            if(length == totalLength){
                let array = Array(UnsafeBufferPointer(start: buffer, count: totalLength))
                var newArray: [UInt8] = []
                newArray = [UInt8](array.dropFirst(5))
            }
    }
    func write(){
        let data = Data(_: newArray)
        data.withUnsafeBytes({ (rawBufferPointer: UnsafeRawBufferPointer) -> Int in
            let bufferPointer = rawBufferPointer.bindMemory(to: UInt8.self)
            return self.outputStream.write(bufferPointer.baseAddress!, maxLength: data.count)
        })
    }
Sona
  • 394
  • 3
  • 15