Apple MP4 -Make and -Model adding

Started by hedegaard1, October 03, 2023, 09:28:34 AM

Previous topic - Next topic

hedegaard1

Hi,
Could someone help me with a way to add the -Make and -Model to a MP4 file i have created from a old AVI file coming from a old Canon camera.
The old and new file don't have this present today.

I have added them to the XMP tags, but it don't work when uploading to iCloud:
https://1drv.ms/i/s!AhTpFo7yM0vxj4tI0CVC7xxknwILCA?e=UQhfRT
https://1drv.ms/i/s!AhTpFo7yM0vxj4tHzx6H3fCERzjVNQ?e=ZgZWl1

And this is the command i am trying, but no quicktime Make or Model is added:
$EXIFTOOL_PATH -overwrite_original -QuickTime:Make="Canon" -QuickTime:Model="DIGITAL IXUS 500" $mp4Path


This is the powershell script i have created (In co-work with ChatGPT  ;) ) for making the nessecary changes:
The script helps me choosing a folder and then it takes all AVI files from there. It look up if the files is actually made with a Canon or else, i don't touch them with this script as it also should add the specific make and model. And it also helps me changing the time to UTC 0, as when changing to MP4 it starts to mess up my times. And the time looks into if the video is in winter or summertime and change to either +1 or +2 on the MP4 file.


# Load required assemblies
Add-Type -AssemblyName System.Windows.Forms

# Create main form
$form = New-Object System.Windows.Forms.Form
$form.Text = 'AVI Converter'
$form.Size = New-Object System.Drawing.Size(400,200)
$form.StartPosition = 'CenterScreen'

# Label for directory selection
$label = New-Object System.Windows.Forms.Label
$label.Text = 'Select Folder:'
$label.Location = New-Object System.Drawing.Point(10,20)
$label.AutoSize = $true
$form.Controls.Add($label)

# Textbox to display selected directory
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(10,40)
$textBox.Size = New-Object System.Drawing.Size(260,20)
$form.Controls.Add($textBox)

# Button to open folder browser dialog
$browseButton = New-Object System.Windows.Forms.Button
$browseButton.Text = 'Browse'
$browseButton.Location = New-Object System.Drawing.Point(280,40)
$browseButton.Add_Click({
    $folderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog
    $folderBrowser.SelectedPath = "C:\Users\xxx\Downloads\__Billeder_og_Videoer\_AVI Original" # Setting default path
    $dialogResult = $folderBrowser.ShowDialog()
    if ($dialogResult -eq [System.Windows.Forms.DialogResult]::OK) {
        $textBox.Text = $folderBrowser.SelectedPath
    }
})
$form.Controls.Add($browseButton)

# Progress Bar
$progressBar = New-Object System.Windows.Forms.ProgressBar
$progressBar.Location = New-Object System.Drawing.Point(10,120)
$progressBar.Size = New-Object System.Drawing.Size(360,20)
$form.Controls.Add($progressBar)

# Status Label
$statusLabel = New-Object System.Windows.Forms.Label
$statusLabel.Text = ''
$statusLabel.Location = New-Object System.Drawing.Point(10,100)
$statusLabel.Size = New-Object System.Drawing.Size(360,20)
$form.Controls.Add($statusLabel)

