diff --git a/src/applications/files/conduit/FileUploadChunkConduitAPIMethod.php b/src/applications/files/conduit/FileUploadChunkConduitAPIMethod.php
--- a/src/applications/files/conduit/FileUploadChunkConduitAPIMethod.php
+++ b/src/applications/files/conduit/FileUploadChunkConduitAPIMethod.php
@@ -51,6 +51,16 @@
       $start,
       $start + $length);
 
+    // If this is the initial chunk, leave the MIME type unset so we detect
+    // it and can update the parent file. If this is any other chunk, it has
+    // no meaningful MIME type. Provide a default type so we can avoid writing
+    // it to disk to perform MIME type detection.
+    if (!$start) {
+      $mime_type = null;
+    } else {
+      $mime_type = 'application/octet-stream';
+    }
+
     // NOTE: These files have a view policy which prevents normal access. They
     // are only accessed through the storage engine.
     $chunk_data = PhabricatorFile::newFromFileData(
@@ -58,13 +68,26 @@
       array(
         'name' => $file->getMonogram().'.chunk-'.$chunk->getID(),
         'viewPolicy' => PhabricatorPolicies::POLICY_NOONE,
+        'mime-type' => $mime_type,
       ));
 
     $chunk->setDataFilePHID($chunk_data->getPHID())->save();
 
+    $needs_update = false;
+
     $missing = $this->loadAnyMissingChunk($viewer, $file);
     if (!$missing) {
-      $file->setIsPartial(0)->save();
+      $file->setIsPartial(0);
+      $needs_update = true;
+    }
+
+    if (!$start) {
+      $file->setMimeType($chunk_data->getMimeType());
+      $needs_update = true;
+    }
+
+    if ($needs_update) {
+      $file->save();
     }
 
     return null;
diff --git a/src/applications/files/storage/PhabricatorFile.php b/src/applications/files/storage/PhabricatorFile.php
--- a/src/applications/files/storage/PhabricatorFile.php
+++ b/src/applications/files/storage/PhabricatorFile.php
@@ -270,10 +270,8 @@
 
     $file->setByteSize($length);
 
-    // TODO: We might be able to test the first chunk in order to figure
-    // this out more reliably, since MIME detection usually examines headers.
-    // However, enormous files are probably always either actually raw data
-    // or reasonable to treat like raw data.
+    // NOTE: Once we receive the first chunk, we'll detect its MIME type and
+    // update the parent file. This matters for large media files like video.
     $file->setMimeType('application/octet-stream');
 
     $chunked_hash = idx($params, 'chunkedHash');