Skip to content

Commit

Permalink
Upload files
Browse files Browse the repository at this point in the history
  • Loading branch information
DaiDiT committed May 7, 2024
0 parents commit 5ebe815
Show file tree
Hide file tree
Showing 9 changed files with 621 additions and 0 deletions.
20 changes: 20 additions & 0 deletions core/audio_processor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import numpy as np
from pydub.utils import mediainfo

from ui.utils.file_utils import getFileNameAndExtension

def getBitRate(filePath):
audioInfo = mediainfo(filePath)
bitrate = audioInfo['bit_rate']

return str(int(bitrate)//1000) + 'k'

def changeVolume(audioSegment, val):
audioSegment = audioSegment + val

return audioSegment

def saveAudio(filePath, audioSegment, bitrate):
fileType = getFileNameAndExtension(filePath)[1]

audioSegment.export(filePath, format=fileType[1:], bitrate=bitrate)
69 changes: 69 additions & 0 deletions core/image_processor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import cv2
import numpy as np

def loadImage(filePath):
return cv2.imread(filePath)

def convertColor(image):
return cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

def resizeImage(image, width, height):
widthScale = width / image.shape[1]
heightScale = height / image.shape[0]
scale = widthScale if widthScale != 1 else heightScale

dimension = (int(image.shape[1] * scale), int(image.shape[0] * scale))

return cv2.resize(image, dimension)

def rotateImage(image, angle):
width = image.shape[1]
height = image.shape[0]
rotationMatrix = cv2.getRotationMatrix2D((width/2,height/2), angle, 1)

return cv2.warpAffine(image, rotationMatrix,(width,height))

def flipImage(image, direction):
return cv2.flip(image, 1) if direction == 'horizontal' else cv2.flip(image, 0)

def adjustBrightness(image, val):
image = np.int16(image)
image += val*2
image = np.clip(image, 0, 255)
return np.uint8(image)

def adjustContrast(image, val):
image = np.int16(image)
image = image * (val / 127 + 1) - val
image = np.clip(image, 0, 255)
return np.uint8(image)

def adjustSaturation(image, val):
if len(image.shape) < 3:
return image

saturationScale = (val + 100) / 100

image = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
image = np.float32(image)

image[:, :, 1] *= saturationScale
image[:, :, 1] = np.clip(image[:, :, 1], 0, 255)

image = np.uint8(image)

return cv2.cvtColor(image, cv2.COLOR_HSV2RGB)

def applyBlur(image):
return cv2.blur(image, (15, 15))

def applyNoiseGause(image):
noise_gauss = np.random.normal(0,1,image.size)
noise_gauss = noise_gauss.reshape(image.shape[0],image.shape[1],image.shape[2]).astype('uint8')
image = image + image * noise_gauss

return image

def saveImage(filePath, image):
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
cv2.imwrite(filePath, image)
18 changes: 18 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import sys
from PyQt5.QtWidgets import QApplication
from ui.main_window import MainWindow

def loadStylesheet(path):
with open(path, "r") as f:
return f.read()

def main():
app = QApplication(sys.argv)
app.setStyleSheet(loadStylesheet("resources/styles/style.qss"))

mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())

if __name__ == "__main__":
main()
Binary file added resources/icons/app_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions resources/styles/style.qss
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#scrollArea {
margin: 10px;
}

#appDescription {
font-size: 20px;
font-weight: bold;
margin: 20px;
}

#imgButton, #audioButton {
font-weight: bold;
margin: 10px;
padding: 10px
}
186 changes: 186 additions & 0 deletions ui/audio_processing_window.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QHBoxLayout, QLabel, QFileDialog, QSlider, QComboBox, QSpacerItem, QSizePolicy
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import QTimer, Qt
from pydub import AudioSegment
from pydub.playback import _play_with_simpleaudio

from core.audio_processor import *
from ui.utils.file_utils import saveAudioFileDialog

class AudioProcessingWindow(QWidget):
def __init__(self, parent=None, fileName=None):
super().__init__()
self.parent = parent
self.setWindowIcon(QIcon("resources/icons/app_icon.png"))
self.setWindowTitle("Audio Processing - {}".format(fileName))
self.setGeometry(300, 300, 350, 170)

self.initUI()
self.filePath = None
self.audioSegment = None
self.timer = QTimer()
self.timer.timeout.connect(self.updateTime)
self.startTime = 0
self.playing = False
self.audio = None

def initUI(self):
mainLayout = QVBoxLayout()
controlLayout = QHBoxLayout()

controlButtonLayout = QVBoxLayout()
self.playButton = QPushButton("Play")
self.playButton.clicked.connect(self.playButtonOnClick)
self.pauseButton = QPushButton("Pause")
self.pauseButton.clicked.connect(self.pauseButtonOnClick)
self.resumeButton = QPushButton("Resume")
self.resumeButton.clicked.connect(self.resumeButtonOnClick)
self.stopButton = QPushButton("Stop")
self.stopButton.clicked.connect(self.stopButtonOnClick)
controlButtonLayout.addWidget(self.playButton)
controlButtonLayout.addWidget(self.pauseButton)
controlButtonLayout.addWidget(self.resumeButton)
controlButtonLayout.addWidget(self.stopButton)
controlLayout.addLayout(controlButtonLayout)

