Dans certains fichiers FLV, la durée de lecture était supérieure à 2 heures, même si la vidéo était d'environ 2 minutes, et la vidéo ne s'est pas bien lue. Corrigez cela pour qu'il puisse être joué proprement. FLV MetaData Injector ne semble pas être un problème, alors j'aimerais en trouver la cause et y remédier.
Pour le moment, utilisez FLV Extract pour diviser en fichier vidéo (.264), fichier audio (.aac) et time code (.txt). En conséquence, il n'y avait aucun problème avec la vidéo et l'audio, et il semblait y avoir un problème avec la description du code temporel. Quand je l'ouvre, cela ressemble à ce qui suit.
timecode.txt
# timecode format v2
0
0
70
134
334
609
952
1358
1816
2352
2957
Le code temporel, qui augmente en millisecondes, gonfle et grossit. De plus, la valeur numérique devient parfois plus petite (le code temporel contient la valeur numérique du temps écoulé, donc elle diminue = il ne faut pas rembobiner ...).
1305237
1329824
1354481
24718
49511
74372
99290
Après avoir fait divers calculs,
Il semble que (au moins ça ressemblait à ça). Le calcul basé sur ces résultats est le suivant.
0 -> 0
0 -> 0
70 -> 70
134 -> 134
334 -> 200
609 -> 275
952 -> 343
1358 -> 406
...
1329824 -> 24587
1354481 -> 24657
24718 -> 24718
49511 -> 24793
74372 -> 24861
99290 -> 24918
Il augmente d'environ 66 (millisecondes) (un code temporel d'environ 15 images) et semble correct.
J'ai modifié ce nombre comme suit (toute langue est acceptable car il ne s'agit que d'entrée / sortie de fichier et de calcul simple)
timecode.py
import sys
import os
import datetime
filename =''
if(len(sys.argv) > 1):
filename = os.path.abspath(sys.argv[1])
else:
filename = 'timecode.txt'
f = open(filename)
lines = []
header = []
for i,line in enumerate(f.readlines()):
#Séparez le code temporel de l'en-tête au début de la ligne
if(line.startswith('#') == False):
lines.append(int(line))
else:
header.append(line)
f.close()
timecodes = []
val = 0
for i,line in enumerate(lines):
#0 reste tel quel
if(line == 0):
timecodes.append(line)
#Une valeur plus petite que l'avant est estimée comme étant le code temporel correct, insérez-la telle quelle
elif(line < lines[i-1]):
if(timecodes[i-1] < line):
timecodes.append(line)
#Si indéfini (plus petit que le code temporel précédent), insérez le code temporel précédent tel quel
else:
timecodes.append(timecodes[i-1])
else:
#Si vous prenez la différence par rapport à la ligne précédente, cela semble être le code temporel correct
val = line - lines[i-1]
#Si le même numéro continue, définissez le numéro précédent
if(val == 0):
timecodes.append(timecodes[i-1])
#Si la différence est inférieure à l'avant (la valeur d'origine est supposée être le code temporel correct), insérez-la telle quelle
elif(timecodes[i-1] > val):
timecodes.append(line)
#Sinon, insérez diff
else:
timecodes.append(val)
#Faire une liste de chaînes avec un saut de ligne à la fin
output = [str(v)+'\n' for v in timecodes]
now = datetime.datetime.now()
#Insérer un en-tête de code temporel
header.extend(output)
#Enregistrez le fichier et quittez
if(len(sys.argv) > 1):
o_file,o_ext = os.path.splitext(os.path.abspath(sys.argv[1]))
filename = o_file + now.strftime('_%Y%m%d%H%M%S') + o_ext
else:
filename = 'timecode_change' + now.strftime('_%Y%m%d%H%M%S') + '.txt'
with open(filename, mode='w') as f:
f.writelines(header)
J'ai utilisé MKVToolNix pour combiner le code temporel modifié avec la première vidéo / audio. Lorsque j'ai lu le fichier mkv terminé, il a joué magnifiquement.
Utilisez pyinstaller pour en faire un fichier exécutable afin qu'il puisse être utilisé par des personnes qui n'ont pas installé python. Si vous faites glisser et déposez le fichier vers le timecode.exe terminé, le fichier de timecode modifié sera généré dans le même dossier.
$ pyinstaller --onefile timecode.py
** 1. Placez le fichier FLV cible dans Extrait FLV et divisez-le en fichiers vidéo / audio / time code. 2. Déterminez la logique de correction 3. Appliquez le processus de correction ci-dessus au fichier de code temporel 4. Placez le code temporel modifié et le fichier vidéo / audio divisé dans MKVToolNix et combinez-les pour créer un fichier mkv. 5. Jouer **
Puisqu'il est pratique de pouvoir traiter 1 à 4 ensemble, je l'ai ajouté au code ci-dessus et il est devenu comme suit.
timecode.py
###################################################################################################
#
#Le temps de lecture de FLV est étrange, donc
#Script pour modifier le fichier de code temporel extrait de FLV Extractor
#Lorsqu'il est combiné avec des fichiers vidéo et audio avec MKV toolnix en utilisant le code temporel modifié
#Si le code temporel suit cette règle, ce sera un fichier mkv qui pourra être lu correctement.
#Installez FLV Extract et MKV ToolNix, et placez le fichier exécutable dans le PATH.
#
###################################################################################################
import sys
import os
import datetime
import subprocess
import tempfile
import shutil
#===================================================================================================
#Extraction de code temporel avec extrait flv
#===================================================================================================
def flvExtract(flvFilename,outputDir):
cmd = [
'flvextractcl',
'-t',
'-v',
'-a',
'-d',
outputDir,
flvFilename,
]
print(flvFilename)
subprocess.call(cmd)
#===================================================================================================
#Lire et modifier le fichier de code temporel
#===================================================================================================
def repairTimecode(timecodeFilename):
f = open(timecodeFilename)
lines = []
header = []
for i,line in enumerate(f.readlines()):
#Séparez le code temporel de l'en-tête au début de la ligne
if(line.startswith('#') == False):
lines.append(int(line))
else:
header.append(line)
f.close()
timecodes = []
val = 0
for i,line in enumerate(lines):
#0 reste tel quel
if(line == 0):
timecodes.append(line)
#Une valeur plus petite que l'avant est estimée comme étant le code temporel correct, insérez-la telle quelle
elif(line < lines[i-1]):
if(timecodes[i-1] < line):
timecodes.append(line)
#Si indéfini (plus petit que le code temporel précédent), insérez le code temporel précédent tel quel
else:
timecodes.append(timecodes[i-1])
else:
#Si vous prenez la différence par rapport à la ligne précédente, cela semble être le code temporel correct
val = line - lines[i-1]
#Si le même numéro continue, définissez le numéro précédent
if(val == 0):
timecodes.append(timecodes[i-1])
#Si la différence est inférieure à l'avant (la valeur d'origine est supposée être le code temporel correct), insérez-la telle quelle
elif(timecodes[i-1] > val):
timecodes.append(line)
#Sinon, insérez diff
else:
timecodes.append(val)
if(i > 0 and timecodes[i] < timecodes[i-1]):
print(timecodes[i-1])
print(timecodes[i])
print('\n')
#Faire une liste de chaînes avec un saut de ligne à la fin
output = [str(v)+'\n' for v in timecodes]
#Insérer un en-tête de code temporel
header.extend(output)
#Enregistrer le fichier en écrasant
with open(timecodeFilename, mode='w') as f:
f.writelines(header)
return
#===================================================================================================
#Combinez vidéo, audio et code temporel modifié avec MKVToolNIX
#===================================================================================================
def mkvMerge(video,audio,timecode,outputDir):
now = datetime.datetime.now()
basename = os.path.splitext(os.path.abspath(video))[0]
mkv = basename + now.strftime('_%Y%m%d%H%M%S') + '.mkv'
#Utilisez mkvmerge
#Créer mkv en multiplexant divers fichiers
cmd = [
'mkvmerge',
'-o',
mkv,
'--timecodes',
'0:' + timecode,
video,
audio
]
subprocess.call(cmd)
#Sortie vers le répertoire spécifié
shutil.move(mkv,outputDir)
return
#===================================================================================================
#Traitement principal
#===================================================================================================
def main():
flvFilename = ''
#Obtenir le nom du fichier
if(len(sys.argv) > 1):
flvFilename = os.path.abspath(sys.argv[1])
else:
flvFilename = os.path.join(os.getcwd(),'test.flv')
#Préparez trois noms de fichier: vidéo, audio et code temporel
o_file = os.path.splitext(os.path.basename(flvFilename))[0]
outputDir = os.path.dirname(os.path.abspath(flvFilename))
#Créer un répertoire temporaire pour le travail
with tempfile.TemporaryDirectory() as tmpDir:
print(tmpDir+'\n')
#Extrait avec extrait FLV
flvExtract(flvFilename,tmpDir)
timecodeFilename = os.path.join(tmpDir,o_file + '.txt')
videoFilename = os.path.join(tmpDir,o_file + '.264')
audioFilename =os.path.join(tmpDir,o_file + '.aac')
#Réparation de code temporel et création de MKV si des fichiers vidéo / audio / code temporel existent
if(os.path.exists(timecodeFilename) and os.path.exists(videoFilename) and os.path.exists(audioFilename)):
repairTimecode(timecodeFilename)
mkvMerge(videoFilename,audioFilename,timecodeFilename,outputDir)
#Pour le fichier FLV utilisé pour le traitement, ajoutez un horodatage au nom du fichier et déplacez-le dans le répertoire FLV directement en dessous.
os.makedirs(os.path.join(outputDir,'flv'),exist_ok=True)
flv = datetime.datetime.now().strftime('%Y%m%d%H%M%S') + '_' + os.path.splitext(os.path.basename(flvFilename))[0] + '.flv'
shutil.move(flvFilename,os.path.join(os.path.join(outputDir,'flv'),flv))
main()
C'était une bonne solution, et je n'ai pas pu la résoudre en premier lieu, et il y avait certaines choses que je ne pouvais pas aider parce que le code temporel était tout à 0. (Il est possible de calculer la longueur à partir de la longueur du fichier audio, de la diviser par le nombre d'images vidéo et de produire un code temporel provisoire, mais bien sûr, l'écart sonore sera important)
Cependant, si vous rencontrez un problème dans la même situation, il est recommandé de regarder le code temporel pour le moment.