# Button to start processing
$processButton = New-Object System.Windows.Forms.Button
$processButton.Text = 'Start Processing'
$processButton.Location = New-Object System.Drawing.Point(10,70)
$processButton.Add_Click({
    if (-not [string]::IsNullOrWhiteSpace($textBox.Text)) {
        # Logic for processing AVI files
        $SOURCE_DIR = $textBox.Text
        $EXIFTOOL_PATH = "C:\Users\xxx\Downloads\__Billeder_og_Videoer\Exiftool\exiftool-12.67\exiftool.exe"

        # Get all AVI files recursively
        $aviFiles = Get-ChildItem -Path $SOURCE_DIR -Recurse -Filter "*.avi"

        $progressBar.Maximum = $aviFiles.Count
        $progressBar.Value = 0

        foreach ($file in $aviFiles) {
            # Update status label
            $statusLabel.Text = "Processing: " + $file.Name

            # Check for CanonMVI01 tag
            $tag = & $EXIFTOOL_PATH -RIFF:Software $file.FullName
            if ($tag -notlike "*CanonMVI01*") {
                # Rename if tag not found
                Rename-Item -Path $file.FullName -NewName ("New model -" + $file.Name)
            } else {
                # Convert AVI to MP4
                ffmpeg -i $file.FullName -c:v libx264 -pix_fmt yuv420p -profile:v main -level 3.1 -preset slow -crf 12 -c:a aac -b:a 128k -movflags +faststart ($file.DirectoryName + "\" + $file.BaseName + ".mp4")

                $mp4Path = $file.DirectoryName + "\" + $file.BaseName + ".mp4"
               
                # Copy metadata and adjust time
                & $EXIFTOOL_PATH -overwrite_original -tagsFromFile $file.FullName "-MediaCreateDate<DateTimeOriginal" "-FileCreateDate<DateTimeOriginal" "-CreateDate<DateTimeOriginal" $mp4Path
                & $EXIFTOOL_PATH -overwrite_original "-MediaCreateDate-=0:0:0 2:0:0" "-CreateDate-=0:0:0 2:0:0" $mp4Path
                & $EXIFTOOL_PATH -overwrite_original -Make="Canon" -Model="DIGITAL IXUS 500" $mp4Path
                & [b]$EXIFTOOL_PATH -overwrite_original -QuickTime:Make="Canon" -QuickTime:Model="DIGITAL IXUS 500" $mp4Path[/b]

            }

            $progressBar.Value++
        }

        # Rename MP4 files based on MediaCreateDate
        $mp4Files = Get-ChildItem -Path $SOURCE_DIR -Recurse -Filter "*.mp4"

        foreach ($file in $mp4Files) {
            # Extract MediaCreateDate
            $date = & $EXIFTOOL_PATH -s3 -d "%Y-%m-%d %H:%M:%S" -MediaCreateDate $file.FullName

            # Convert string to DateTime and adjust for DST
            $dateTime = [DateTime]::ParseExact($date, "yyyy-MM-dd HH:mm:ss", $null)

            # Adjust for DST (assuming DST starts last Sunday of March and ends last Sunday of October)
            if ($dateTime.Month -ge 3 -and $dateTime.Month -le 10) {
                if ($dateTime.Month -eq 3 -and $dateTime.Day -ge [DateTime]::DaysInMonth($dateTime.Year, 3) - 6) {
                    $dateTime = $dateTime.AddHours(2)
                } elseif ($dateTime.Month -eq 10 -and $dateTime.Day -le 7) {
                    $dateTime = $dateTime.AddHours(2)
                } else {
                    $dateTime = $dateTime.AddHours(2)
                }
            } else {
                $dateTime = $dateTime.AddHours(1)
            }

            # Rename file
            $newName = $dateTime.ToString("yyyy-MM-dd - HH.mm.ss") + ".mp4"
            Rename-Item -Path $file.FullName -NewName $newName
        }

        [System.Windows.Forms.MessageBox]::Show("Processing completed!", "Info", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Information)
    } else {
        [System.Windows.Forms.MessageBox]::Show("Please select a valid directory!", "Warning", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Warning)
    }
})
$form.Controls.Add($processButton)

# Display the form
$form.ShowDialog()

Hope someone can help me with adding the Make and Model, that will work with iCloud/Apple.

wywh

#1
Try this:

exiftool -m -P -overwrite_original -api LargeFileSupport=1 '-Keys:Make=Canon' '-Keys:Model=DIGITAL IXUS 500' movie.mp4
Apple's apps prefer Keys. exiftool 'QuickTime' defaults to UserData that Apple's apps do not always read (ItemList has also limited support).

Check the details with something like:

exiftool -a -G1 -s -n -api LargeFileSupport=1 -api QuickTimeUTC=1 movie.mp4
- Matti

StarGeek

Quote from: hedegaard1 on October 03, 2023, 09:28:34 AMAnd this is the command i am trying, but no quicktime Make or Model is added:

Just to clarify, you aren't double checking with exiftool but checking what iCloud says.  Because exiftool is adding the information.

As wywh says, location matters.  The Quicktime:Make tag can show up in the Keys subgroup and has three separate locations in the UserData subgroup.  Even worse is Model as it can show up in the Keys subgroup and six separate locations in the UserData subgroup.
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

hedegaard1

#3
Thanks for the help.
This was doing the trick:
exiftool -m -P -overwrite_original -api LargeFileSupport=1 '-Keys:Make=Canon' '-Keys:Model=DIGITAL IXUS 500' movie.mp4

Here is the description on my script:

Script: AVI Converter

Purpose: Convert AVI files to MP4 format, adjust metadata based on specific criteria, and move the converted files to a desired location.

Initialization:

Set default camera brand and model metadata values.
Load necessary assemblies for creating a GUI.
GUI Setup:

A form is created to allow the user to:
Select the source directory containing AVI files.
Select the destination directory to move converted MP4 files.
Start the processing via a button.
Monitor progress with a progress bar.
Processing Logic:

On pressing the "Start Processing" button:
All AVI files in the specified directory are fetched.
For each AVI file:
If it doesn't contain a specific tag, it's renamed.
If it does, it's converted to MP4 format.
Metadata of the MP4 file is then updated:
Copy metadata from the original AVI file.
Adjust the time in the metadata.
Update the 'Make' and 'Model' metadata fields using ExifTool.
Rename the MP4 files based on the 'MediaCreateDate' metadata.
File Movement:

Once all processing is complete:
The converted (and possibly renamed) MP4 files are moved to the specified destination directory. If files with the same name already exist, they are overwritten.
Completion Notification:

A message box notifies the user once the processing is completed.


# Camera Brand
$Make = "Canon"
# Camera Model
$Model = "DIGITAL IXUS 500"

# Load required assemblies
Add-Type -AssemblyName System.Windows.Forms

# Create main form
$form = New-Object System.Windows.Forms.Form
$form.Text = 'AVI Converter'
$form.Size = New-Object System.Drawing.Size(400,300) # Adjusted size for the new controls
$form.StartPosition = 'CenterScreen'

# Label for source directory selection
$label = New-Object System.Windows.Forms.Label
$label.Text = 'Select Source Folder:'
$label.Location = New-Object System.Drawing.Point(10,20)
$label.AutoSize = $true
$form.Controls.Add($label)

# Textbox to display selected source directory
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(10,40)
$textBox.Size = New-Object System.Drawing.Size(260,20)
$form.Controls.Add($textBox)

# Button to open source folder browser dialog
$browseButton = New-Object System.Windows.Forms.Button
$browseButton.Text = 'Browse'
$browseButton.Location = New-Object System.Drawing.Point(280,40)
$browseButton.Add_Click({
    $folderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog
    $folderBrowser.SelectedPath = "C:\Users\mfhl\Downloads\__Billeder_og_Videoer\_AVI Original" # Setting default path
    $dialogResult = $folderBrowser.ShowDialog()
    if ($dialogResult -eq [System.Windows.Forms.DialogResult]::OK) {
        $textBox.Text = $folderBrowser.SelectedPath
    }
})
$form.Controls.Add($browseButton)

# Label for destination directory selection
$labelDest = New-Object System.Windows.Forms.Label
$labelDest.Text = 'Select Destination Folder:'
$labelDest.Location = New-Object System.Drawing.Point(10,80)
$labelDest.AutoSize = $true
$form.Controls.Add($labelDest)

# Textbox to display selected destination directory
$textBoxDest = New-Object System.Windows.Forms.TextBox
$textBoxDest.Location = New-Object System.Drawing.Point(10,100)
$textBoxDest.Size = New-Object System.Drawing.Size(260,20)
$textBoxDest.Text = "C:\Users\mfhl\iCloudPhotos\Photos" # Setting default path
$form.Controls.Add($textBoxDest)

# Button to open destination folder browser dialog
$browseButtonDest = New-Object System.Windows.Forms.Button
$browseButtonDest.Text = 'Browse'
$browseButtonDest.Location = New-Object System.Drawing.Point(280,100)
$browseButtonDest.Add_Click({
    $folderBrowserDest = New-Object System.Windows.Forms.FolderBrowserDialog
    $folderBrowserDest.SelectedPath = $textBoxDest.Text # Setting default path from the textbox
    $dialogResultDest = $folderBrowserDest.ShowDialog()
    if ($dialogResultDest -eq [System.Windows.Forms.DialogResult]::OK) {
        $textBoxDest.Text = $folderBrowserDest.SelectedPath
    }
})
$form.Controls.Add($browseButtonDest)

# Progress Bar
$progressBar = New-Object System.Windows.Forms.ProgressBar
$progressBar.Location = New-Object System.Drawing.Point(10,180)
$progressBar.Size = New-Object System.Drawing.Size(360,20)
$form.Controls.Add($progressBar)

# Status Label
$statusLabel = New-Object System.Windows.Forms.Label
$statusLabel.Text = ''
$statusLabel.Location = New-Object System.Drawing.Point(10,160)
$statusLabel.Size = New-Object System.Drawing.Size(360,20)
$form.Controls.Add($statusLabel)

# Button to start processing
$processButton = New-Object System.Windows.Forms.Button
$processButton.Text = 'Start Processing'
$processButton.Location = New-Object System.Drawing.Point(10,130)
$processButton.Add_Click({
    if (-not [string]::IsNullOrWhiteSpace($textBox.Text) -and -not [string]::IsNullOrWhiteSpace($textBoxDest.Text)) {
        # Logic for processing AVI files
        $SOURCE_DIR = $textBox.Text
        $EXIFTOOL_PATH = "C:\Users\mfhl\Downloads\__Billeder_og_Videoer\Exiftool\exiftool-12.67\exiftool.exe"

        # Get all AVI files recursively
        $aviFiles = Get-ChildItem -Path $SOURCE_DIR -Recurse -Filter "*.avi"
        $progressBar.Maximum = $aviFiles.Count
        $progressBar.Value = 0

        foreach ($file in $aviFiles) {
            # Update status label
            $statusLabel.Text = "Processing: " + $file.Name

            # Check for CanonMVI01 tag
            $tag = & $EXIFTOOL_PATH -RIFF:Software $file.FullName
            if ($tag -notlike "*CanonMVI01*") {
                # Rename if tag not found
                Rename-Item -Path $file.FullName -NewName ("New model -" + $file.Name)
            } else {
                # Convert AVI to MP4
                & ffmpeg -i $file.FullName -c:v libx264 -pix_fmt yuv420p -profile:v main -level 3.1 -preset slow -crf 12 -c:a aac -b:a 128k -movflags +faststart ($file.DirectoryName + "\" + $file.BaseName + ".mp4")

                $mp4Path = $file.DirectoryName + "\" + $file.BaseName + ".mp4"
               
                # Copy metadata and adjust time
                & $EXIFTOOL_PATH -overwrite_original -tagsFromFile $file.FullName "-MediaCreateDate<DateTimeOriginal" "-FileCreateDate<DateTimeOriginal" "-CreateDate<DateTimeOriginal" $mp4Path
                & $EXIFTOOL_PATH -overwrite_original "-MediaCreateDate-=0:0:0 2:0:0" "-CreateDate-=0:0:0 2:0:0" $mp4Path
                & $EXIFTOOL_PATH -overwrite_original "-XMP-xmp:CreateDate+=0:0:0 2:0:0" $mp4Path

                # Update Metadata using the script block
                $commandScriptBlock = {
                    param($EXIFTOOL_PATH, $Make, $Model, $mp4Path)
                    & $EXIFTOOL_PATH -m -P -overwrite_original -api LargeFileSupport=1 -Keys:Make=$Make -Keys:Model=$Model $mp4Path
                }
                & $commandScriptBlock $EXIFTOOL_PATH $Make $Model $mp4Path

                & $EXIFTOOL_PATH -overwrite_original -QuickTime:Make=$Make -QuickTime:Model=$Model $mp4Path
            }

            $progressBar.Value++
        }

        # Rename MP4 files based on MediaCreateDate
        $mp4Files = Get-ChildItem -Path $SOURCE_DIR -Recurse -Filter "*.mp4"

        foreach ($file in $mp4Files) {
            # Extract MediaCreateDate
            $date = & $EXIFTOOL_PATH -s3 -d "%Y-%m-%d %H:%M:%S" -MediaCreateDate $file.FullName

            # Convert string to DateTime and adjust for DST
            $dateTime = [DateTime]::ParseExact($date, "yyyy-MM-dd HH:mm:ss", $null)

            # Adjust for DST (assuming DST starts last Sunday of March and ends last Sunday of October)
            if ($dateTime.Month -ge 3 -and $dateTime.Month -le 10) {
                if ($dateTime.Month -eq 3 -and $dateTime.Day -ge [DateTime]::DaysInMonth($dateTime.Year, 3) - 6) {
                    $dateTime = $dateTime.AddHours(2)
                } elseif ($dateTime.Month -eq 10 -and $dateTime.Day -le 7) {
                    $dateTime = $dateTime.AddHours(2)
                } else {
                    $dateTime = $dateTime.AddHours(2)
                }
            } else {
                $dateTime = $dateTime.AddHours(1)
            }

            # Rename file
            $newName = $dateTime.ToString("yyyy_MM_dd - HH_mm_ss") + ".mp4"
            Rename-Item -Path $file.FullName -NewName $newName

            # Move renamed MP4 files to the specified destination
            $destinationPath = $textBoxDest.Text
            Move-Item -Path ($file.DirectoryName + "\" + $newName) -Destination $destinationPath -Force
        }

        [System.Windows.Forms.MessageBox]::Show("Processing completed!", "Info", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Information)
    }
})
$form.Controls.Add($processButton)

# Display the form
$form.ShowDialog()

hedegaard1

I have made a new version of this little Powershell script with more options.

The code has been made to easier convert old AVI files to MP4 format compatible with Apple iCloud.

AVI Converter Utility Highlights:

1. Initialization:
Sets the path for iCloud Photos.
Loads necessary .NET assemblies for Windows Forms.
Initializes the main Graphical User Interface (GUI) form with specifics like size, start position, background color, and title.
Defines the font style to be used throughout the UI.

2. Camera Information Controls:
Creates labels and textboxes for the user to input:
Camera Make (default set to "Canon").
Camera Model (default set to "DIGITAL IXUS 500").
AVI Software Tag (default set to "CanonMVI01").

3. Source Folder Selection Controls:
Enables users to select the source directory containing AVI files:
A label prompts the user.
A textbox displays the selected or default directory (default set to the user's "MyVideos" folder).
A "Browse" button allows users to navigate and choose a different directory.

4. File Movement Control Section:
Provides a checkbox option to move processed files to a destination folder.
If checked, reveals controls to:
Select the destination folder (default is set to the user's iCloud Photos path).
Select the folder where completed AVI files should be stored (default is a subfolder within "MyVideos").

5. Progress and Status Display Controls:
Incorporates a progress bar to show real-time processing progress.
Displays a status label, which provides information about the current processing status (e.g., which file is currently being processed).

6. Process Execution and Button Controls:
Introduces a "Start Processing" button that, when clicked, initiates the conversion process:
Extracts values from the GUI controls.
Uses Exiftool to fetch metadata from AVI files.
Converts AVI files to MP4 using FFmpeg, ensuring high-quality conversion.
Renames files based on their metadata.
Moves the processed AVI and MP4 files to specified directories if the "Move files to Destination" option is checked.
Notifies the user upon completion with a message box.

7. Form Display Initialization:
Displays the entire GUI form to the user, making it ready for interaction.

Feel free to use:

###################################
### 1. Start of Initialization: ###
###################################
# Set iCloud Photos path
$iCloudPhotosPath = "$env:USERPROFILE\iCloudPhotos\Photos"

# Load required assemblies
Add-Type -AssemblyName System.Windows.Forms

# Initialize main GUI form
$form = New-Object System.Windows.Forms.Form
$form.Text = 'AVI Converter'
$form.Size = New-Object System.Drawing.Size(700,600)
$form.StartPosition = 'CenterScreen'
$form.BackColor = [System.Drawing.Color]::White

# Define UI font style
$font = New-Object System.Drawing.Font("Segoe UI", 10)
#################################
### 1. End of Initialization: ###
#################################

##############################################
### 2. Start of Camera Information Controls: ###
##############################################

# Label for Make input
$labelMake = New-Object System.Windows.Forms.Label
$labelMake.Text = 'Camera Make:'
$labelMake.Location = New-Object System.Drawing.Point(20,10)
$labelMake.AutoSize = $true
$labelMake.Font = $font
$labelMake.ForeColor = [System.Drawing.Color]::DarkGray
$form.Controls.Add($labelMake)

# Textbox for Make input
$textMake = New-Object System.Windows.Forms.TextBox
$textMake.Location = New-Object System.Drawing.Point(130,10)
$textMake.Size = New-Object System.Drawing.Size(200,25)
$textMake.Text = "Canon"
$textMake.Font = $font
$form.Controls.Add($textMake)

# Label for Model input
$labelModel = New-Object System.Windows.Forms.Label
$labelModel.Text = 'Camera Model:'
$labelModel.Location = New-Object System.Drawing.Point(340,10)
$labelModel.AutoSize = $true
$labelModel.Font = $font
$labelModel.ForeColor = [System.Drawing.Color]::DarkGray
$form.Controls.Add($labelModel)

# Textbox for Model input
$textModel = New-Object System.Windows.Forms.TextBox
$textModel.Location = New-Object System.Drawing.Point(450,10)
$textModel.Size = New-Object System.Drawing.Size(200,25)
$textModel.Text = "DIGITAL IXUS 500"
$textModel.Font = $font
$form.Controls.Add($textModel)

# Define label for tag input
$labelTag = New-Object System.Windows.Forms.Label
$labelTag.Text = 'AVI Software Tag:'
$labelTag.Location = New-Object System.Drawing.Point(20,50)
$labelTag.AutoSize = $true
$labelTag.Font = $font
$labelTag.ForeColor = [System.Drawing.Color]::DarkGray
$form.Controls.Add($labelTag)

# Define textbox for entering tag
$textTag = New-Object System.Windows.Forms.TextBox
$textTag.Location = New-Object System.Drawing.Point(130,50)
$textTag.Size = New-Object System.Drawing.Size(200,25)
$textTag.Text = "CanonMVI01"  # Default value (you can change this if required)
$textTag.Font = $font
$form.Controls.Add($textTag)

##############################################
### 2. End of Camera Information Controls: ###
##############################################

#####################################################
### 3. Start of Source Folder Selection Controls: ###
#####################################################
# Label for source directory selection
$label = New-Object System.Windows.Forms.Label
$label.Text = 'Select Source Folder:'
$label.Location = New-Object System.Drawing.Point(20,90)  # Adjusted the Y-coordinate here
$label.AutoSize = $true
$label.Font = $font
$label.ForeColor = [System.Drawing.Color]::DarkGray
$form.Controls.Add($label)

# Define textbox to show chosen source directory
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(20,120)
$textBox.Size = New-Object System.Drawing.Size(540,25)
$textBox.Text = [Environment]::GetFolderPath("MyVideos")
$textBox.Font = $font
$form.Controls.Add($textBox)

# Define button to trigger source folder selection
$browseButton = New-Object System.Windows.Forms.Button
$browseButton.Text = 'Browse'
$browseButton.Location = New-Object System.Drawing.Point(570,120)
$browseButton.Size = New-Object System.Drawing.Size(100,25)
$browseButton.Font = $font
$browseButton.Add_Click({
    $folderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog
    $videosPath = [Environment]::GetFolderPath("MyVideos")
    $folderBrowser.SelectedPath = $videosPath
    $dialogResult = $folderBrowser.ShowDialog()
    if ($dialogResult -eq [System.Windows.Forms.DialogResult]::OK) {
        $textBox.Text = $folderBrowser.SelectedPath
    }
})
$form.Controls.Add($browseButton)
###################################################
### 3. End of Source Folder Selection Controls: ###
###################################################

##################################################
### 4. Start of File Movement Control Section: ###
##################################################
# CheckBox for moving files to destination
$moveCheckBox = New-Object System.Windows.Forms.CheckBox
$moveCheckBox.Text = 'Move files to Destination'
$moveCheckBox.Checked = $false
$moveCheckBox.Location = New-Object System.Drawing.Point(20,160)
$moveCheckBox.Font = $font
$moveCheckBox.ForeColor = [System.Drawing.Color]::DarkGray
$form.Controls.Add($moveCheckBox)

$moveCheckBox.Add_CheckedChanged({
    if ($moveCheckBox.Checked) {
        $labelDest.Visible = $true
        $textBoxDest.Visible = $true
        $browseButtonDest.Visible = $true
        $labelAVIStore.Visible = $true
        $textBoxAVIStore.Visible = $true
        $browseButtonAVIStore.Visible = $true
    } else {
        $labelDest.Visible = $false
        $textBoxDest.Visible = $false
        $browseButtonDest.Visible = $false
        $labelAVIStore.Visible = $false
        $textBoxAVIStore.Visible = $false
        $browseButtonAVIStore.Visible = $false
    }
})

# Label for destination directory selection
$labelDest = New-Object System.Windows.Forms.Label
$labelDest.Text = 'Select Destination Folder:'
$labelDest.Location = New-Object System.Drawing.Point(20,200)
$labelDest.AutoSize = $true
$labelDest.Font = $font
$labelDest.ForeColor = [System.Drawing.Color]::DarkGray
$labelDest.Visible = $false
$form.Controls.Add($labelDest)

# Textbox to display selected destination directory with increased width
$textBoxDest = New-Object System.Windows.Forms.TextBox
$textBoxDest.Location = New-Object System.Drawing.Point(20,230)
$textBoxDest.Size = New-Object System.Drawing.Size(540,25)
$textBoxDest.Text = $iCloudPhotosPath
$textBoxDest.Font = $font
$textBoxDest.Visible = $false
$form.Controls.Add($textBoxDest)

# Button to open destination folder browser dialog
$browseButtonDest = New-Object System.Windows.Forms.Button
$browseButtonDest.Text = 'Browse'
$browseButtonDest.Location = New-Object System.Drawing.Point(570,230)
$browseButtonDest.Size = New-Object System.Drawing.Size(100,25)
$browseButtonDest.Font = $font
$browseButtonDest.Add_Click({
    $folderBrowserDest = New-Object System.Windows.Forms.FolderBrowserDialog
    $folderBrowserDest.SelectedPath = $iCloudPhotosPath
    $dialogResultDest = $folderBrowserDest.ShowDialog()
    if ($dialogResultDest -eq [System.Windows.Forms.DialogResult]::OK) {
        $textBoxDest.Text = $folderBrowserDest.SelectedPath
    }
})
$browseButtonDest.Visible = $false
$form.Controls.Add($browseButtonDest)

# New Label for AVI files storage directory selection
$labelAVIStore = New-Object System.Windows.Forms.Label
$labelAVIStore.Text = 'Select Folder for completed AVI files:'
$labelAVIStore.Location = New-Object System.Drawing.Point(20,270)
$labelAVIStore.AutoSize = $true
$labelAVIStore.Font = $font
$labelAVIStore.ForeColor = [System.Drawing.Color]::DarkGray
$labelAVIStore.Visible = $false
$form.Controls.Add($labelAVIStore)

# New Textbox to display selected AVI files storage directory
$textBoxAVIStore = New-Object System.Windows.Forms.TextBox
$textBoxAVIStore.Location = New-Object System.Drawing.Point(20,300)
$textBoxAVIStore.Size = New-Object System.Drawing.Size(540,25)
$textBoxAVIStore.Text = [Environment]::GetFolderPath("MyVideos") + "\Completed Video Files"
$textBoxAVIStore.Font = $font
$textBoxAVIStore.Visible = $false
$form.Controls.Add($textBoxAVIStore)

# New Button to open AVI storage folder browser dialog
$browseButtonAVIStore = New-Object System.Windows.Forms.Button
$browseButtonAVIStore.Text = 'Browse'
$browseButtonAVIStore.Location = New-Object System.Drawing.Point(570,300)
$browseButtonAVIStore.Size = New-Object System.Drawing.Size(100,25)
$browseButtonAVIStore.Font = $font
$browseButtonAVIStore.Visible = $false  # Ensure initial visibility is set to false
$browseButtonAVIStore.Add_Click({
    $folderBrowserAVIStore = New-Object System.Windows.Forms.FolderBrowserDialog
    $folderBrowserAVIStore.SelectedPath = $textBoxAVIStore.Text
    $dialogResultAVIStore = $folderBrowserAVIStore.ShowDialog()
    if ($dialogResultAVIStore -eq [System.Windows.Forms.DialogResult]::OK) {
        $textBoxAVIStore.Text = $folderBrowserAVIStore.SelectedPath
    }
})
$form.Controls.Add($browseButtonAVIStore)
################################################
### 4. End of File Movement Control Section: ###
################################################

#########################################################
### 5. Start of Progress and Status Display Controls: ###
#########################################################
# Progress Bar and Status Label
$progressBar = New-Object System.Windows.Forms.ProgressBar
$progressBar.Location = New-Object System.Drawing.Point(20,510)
$progressBar.Size = New-Object System.Drawing.Size(650,25)
$form.Controls.Add($progressBar)

# Status Label with increased width
$statusLabel = New-Object System.Windows.Forms.Label
$statusLabel.Text = 'Process completion:'
$statusLabel.Location = New-Object System.Drawing.Point(20,490)
$statusLabel.Size = New-Object System.Drawing.Size(650,25)
$statusLabel.Font = $font
$statusLabel.ForeColor = [System.Drawing.Color]::DarkGray
$form.Controls.Add($statusLabel)
#######################################################
### 5. End of Progress and Status Display Controls: ###
#######################################################

##########################################################
### 6. Start of Process Execution and Button Controls: ###
##########################################################
# Button to start processing
$processButton = New-Object System.Windows.Forms.Button
$processButton.Text = 'Start Processing'
$processButton.Location = New-Object System.Drawing.Point(20,440)
$processButton.Size = New-Object System.Drawing.Size(150,40)
$processButton.Font = $font
$processButton.Add_Click({
    # Extract values from GUI controls and assign to local variables
    $sourceDirValue = $textBox.Text
    $tagValue = $textTag.Text
    $makeValue = $textMake.Text
    $modelValue = $textModel.Text
    $aviStorageBasePathValue = $textBoxAVIStore.Text
    $destinationPathValue = $textBoxDest.Text

    if (-not [string]::IsNullOrWhiteSpace($sourceDirValue)) {
        $EXIFTOOL_PATH = "C:\Users\mfhl\Downloads\__Billeder_og_Videoer\Exiftool\exiftool-12.67\exiftool.exe"
        $aviFiles = Get-ChildItem -Path $sourceDirValue -Recurse -Filter "*.avi"
        $progressBar.Maximum = $aviFiles.Count
        $progressBar.Value = 0

        foreach ($file in $aviFiles) {
            $statusLabel.Text = "Processing: " + $file.Name
       
            $tag = & $EXIFTOOL_PATH -RIFF:Software $file.FullName
            if ($tag -notlike "*$tagValue*") {
                Rename-Item -Path $file.FullName -NewName ("New model -" + $file.Name)
            } else {
                & ffmpeg -i $file.FullName -c:v libx264 -pix_fmt yuv420p -profile:v main -level 3.1 -preset slow -crf 12 -c:a aac -b:a 128k -movflags +faststart -map_metadata 0 ($file.DirectoryName + "\" + $file.BaseName + ".mp4")
                $mp4Path = $file.DirectoryName + "\" + $file.BaseName + ".mp4"
                & $EXIFTOOL_PATH -overwrite_original -tagsFromFile $file.FullName "-MediaCreateDate<DateTimeOriginal" "-FileCreateDate<DateTimeOriginal" "-CreateDate<DateTimeOriginal" $mp4Path
       
                $commandScriptBlock = {
                    param($EXIFTOOL_PATH, $makeValue, $modelValue, $mp4Path)
                    & $EXIFTOOL_PATH -m -P -overwrite_original -api LargeFileSupport=1 -Keys:Make=$makeValue -Keys:Model=$modelValue $mp4Path
                }
                & $commandScriptBlock $EXIFTOOL_PATH $makeValue $modelValue $mp4Path
                & $EXIFTOOL_PATH -overwrite_original -QuickTime:Make=$makeValue -QuickTime:Model=$modelValue $mp4Path
       
                # Extract DateTimeOriginal from the AVI file
                $dateTimeOriginal = & $EXIFTOOL_PATH -s3 -d "%Y-%m-%d" -RIFF:DateTimeOriginal $file.FullName
                $dateParts = $dateTimeOriginal -split '-'
                $year = $dateParts[0]
                $month = $dateParts[1]
       
                # Create folder structure based on DateTimeOriginal
                $newAVIPath = "$aviStorageBasePathValue\$year\$month"
                if (-not (Test-Path $newAVIPath)) {
                    New-Item -Path $newAVIPath -ItemType Directory
                }
       
                # Move the AVI file to the new location only if the checkbox is checked
                if ($moveCheckBox.Checked) {
                    Move-Item -Path $file.FullName -Destination $newAVIPath
                }
            }
            $progressBar.Value++
        }
       

        $mp4Files = Get-ChildItem -Path $sourceDirValue -Recurse -Filter "*.mp4"
        foreach ($file in $mp4Files) {
            $date = & $EXIFTOOL_PATH -s3 -d "%Y-%m-%d %H:%M:%S" -MediaCreateDate $file.FullName
            $dateTime = [DateTime]::ParseExact($date, "yyyy-MM-dd HH:mm:ss", $null)
            $newName = $dateTime.ToString("yyyy_MM_dd - HH_mm_ss") + ".mp4"
            Rename-Item -Path $file.FullName -NewName $newName
            if ($moveCheckBox.Checked) {
                Move-Item -Path ($file.DirectoryName + "\" + $newName) -Destination $destinationPathValue -Force
            }
        }

        [System.Windows.Forms.MessageBox]::Show("Processing completed!", "Info", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Information)
    }
})

$form.Controls.Add($processButton)
########################################################
### 6. End of Process Execution and Button Controls: ###
########################################################

################################################
### 7. Start of Form Display Initialization: ###
################################################
# Display the form
$form.ShowDialog()
##############################################
### 7. End of Form Display Initialization: ###
##############################################