audioProgressLayout = QVBoxLayout()
self.timeLabel = QLabel("00:00 / 00:00")
audioProgressLayout.addWidget(self.timeLabel)

self.timeSlider = QSlider(Qt.Horizontal)
self.timeSlider.setMinimum(0)
self.timeSlider.setMaximum(100)
self.timeSlider.setValue(0)
self.timeSlider.sliderPressed.connect(self.stopAudio)
self.timeSlider.sliderMoved.connect(self.changeStartTime)
self.timeSlider.valueChanged.connect(self.updateTimeLabel)
self.timeSlider.sliderReleased.connect(self.timeSliderValueOnChanged)
audioProgressLayout.addWidget(self.timeSlider)
controlLayout.addLayout(audioProgressLayout)

commandLayout = QVBoxLayout()
self.saveButton = QPushButton("Save", self)
self.saveButton.clicked.connect(self.onSaveButton)
self.backButton = QPushButton("Cancel", self)
self.backButton.clicked.connect(self.onBackButton)
commandLayout.addWidget(self.saveButton)
commandLayout.addWidget(self.backButton)
controlLayout.addLayout(commandLayout)
mainLayout.addLayout(controlLayout)

featuresLayout = QHBoxLayout()
self.volumeSlider = QSlider(Qt.Horizontal)
self.volumeSlider.setMinimum(-10)
self.volumeSlider.setMaximum(10)
self.volumeSlider.setValue(0)
self.volumeSlider.sliderPressed.connect(self.stopAudio)
self.volumeSlider.sliderReleased.connect(self.volumeSliderValueOnChanged)
featuresLayout.addWidget(QLabel("Volume:"))
featuresLayout.addWidget(self.volumeSlider)

self.bitrateComboBox = QComboBox(self)
self.bitrateComboBox.addItems(["64k", "128k", "192k", "256k", "320k"])
featuresLayout.addWidget(QLabel("Bitrate:"))
featuresLayout.addWidget(self.bitrateComboBox)

mainLayout.addItem(QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum))
mainLayout.addLayout(featuresLayout)

self.setLayout(mainLayout)

def loadAudioOnStart(self, filePath):
self.audioSegment = AudioSegment.from_file(filePath)
self.bitrateComboBox.setCurrentText(getBitRate(filePath))
self.filePath = filePath
self.timeLabel.setText("00:00 / " + "{:02}:{:02}".format(*divmod(len(self.audioSegment) // 1000, 60)))
self.pauseButton.hide()
self.resumeButton.hide()
self.stopButton.hide()
self.timeSlider.setMaximum((len(self.audioSegment)))



def playAudio(self, audio):
self.audio = _play_with_simpleaudio(audio[self.startTime:])
self.timer.start(10)

def stopAudio(self):
if self.audio:
self.audio.stop()
self.timer.stop()

def playButtonOnClick(self):
self.playing = True
self.playAudio(self.audioSegment)
self.startTime = 0 if self.startTime == None else self.startTime
self.timeLabel.setText("00:00 / " + "{:02}:{:02}".format(*divmod(len(self.audioSegment) // 1000, 60)))

self.playButton.hide()
self.pauseButton.show()
self.stopButton.show()

def pauseButtonOnClick(self):
self.audio.stop()
self.timer.stop()
self.pauseButton.hide()
self.resumeButton.show()

def resumeButtonOnClick(self):
self.playAudio(self.audioSegment[self.startTime:])
self.timer.start(10)
self.resumeButton.hide()
self.pauseButton.show()

def stopButtonOnClick(self):
self.stopAudio()
self.audio = None
self.startTime = 0
self.playButton.show()
self.pauseButton.hide()
self.resumeButton.hide()
self.stopButton.hide()

def updateTimeLabel(self):
self.timeLabel.setText('{:02}:{:02} / '.format(*divmod(self.startTime//1000, 60)) + "{:02}:{:02}".format(*divmod(len(self.audioSegment) // 1000, 60)))

def updateTime(self):
self.startTime += 10
self.timeSlider.setValue(self.startTime)

if not self.playing:
self.timer.stop()

if self.startTime >= len(self.audioSegment):
self.playing = False
self.timer.stop()
self.startTime = None
self.playButton.show()
self.pauseButton.hide()
self.resumeButton.hide()
self.stopButton.hide()

def changeStartTime(self):
self.startTime = self.timeSlider.value()

def timeSliderValueOnChanged(self):
self.stopAudio()
self.changeStartTime()
if self.audio:
self.playAudio(self.audioSegment)

def volumeSliderValueOnChanged(self):
self.audioSegment = changeVolume(self.audioSegment, self.volumeSlider.value())
if self.audio:
self.playAudio(self.audioSegment)

def onSaveButton(self):
newFilePath = saveAudioFileDialog(self, self.filePath)

if newFilePath:
saveAudio(newFilePath, self.audioSegment, self.bitrateComboBox.currentText())

def onBackButton(self):
self.stopAudio()
self.hide()
self.deleteLater()
self.parent.show()
Loading

0 comments on commit 5ebe815

Please sign in to comment.